From c05d042fda889f1e591b9d306482d9c16072dd60 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 19 Jun 2020 20:14:06 -0500 Subject: [PATCH 0001/5577] sparc64: viohs: Use struct_size() helper Make use of the struct_size() helper instead of an open-coded version in order to avoid any potential type mistakes. Also, remove unnecessary variable _len_. This code was detected with the help of Coccinelle and, audited and fixed manually. Addresses-KSPP-ID: https://github.com/KSPP/linux/issues/83 Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller --- arch/sparc/kernel/viohs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c index 7db5aabe9708..e27afd233bf5 100644 --- a/arch/sparc/kernel/viohs.c +++ b/arch/sparc/kernel/viohs.c @@ -428,7 +428,7 @@ static int process_dreg_info(struct vio_driver_state *vio, struct vio_dring_register *pkt) { struct vio_dring_state *dr; - int i, len; + int i; viodbg(HS, "GOT DRING_REG INFO ident[%llx] " "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", @@ -482,9 +482,7 @@ static int process_dreg_info(struct vio_driver_state *vio, pkt->num_descr, pkt->descr_size, pkt->options, pkt->num_cookies); - len = (sizeof(*pkt) + - (dr->ncookies * sizeof(struct ldc_trans_cookie))); - if (send_ctrl(vio, &pkt->tag, len) < 0) + if (send_ctrl(vio, &pkt->tag, struct_size(pkt, cookies, dr->ncookies)) < 0) goto send_nack; vio->dr_state |= VIO_DR_STATE_RXREG; From 5124b31c1e90797e26710377d04eb005759494a0 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Wed, 10 Jun 2020 07:55:19 +0000 Subject: [PATCH 0002/5577] sparc: piggyback: handle invalid image With an old elftoaout, the generation of tftpboot.img fail with "lseek: invalid argument". This is due to offset being negative. Instead of printing this error message, let's print a better one. Signed-off-by: Corentin Labbe Signed-off-by: David S. Miller --- arch/sparc/boot/piggyback.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/sparc/boot/piggyback.c b/arch/sparc/boot/piggyback.c index a7a38fb4ece0..6d74064add0a 100644 --- a/arch/sparc/boot/piggyback.c +++ b/arch/sparc/boot/piggyback.c @@ -154,6 +154,10 @@ static off_t get_hdrs_offset(int kernelfd, const char *filename) offset -= LOOKBACK; /* skip a.out header */ offset += AOUT_TEXT_OFFSET; + if (offset < 0) { + errno = -EINVAL; + die("Calculated a negative offset, probably elftoaout generated an invalid image. Did you use a recent elftoaout ?"); + } if (lseek(kernelfd, offset, SEEK_SET) < 0) die("lseek"); if (read(kernelfd, buffer, BUFSIZE) != BUFSIZE) From 37719576046b553092d5a88de90459306dfdec6b Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 13 Jul 2020 11:53:51 +0200 Subject: [PATCH 0003/5577] arch/sparc: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 5bf2dc163540..5f724e53ce9b 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -175,7 +175,7 @@ config SMP Management" code will be disabled if you say Y here. See also and the SMP-HOWTO - available at . + available at . If you don't know what to do here, say N. From e0602848213587d02d146ede8ad31c269982c839 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 21 Jul 2020 14:00:33 -0700 Subject: [PATCH 0004/5577] SPARC: backoff.h: delete a duplicated word Drop the repeated word "other". Signed-off-by: Randy Dunlap Cc: "David S. Miller" Cc: sparclinux@vger.kernel.org Signed-off-by: David S. Miller --- arch/sparc/include/asm/backoff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index 8625946d8d00..597a22953bc5 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h @@ -18,7 +18,7 @@ * * When we spin, we try to use an operation that will cause the * current cpu strand to block, and therefore make the core fully - * available to any other other runnable strands. There are two + * available to any other runnable strands. There are two * options, based upon cpu capabilities. * * On all cpus prior to SPARC-T4 we do three dummy reads of the From 7780918b36489f0b2f9a3749d7be00c2ceaec513 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Jul 2020 02:21:51 +0100 Subject: [PATCH 0005/5577] sparc32: fix a user-triggerable oops in clear_user() Back in 2.1.29 the clear_user() guts (__bzero()) had been merged with memset(). Unfortunately, while all exception handlers had been copied, one of the exception table entries got lost. As the result, clear_user() starting at 128*n bytes before the end of page and spanning between 8 and 127 bytes into the next page would oops when the second page is unmapped. It's trivial to reproduce - all it takes is main() { int fd = open("/dev/zero", O_RDONLY); char *p = mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); munmap(p + 8192, 8192); read(fd, p + 8192 - 128, 192); } which had been oopsing since March 1997. Says something about the quality of test coverage... ;-/ And while today sparc32 port is nearly dead, back in '97 it had been very much alive; in fact, sparc64 had only been in mainline for 3 months by that point... Cc: stable@kernel.org Fixes: v2.1.29 Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/sparc/lib/memset.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S index b89d42b29e34..f427f34b8b79 100644 --- a/arch/sparc/lib/memset.S +++ b/arch/sparc/lib/memset.S @@ -142,6 +142,7 @@ __bzero: ZERO_LAST_BLOCKS(%o0, 0x48, %g2) ZERO_LAST_BLOCKS(%o0, 0x08, %g2) 13: + EXT(12b, 13b, 21f) be 8f andcc %o1, 4, %g0 From 72a7af33e08083c118b57c93c1456cc9a5045dc6 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sat, 27 Jun 2020 11:16:52 +0300 Subject: [PATCH 0006/5577] sparc32: use PUD rather than PGD to get PMD in srmmu_inherit_prom_mappings() This is a misprint in the page table traversal in srmmu_inherit_prom_mappings`() function which accessed a PMD entry using PGD rather than PUD. Since sparc32 has only 3 page table levels, the PGD and PUD are essentially the same and usage of __nocache_fix() removed the type checking. Use PUD for the consistency and to avoid breakage because of upcoming addition of type checking into __nocache_fix(). Fixes: 7235db268a2777bc38 ("sparc32: use pgtable-nopud instead of 4level-fixup") Signed-off-by: Mike Rapoport Signed-off-by: David S. Miller --- arch/sparc/mm/srmmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 0070f8b9a753..f5fa07958f34 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -822,7 +822,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE); pud_set(__nocache_fix(pudp), pmdp); } - pmdp = pmd_offset(__nocache_fix(pgdp), start); + pmdp = pmd_offset(__nocache_fix(pudp), start); if (what == 1) { *(pmd_t *)__nocache_fix(pmdp) = __pmd(probed); start += PMD_SIZE; From c0d5b0c721b67d13796914031cc8b9bbf2c7f453 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sat, 27 Jun 2020 11:16:53 +0300 Subject: [PATCH 0007/5577] sparc32: srmmu: improve type safety of __nocache_fix() The __nocache_fix(VADDR) macro is used to add an offset for pointers and its "return type" is 'void *'. We can do better and keep the type information with simply by casting the return value to (__typeof__(VADDR)). This will ".. show when those pgd/p4d/pud pointers get mis-used because they don't end up dropping the type info.." The addition of the casting to __nocache_fix() also allows to remove explicit casts at its call sites. Suggested-by: Linus Torvalds Signed-off-by: Mike Rapoport Link: https://lkml.kernel.org/r/CAHk-=wisORTa7QVPnFqNw9pFs62UiwgsD4C4d=MtYy1o4JPyGQ@mail.gmail.com Signed-off-by: David S. Miller --- arch/sparc/include/asm/pgtsrmmu.h | 2 +- arch/sparc/mm/srmmu.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h index 7708d015712b..6067925972d9 100644 --- a/arch/sparc/include/asm/pgtsrmmu.h +++ b/arch/sparc/include/asm/pgtsrmmu.h @@ -113,7 +113,7 @@ extern unsigned long last_valid_pfn; extern void *srmmu_nocache_pool; #define __nocache_pa(VADDR) (((unsigned long)VADDR) - SRMMU_NOCACHE_VADDR + __pa((unsigned long)srmmu_nocache_pool)) #define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR) -#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR)) +#define __nocache_fix(VADDR) ((__typeof__(VADDR))__va(__nocache_pa(VADDR))) /* Accessing the MMU control register. */ unsigned int srmmu_get_mmureg(void); diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index f5fa07958f34..da4e10b4cb37 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -689,7 +689,7 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, pgdp = pgd_offset_k(start); p4dp = p4d_offset(pgdp, start); pudp = pud_offset(p4dp, start); - if (pud_none(*(pud_t *)__nocache_fix(pudp))) { + if (pud_none(*__nocache_fix(pudp))) { pmdp = __srmmu_get_nocache( SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) @@ -698,7 +698,7 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, pud_set(__nocache_fix(pudp), pmdp); } pmdp = pmd_offset(__nocache_fix(pudp), start); - if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { + if (srmmu_pmd_none(*__nocache_fix(pmdp))) { ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); @@ -810,11 +810,11 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, p4dp = p4d_offset(pgdp, start); pudp = pud_offset(p4dp, start); if (what == 2) { - *(pgd_t *)__nocache_fix(pgdp) = __pgd(probed); + *__nocache_fix(pgdp) = __pgd(probed); start += PGDIR_SIZE; continue; } - if (pud_none(*(pud_t *)__nocache_fix(pudp))) { + if (pud_none(*__nocache_fix(pudp))) { pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if (pmdp == NULL) @@ -828,7 +828,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, start += PMD_SIZE; continue; } - if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { + if (srmmu_pmd_none(*__nocache_fix(pmdp))) { ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); @@ -836,7 +836,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, pmd_set(__nocache_fix(pmdp), ptep); } ptep = pte_offset_kernel(__nocache_fix(pmdp), start); - *(pte_t *)__nocache_fix(ptep) = __pte(probed); + *__nocache_fix(ptep) = __pte(probed); start += PAGE_SIZE; } } @@ -850,7 +850,7 @@ static void __init do_large_mapping(unsigned long vaddr, unsigned long phys_base unsigned long big_pte; big_pte = KERNEL_PTE(phys_base >> 4); - *(pgd_t *)__nocache_fix(pgdp) = __pgd(big_pte); + *__nocache_fix(pgdp) = __pgd(big_pte); } /* Map sp_bank entry SP_ENTRY, starting at virtual address VBASE. */ @@ -940,7 +940,7 @@ void __init srmmu_paging_init(void) srmmu_ctx_table_phys = (ctxd_t *)__nocache_pa(srmmu_context_table); for (i = 0; i < num_contexts; i++) - srmmu_ctxd_set((ctxd_t *)__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir); + srmmu_ctxd_set(__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir); flush_cache_all(); srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys); From 17ec0a17e90f4b761025a6b80c8d458b9d5f9ddd Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 7 Jul 2020 12:24:36 -0500 Subject: [PATCH 0008/5577] sparc: Use fallthrough pseudo-keyword Replace the existing /* fall through */ comments and its variants with the new pseudo-keyword macro fallthrough[1]. Also, remove unnecessary fall-through markings when it is the case. [1] https://www.kernel.org/doc/html/latest/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller --- arch/sparc/kernel/auxio_64.c | 1 - arch/sparc/kernel/central.c | 2 +- arch/sparc/kernel/kgdb_32.c | 2 +- arch/sparc/kernel/kgdb_64.c | 2 +- arch/sparc/kernel/pcr.c | 2 +- arch/sparc/kernel/prom_32.c | 2 +- arch/sparc/kernel/signal32.c | 4 ++-- arch/sparc/kernel/signal_32.c | 4 ++-- arch/sparc/kernel/signal_64.c | 4 ++-- arch/sparc/math-emu/math_32.c | 8 ++++---- 10 files changed, 15 insertions(+), 16 deletions(-) diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 4843f48bfe85..774a82b0c649 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -87,7 +87,6 @@ void auxio_set_lte(int on) __auxio_sbus_set_lte(on); break; case AUXIO_TYPE_EBUS: - /* FALL-THROUGH */ default: break; } diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index bfae98ab8638..23f8838dd96e 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -55,7 +55,7 @@ static int clock_board_calc_nslots(struct clock_board *p) else return 5; } - /* Fallthrough */ + fallthrough; default: return 4; } diff --git a/arch/sparc/kernel/kgdb_32.c b/arch/sparc/kernel/kgdb_32.c index 7580775a14b9..58ad3f7de1fb 100644 --- a/arch/sparc/kernel/kgdb_32.c +++ b/arch/sparc/kernel/kgdb_32.c @@ -122,7 +122,7 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, linux_regs->pc = addr; linux_regs->npc = addr + 4; } - /* fall through */ + fallthrough; case 'D': case 'k': diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index 5d6c2d287e85..177746ae2c81 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c @@ -148,7 +148,7 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, linux_regs->tpc = addr; linux_regs->tnpc = addr + 4; } - /* fall through */ + fallthrough; case 'D': case 'k': diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index c0886b400dad..2a12c86af956 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c @@ -359,7 +359,7 @@ int __init pcr_arch_init(void) * counter overflow interrupt so we can't make use of * their hardware currently. */ - /* fallthrough */ + fallthrough; default: err = -ENODEV; goto out_unregister; diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c index da8902295c8c..3df960c137f7 100644 --- a/arch/sparc/kernel/prom_32.c +++ b/arch/sparc/kernel/prom_32.c @@ -224,7 +224,7 @@ void __init of_console_init(void) case PROMDEV_TTYB: skip = 1; - /* FALLTHRU */ + fallthrough; case PROMDEV_TTYA: type = "serial"; diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index e2c6f0abda00..e9695a06492f 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -646,7 +646,7 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs case ERESTARTSYS: if (!(sa->sa_flags & SA_RESTART)) goto no_system_call_restart; - /* fallthrough */ + fallthrough; case ERESTARTNOINTR: regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; @@ -686,7 +686,7 @@ void do_signal32(struct pt_regs * regs) regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); - /* fall through */ + fallthrough; case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 3b005b6c3e0f..e08d294d63e4 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -441,7 +441,7 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, case ERESTARTSYS: if (!(sa->sa_flags & SA_RESTART)) goto no_system_call_restart; - /* fallthrough */ + fallthrough; case ERESTARTNOINTR: regs->u_regs[UREG_I0] = orig_i0; regs->pc -= 4; @@ -507,7 +507,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) regs->pc -= 4; regs->npc -= 4; pt_regs_clear_syscall(regs); - /* fall through */ + fallthrough; case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 6937339a272c..255264bcb46a 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -461,7 +461,7 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, case ERESTARTSYS: if (!(sa->sa_flags & SA_RESTART)) goto no_system_call_restart; - /* fallthrough */ + fallthrough; case ERESTARTNOINTR: regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; @@ -532,7 +532,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); - /* fall through */ + fallthrough; case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; diff --git a/arch/sparc/math-emu/math_32.c b/arch/sparc/math-emu/math_32.c index 72e560ef4a09..d5beec856146 100644 --- a/arch/sparc/math-emu/math_32.c +++ b/arch/sparc/math-emu/math_32.c @@ -359,7 +359,7 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs) *pfsr |= (6 << 14); return 0; /* simulate invalid_fp_register exception */ } - /* fall through */ + fallthrough; case 2: if (freg & 1) { /* doublewords must have bit 5 zeroed */ *pfsr |= (6 << 14); @@ -380,7 +380,7 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs) *pfsr |= (6 << 14); return 0; /* simulate invalid_fp_register exception */ } - /* fall through */ + fallthrough; case 2: if (freg & 1) { /* doublewords must have bit 5 zeroed */ *pfsr |= (6 << 14); @@ -408,13 +408,13 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs) *pfsr |= (6 << 14); return 0; /* simulate invalid_fp_register exception */ } - /* fall through */ + fallthrough; case 2: if (freg & 1) { /* doublewords must have bit 5 zeroed */ *pfsr |= (6 << 14); return 0; } - /* fall through */ + fallthrough; case 1: rd = (void *)&fregs[freg]; break; From 0a95a6d1a4cd6e10e70f8a6c93dc2ecd02e7d6ab Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Tue, 28 Jul 2020 10:28:17 +0800 Subject: [PATCH 0009/5577] sparc: use for_each_child_of_node() macro Use for_each_child_of_node() macro instead of open coding it. Signed-off-by: Qinglang Miao Signed-off-by: David S. Miller --- arch/sparc/kernel/pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 5d45b6d766d6..9c2b720bfd20 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -552,9 +552,8 @@ static void pci_of_scan_bus(struct pci_pbm_info *pbm, pci_info(bus, "scan_bus[%pOF] bus no %d\n", node, bus->number); - child = NULL; prev_devfn = -1; - while ((child = of_get_next_child(node, child)) != NULL) { + for_each_child_of_node(node, child) { if (ofpci_verbose) pci_info(bus, " * %pOF\n", child); reg = of_get_property(child, "reg", ®len); From 4cc8ca08ed0934cfcb9a4f3998119ea954780b02 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 17 Aug 2020 20:17:45 -0700 Subject: [PATCH 0010/5577] sparc: remove SA_STATIC_ALLOC macro definition This macro is not exposed to uapi and is unreferenced in the kernel. The last reference to it was removed in commit 4c6773c3954c ("sparc32,leon: add support for extended interrupt controller"), so remove the definition. Signed-off-by: Peter Collingbourne Signed-off-by: David S. Miller --- arch/sparc/include/asm/signal.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h index 827b73a97f8a..28f81081e37d 100644 --- a/arch/sparc/include/asm/signal.h +++ b/arch/sparc/include/asm/signal.h @@ -9,18 +9,6 @@ #include #ifndef __ASSEMBLY__ -/* - * DJHR - * SA_STATIC_ALLOC is used for the sparc32 system to indicate that this - * interrupt handler's irq structure should be statically allocated - * by the request_irq routine. - * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge - * of interrupt usage and that sucks. Also without a flag like this - * it may be possible for the free_irq routine to attempt to free - * statically allocated data.. which is NOT GOOD. - * - */ -#define SA_STATIC_ALLOC 0x8000 #define __ARCH_HAS_KA_RESTORER #define __ARCH_HAS_SA_RESTORER From b6b9b67d67f0962e9e976c2d3623a992ef7f30b0 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 27 Aug 2020 17:47:36 +0100 Subject: [PATCH 0011/5577] sparc32: signal: Fix stack trampoline for RT signals The stack trampoline generated by the sparc32 native version of setup_rt_frame() calls sigreturn(), not rt_sigreturn(). This will crash the task if it's ever used. (glibc sets its own restorer, so was not affected.) The sparc64 compat implementation has the right syscall number. This is untested; I have no way to run a sparc32 kernel. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- arch/sparc/kernel/signal_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index e08d294d63e4..76b934241e09 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -401,8 +401,8 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, else { regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); - /* mov __NR_sigreturn, %g1 */ - err |= __put_user(0x821020d8, &sf->insns[0]); + /* mov __NR_rt_sigreturn, %g1 */ + err |= __put_user(0x82102065, &sf->insns[0]); /* t 0x10 */ err |= __put_user(0x91d02010, &sf->insns[1]); From bf8c5541df535d1c0e122c0bcc839894961984bc Mon Sep 17 00:00:00 2001 From: Jing Xiangfeng Date: Fri, 11 Sep 2020 15:13:41 +0800 Subject: [PATCH 0012/5577] sbus: char: Remove meaningless jump label out_free After commit 57a4a3d7f756 ("display7seg: Introduce the use of the managed version of kzalloc"), The out_free jump label has nothing to do but goto out. So remove it. Signed-off-by: Jing Xiangfeng Signed-off-by: David S. Miller --- drivers/sbus/char/display7seg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index fad936eb845f..00e72b97d0b6 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -186,7 +186,7 @@ static int d7s_probe(struct platform_device *op) p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s"); if (!p->regs) { printk(KERN_ERR PFX "Cannot map chip registers\n"); - goto out_free; + goto out; } err = misc_register(&d7s_miscdev); @@ -228,8 +228,6 @@ out: out_iounmap: of_iounmap(&op->resource[0], p->regs, sizeof(u8)); - -out_free: goto out; } From 77c296966e866a795742a46fc52a218771894867 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 13 Nov 2020 13:25:10 +0000 Subject: [PATCH 0013/5577] drm/i915: Avoid memory leak with more than 16 workarounds on a list I forgot to free the old list when growing past 16 entries. Luckily, as much as I checked, none of the current platforms has more than 16 workarounds on a single list. Signed-off-by: Tvrtko Ursulin Fixes: 452420d22d5b ("drm/i915: Fuse per-context workaround handling with the common framework") Reported-by: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201113132510.2298483-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index fed9503a7c4e..adc9a8ea410a 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -131,8 +131,10 @@ static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa) return; } - if (wal->list) + if (wal->list) { memcpy(list, wal->list, sizeof(*wa) * wal->count); + kfree(wal->list); + } wal->list = list; } From 01d708840c26c9532579677eaca942363a009fd5 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 16 Nov 2020 09:41:12 -0500 Subject: [PATCH 0014/5577] drm/i915/selftests: Fix wrong return value of perf_series_engines() If intel context create failed, the perf_series_engines() will return 0 rather than error, because we doesn't initialize the return value. Fixes: cbfd3a0c5a55 ("drm/i915/selftests: Add request throughput measurement to perf") Reported-by: Hulk Robot Signed-off-by: Zhang Xiaoxu Reviewed-by: Mika Kuoppala Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201116144112.3673011-1-zhangxiaoxu5@huawei.com --- drivers/gpu/drm/i915/selftests/i915_request.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index 64bbb8288249..480b3da4d8a6 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -2467,8 +2467,10 @@ static int perf_series_engines(void *arg) struct intel_context *ce; ce = intel_context_create(engine); - if (IS_ERR(ce)) + if (IS_ERR(ce)) { + err = PTR_ERR(ce); goto out; + } err = intel_context_pin(ce); if (err) { From 19384452052a1e0525e663bfbdd62ac1399bb647 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 16 Nov 2020 09:35:40 -0500 Subject: [PATCH 0015/5577] drm/i915/selftests: Fix wrong return value of perf_request_latency() If intel context create failed, the perf_request_latency() will return 0 rather than error, because we doesn't initialize the return value. Fixes: 25c26f18ea79 ("drm/i915/selftests: Measure dispatch latency") Reported-by: Hulk Robot Signed-off-by: Zhang Xiaoxu Reviewed-by: Mika Kuoppala Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201116143540.3648870-1-zhangxiaoxu5@huawei.com --- drivers/gpu/drm/i915/selftests/i915_request.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index 480b3da4d8a6..e424a6d1a68c 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -2293,8 +2293,10 @@ static int perf_request_latency(void *arg) struct intel_context *ce; ce = intel_context_create(engine); - if (IS_ERR(ce)) + if (IS_ERR(ce)) { + err = PTR_ERR(ce); goto out; + } err = intel_context_pin(ce); if (err) { From ac54c826cdd6858dfe0246fc3f195f5705675601 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Mon, 26 Oct 2020 21:32:28 -0700 Subject: [PATCH 0016/5577] drm/i915/dg1: make Wa_22010271021 permanent Just like for rkl and tgl, this should be permanent as well for dg1 instead just for A0. The commit making it permanent for those platforms ended up "racing" with the commit adding the DG1 WAs, so now fix that up. v2: Add "tgl,dg1" to WA comment (Matt) Cc: Swathi Dhanavanthri Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20201027043228.696518-3-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index adc9a8ea410a..a82554baa6ac 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1770,6 +1770,14 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) */ wa_write_or(wal, GEN7_FF_THREAD_MODE, GEN12_FF_TESSELATION_DOP_GATE_DISABLE); + + /* + * Wa_1606700617:tgl,dg1 + * Wa_22010271021:tgl,rkl,dg1 + */ + wa_masked_en(wal, + GEN9_CS_DEBUG_MODE1, + FF_DOP_CLOCK_GATE_DISABLE); } if (IS_DG1_REVID(i915, DG1_REVID_A0, DG1_REVID_A0) || @@ -1798,14 +1806,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) GEN6_RC_SLEEP_PSMI_CONTROL, GEN12_WAIT_FOR_EVENT_POWER_DOWN_DISABLE | GEN8_RC_SEMA_IDLE_MSG_DISABLE); - - /* - * Wa_1606700617:tgl - * Wa_22010271021:tgl,rkl - */ - wa_masked_en(wal, - GEN9_CS_DEBUG_MODE1, - FF_DOP_CLOCK_GATE_DISABLE); } if (IS_GEN(i915, 12)) { From d33fcd798cb71268a48f5a26a8ab7ab0ddd51955 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Nov 2020 11:30:39 +0000 Subject: [PATCH 0017/5577] drm/i915/gt: Ignore dt==0 for reporting underflows The presumption was that some time would always elapse between recording the start and the finish of a context switch. This turns out to be a regular occurrence and emitting a debug statement superfluous. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201117113103.21480-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 8a51c1c3a091..52b84474f93a 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1307,7 +1307,7 @@ static void reset_active(struct i915_request *rq, static void st_update_runtime_underflow(struct intel_context *ce, s32 dt) { #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) - ce->runtime.num_underflow += dt < 0; + ce->runtime.num_underflow++; ce->runtime.max_underflow = max_t(u32, ce->runtime.max_underflow, -dt); #endif } @@ -1324,7 +1324,7 @@ static void intel_context_update_runtime(struct intel_context *ce) ce->runtime.last = intel_context_get_runtime(ce); dt = ce->runtime.last - old; - if (unlikely(dt <= 0)) { + if (unlikely(dt < 0)) { CE_TRACE(ce, "runtime underflow: last=%u, new=%u, delta=%d\n", old, ce->runtime.last, dt); st_update_runtime_underflow(ce, dt); From 45e50f48b7907e650cfbbc7879abfe3a0c419c73 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 18 Nov 2020 13:38:39 +0000 Subject: [PATCH 0018/5577] drm/i915/gt: Remember to free the virtual breadcrumbs Since we allocate some breadcrumbs for the virtual engine, and the virtual engine has a custom destructor, we also need to free the breadcrumbs after use. Fixes: b3786b29379c ("drm/i915/gt: Distinguish the virtual breadcrumbs from the irq breadcrumbs") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201118133839.1783-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 52b84474f93a..f7eca93f04bc 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -5512,6 +5512,7 @@ static void virtual_context_destroy(struct kref *kref) __execlists_context_fini(&ve->context); intel_context_fini(&ve->context); + intel_breadcrumbs_free(ve->base.breadcrumbs); intel_engine_free_request_pool(&ve->base); kfree(ve->bonds); From dac67c2d338c8ff2f5abb9a2210bfc0264c025e5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Nov 2020 20:43:07 +0000 Subject: [PATCH 0019/5577] drm/i915/gvt: Remove incorrect kerneldoc marking Just a normal comment, not a kerneldoc function description. drivers/gpu/drm/i915/gvt/handlers.c:1666: warning: Function parameter or member 'vgpu' not described in 'bxt_ppat_low_write' drivers/gpu/drm/i915/gvt/handlers.c:1666: warning: Function parameter or member 'offset' not described in 'bxt_ppat_low_write' drivers/gpu/drm/i915/gvt/handlers.c:1666: warning: Function parameter or member 'p_data' not described in 'bxt_ppat_low_write' drivers/gpu/drm/i915/gvt/handlers.c:1666: warning: Function parameter or member 'bytes' not described in 'bxt_ppat_low_write' Signed-off-by: Chris Wilson Acked-by: Zhenyu Wang Link: https://patchwork.freedesktop.org/patch/msgid/20201103204307.15723-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gvt/handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index ce93079cf933..4ddc9c847470 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1651,7 +1651,7 @@ static int edp_psr_imr_iir_write(struct intel_vgpu *vgpu, return 0; } -/** +/* * FixMe: * If guest fills non-priv batch buffer on ApolloLake/Broxton as Mesa i965 did: * 717e7539124d (i965: Use a WC map and memcpy for the batch instead of pwrite.) From 14cb9a7763622460a904c50b8adbf69a83d6cab5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Nov 2020 16:56:11 +0000 Subject: [PATCH 0020/5577] drm/i915/gt: Include semaphore status in print_request() When pretty-printing the requests for debug, also show the status of any semaphore waits as part of its runnable status. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201119165616.10834-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 0b31670343f5..1ed84ee8ce41 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -1321,6 +1321,7 @@ static void print_request(struct drm_printer *m, rq->fence.context, rq->fence.seqno, i915_request_completed(rq) ? "!" : i915_request_started(rq) ? "*" : + !i915_sw_fence_signaled(&rq->semaphore) ? "&" : "", test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags) ? "+" : From 1f0e785a9cc09b430d0fbe4e9ac438d43c245815 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Nov 2020 16:56:12 +0000 Subject: [PATCH 0021/5577] drm/i915: Lift i915_request_show() Extract i915_request_show for reuse in other request chain pretty printers. For a bonus point, quietly change the seqno format from %llx to %lld to match everywhere else. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201119165616.10834-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 47 ++--------------------- drivers/gpu/drm/i915/gt/intel_lrc.c | 2 +- drivers/gpu/drm/i915/gt/intel_lrc.h | 2 +- drivers/gpu/drm/i915/i915_request.c | 39 +++++++++++++++++++ drivers/gpu/drm/i915/i915_request.h | 5 +++ 5 files changed, 50 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 1ed84ee8ce41..c3bb2e9546e6 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -1294,45 +1294,6 @@ bool intel_engine_can_store_dword(struct intel_engine_cs *engine) } } -static int print_sched_attr(const struct i915_sched_attr *attr, - char *buf, int x, int len) -{ - if (attr->priority == I915_PRIORITY_INVALID) - return x; - - x += snprintf(buf + x, len - x, - " prio=%d", attr->priority); - - return x; -} - -static void print_request(struct drm_printer *m, - struct i915_request *rq, - const char *prefix) -{ - const char *name = rq->fence.ops->get_timeline_name(&rq->fence); - char buf[80] = ""; - int x = 0; - - x = print_sched_attr(&rq->sched.attr, buf, x, sizeof(buf)); - - drm_printf(m, "%s %llx:%llx%s%s %s @ %dms: %s\n", - prefix, - rq->fence.context, rq->fence.seqno, - i915_request_completed(rq) ? "!" : - i915_request_started(rq) ? "*" : - !i915_sw_fence_signaled(&rq->semaphore) ? "&" : - "", - test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &rq->fence.flags) ? "+" : - test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &rq->fence.flags) ? "-" : - "", - buf, - jiffies_to_msecs(jiffies - rq->emitted_jiffies), - name); -} - static struct intel_timeline *get_timeline(struct i915_request *rq) { struct intel_timeline *tl; @@ -1530,7 +1491,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine, intel_context_is_banned(rq->context) ? "*" : ""); len += print_ring(hdr + len, sizeof(hdr) - len, rq); scnprintf(hdr + len, sizeof(hdr) - len, "rq: "); - print_request(m, rq, hdr); + i915_request_show(m, rq, hdr); } for (port = execlists->pending; (rq = *port); port++) { char hdr[160]; @@ -1544,7 +1505,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine, intel_context_is_banned(rq->context) ? "*" : ""); len += print_ring(hdr + len, sizeof(hdr) - len, rq); scnprintf(hdr + len, sizeof(hdr) - len, "rq: "); - print_request(m, rq, hdr); + i915_request_show(m, rq, hdr); } rcu_read_unlock(); execlists_active_unlock_bh(execlists); @@ -1688,7 +1649,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, if (rq) { struct intel_timeline *tl = get_timeline(rq); - print_request(m, rq, "\t\tactive "); + i915_request_show(m, rq, "\t\tactive "); drm_printf(m, "\t\tring->start: 0x%08x\n", i915_ggtt_offset(rq->ring->vma)); @@ -1726,7 +1687,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, drm_printf(m, "\tDevice is asleep; skipping register dump\n"); } - intel_execlists_show_requests(engine, m, print_request, 8); + intel_execlists_show_requests(engine, m, i915_request_show, 8); drm_printf(m, "HWSP:\n"); hexdump(m, engine->status_page.addr, PAGE_SIZE); diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index f7eca93f04bc..b6ab1161942a 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -5981,7 +5981,7 @@ int intel_virtual_engine_attach_bond(struct intel_engine_cs *engine, void intel_execlists_show_requests(struct intel_engine_cs *engine, struct drm_printer *m, void (*show_request)(struct drm_printer *m, - struct i915_request *rq, + const struct i915_request *rq, const char *prefix), unsigned int max) { diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h b/drivers/gpu/drm/i915/gt/intel_lrc.h index c2d287f25497..32e6e204f544 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc.h @@ -106,7 +106,7 @@ void intel_lr_context_reset(struct intel_engine_cs *engine, void intel_execlists_show_requests(struct intel_engine_cs *engine, struct drm_printer *m, void (*show_request)(struct drm_printer *m, - struct i915_request *rq, + const struct i915_request *rq, const char *prefix), unsigned int max); diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 0e813819b041..673991718ae6 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1855,6 +1855,45 @@ out: return timeout; } +static int print_sched_attr(const struct i915_sched_attr *attr, + char *buf, int x, int len) +{ + if (attr->priority == I915_PRIORITY_INVALID) + return x; + + x += snprintf(buf + x, len - x, + " prio=%d", attr->priority); + + return x; +} + +void i915_request_show(struct drm_printer *m, + const struct i915_request *rq, + const char *prefix) +{ + const char *name = rq->fence.ops->get_timeline_name((struct dma_fence *)&rq->fence); + char buf[80] = ""; + int x = 0; + + x = print_sched_attr(&rq->sched.attr, buf, x, sizeof(buf)); + + drm_printf(m, "%s %llx:%lld%s%s %s @ %dms: %s\n", + prefix, + rq->fence.context, rq->fence.seqno, + i915_request_completed(rq) ? "!" : + i915_request_started(rq) ? "*" : + !i915_sw_fence_signaled(&rq->semaphore) ? "&" : + "", + test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, + &rq->fence.flags) ? "+" : + test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, + &rq->fence.flags) ? "-" : + "", + buf, + jiffies_to_msecs(jiffies - rq->emitted_jiffies), + name); +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/mock_request.c" #include "selftests/i915_request.c" diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 16b721080195..09609071b725 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -43,6 +43,7 @@ struct drm_file; struct drm_i915_gem_object; +struct drm_printer; struct i915_request; struct i915_capture_list { @@ -369,6 +370,10 @@ long i915_request_wait(struct i915_request *rq, #define I915_WAIT_PRIORITY BIT(1) /* small priority bump for the request */ #define I915_WAIT_ALL BIT(2) /* used by i915_gem_object_wait() */ +void i915_request_show(struct drm_printer *m, + const struct i915_request *rq, + const char *prefix); + static inline bool i915_request_signaled(const struct i915_request *rq) { /* The request may live longer than its HWSP, so check flags first! */ From 562675d09a351a81e0dfc9a9d7df0f5f4f2fb6a9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Nov 2020 16:56:13 +0000 Subject: [PATCH 0022/5577] drm/i915/gt: Update request status flags for debug pretty-printer We plan to expand upon the number of available statuses for when we pretty-print the requests along the timelines, and so need a new set of flags. We have settled upon: Unready [U] - initial status after being submitted, the request is not ready for execution as it is waiting for external fences Ready [R] - all fences the request was waiting on have been signaled, and the request is now ready for execution and will be in a backend queue - a ready request may still need to wait on semaphores [internal fences] Ready/virtual [V] - same as ready, but queued over multiple backends Executing [E] - the request has been transferred from the backend queue and submitted for execution on HW - a completed request may still be regarded as executing, its status may not be updated until it is retired and removed from the lists Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201119165616.10834-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 6 +- drivers/gpu/drm/i915/gt/intel_lrc.c | 15 ++-- drivers/gpu/drm/i915/gt/intel_lrc.h | 3 +- drivers/gpu/drm/i915/i915_request.c | 85 +++++++++++++++++++---- drivers/gpu/drm/i915/i915_request.h | 3 +- 5 files changed, 88 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index c3bb2e9546e6..d4e988b2816a 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -1491,7 +1491,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine, intel_context_is_banned(rq->context) ? "*" : ""); len += print_ring(hdr + len, sizeof(hdr) - len, rq); scnprintf(hdr + len, sizeof(hdr) - len, "rq: "); - i915_request_show(m, rq, hdr); + i915_request_show(m, rq, hdr, 0); } for (port = execlists->pending; (rq = *port); port++) { char hdr[160]; @@ -1505,7 +1505,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine, intel_context_is_banned(rq->context) ? "*" : ""); len += print_ring(hdr + len, sizeof(hdr) - len, rq); scnprintf(hdr + len, sizeof(hdr) - len, "rq: "); - i915_request_show(m, rq, hdr); + i915_request_show(m, rq, hdr, 0); } rcu_read_unlock(); execlists_active_unlock_bh(execlists); @@ -1649,7 +1649,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, if (rq) { struct intel_timeline *tl = get_timeline(rq); - i915_request_show(m, rq, "\t\tactive "); + i915_request_show(m, rq, "\t\tactive ", 0); drm_printf(m, "\t\tring->start: 0x%08x\n", i915_ggtt_offset(rq->ring->vma)); diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index b6ab1161942a..5257f3c71366 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -5982,7 +5982,8 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, struct drm_printer *m, void (*show_request)(struct drm_printer *m, const struct i915_request *rq, - const char *prefix), + const char *prefix, + int indent), unsigned int max) { const struct intel_engine_execlists *execlists = &engine->execlists; @@ -5997,7 +5998,7 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, count = 0; list_for_each_entry(rq, &engine->active.requests, sched.link) { if (count++ < max - 1) - show_request(m, rq, "\t\tE "); + show_request(m, rq, "\t\t", 0); else last = rq; } @@ -6007,7 +6008,7 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, "\t\t...skipping %d executing requests...\n", count - max); } - show_request(m, last, "\t\tE "); + show_request(m, last, "\t\t", 0); } if (execlists->switch_priority_hint != INT_MIN) @@ -6025,7 +6026,7 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, priolist_for_each_request(rq, p, i) { if (count++ < max - 1) - show_request(m, rq, "\t\tQ "); + show_request(m, rq, "\t\t", 0); else last = rq; } @@ -6036,7 +6037,7 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, "\t\t...skipping %d queued requests...\n", count - max); } - show_request(m, last, "\t\tQ "); + show_request(m, last, "\t\t", 0); } last = NULL; @@ -6048,7 +6049,7 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, if (rq) { if (count++ < max - 1) - show_request(m, rq, "\t\tV "); + show_request(m, rq, "\t\t", 0); else last = rq; } @@ -6059,7 +6060,7 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, "\t\t...skipping %d virtual requests...\n", count - max); } - show_request(m, last, "\t\tV "); + show_request(m, last, "\t\t", 0); } spin_unlock_irqrestore(&engine->active.lock, flags); diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h b/drivers/gpu/drm/i915/gt/intel_lrc.h index 32e6e204f544..802585a308e9 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc.h @@ -107,7 +107,8 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, struct drm_printer *m, void (*show_request)(struct drm_printer *m, const struct i915_request *rq, - const char *prefix), + const char *prefix, + int indent), unsigned int max); struct intel_context * diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 673991718ae6..8d7d29c9e375 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1867,28 +1867,89 @@ static int print_sched_attr(const struct i915_sched_attr *attr, return x; } +static char queue_status(const struct i915_request *rq) +{ + if (i915_request_is_active(rq)) + return 'E'; + + if (i915_request_is_ready(rq)) + return intel_engine_is_virtual(rq->engine) ? 'V' : 'R'; + + return 'U'; +} + +static const char *run_status(const struct i915_request *rq) +{ + if (i915_request_completed(rq)) + return "!"; + + if (i915_request_started(rq)) + return "*"; + + if (!i915_sw_fence_signaled(&rq->semaphore)) + return "&"; + + return ""; +} + +static const char *fence_status(const struct i915_request *rq) +{ + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)) + return "+"; + + if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags)) + return "-"; + + return ""; +} + void i915_request_show(struct drm_printer *m, const struct i915_request *rq, - const char *prefix) + const char *prefix, + int indent) { const char *name = rq->fence.ops->get_timeline_name((struct dma_fence *)&rq->fence); char buf[80] = ""; int x = 0; + /* + * The prefix is used to show the queue status, for which we use + * the following flags: + * + * U [Unready] + * - initial status upon being submitted by the user + * + * - the request is not ready for execution as it is waiting + * for external fences + * + * R [Ready] + * - all fences the request was waiting on have been signaled, + * and the request is now ready for execution and will be + * in a backend queue + * + * - a ready request may still need to wait on semaphores + * [internal fences] + * + * V [Ready/virtual] + * - same as ready, but queued over multiple backends + * + * E [Executing] + * - the request has been transferred from the backend queue and + * submitted for execution on HW + * + * - a completed request may still be regarded as executing, its + * status may not be updated until it is retired and removed + * from the lists + */ + x = print_sched_attr(&rq->sched.attr, buf, x, sizeof(buf)); - drm_printf(m, "%s %llx:%lld%s%s %s @ %dms: %s\n", - prefix, + drm_printf(m, "%s%.*s%c %llx:%lld%s%s %s @ %dms: %s\n", + prefix, indent, " ", + queue_status(rq), rq->fence.context, rq->fence.seqno, - i915_request_completed(rq) ? "!" : - i915_request_started(rq) ? "*" : - !i915_sw_fence_signaled(&rq->semaphore) ? "&" : - "", - test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &rq->fence.flags) ? "+" : - test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &rq->fence.flags) ? "-" : - "", + run_status(rq), + fence_status(rq), buf, jiffies_to_msecs(jiffies - rq->emitted_jiffies), name); diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 09609071b725..8f6173b1c3df 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -372,7 +372,8 @@ long i915_request_wait(struct i915_request *rq, void i915_request_show(struct drm_printer *m, const struct i915_request *rq, - const char *prefix); + const char *prefix, + int indent); static inline bool i915_request_signaled(const struct i915_request *rq) { From 0986317a45df7ff380f1512b53a2f94ab16922b8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Nov 2020 16:56:14 +0000 Subject: [PATCH 0023/5577] drm/i915/gt: Show all active timelines for debugging Include the active timelines for debugfs/i915_engine_info, so that we can see which have unready requests inflight which are not shown otherwise. Suggested-by: Tvrtko Ursulin Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201119165616.10834-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_timeline.c | 80 ++++++++++++++++++++++++ drivers/gpu/drm/i915/gt/intel_timeline.h | 9 +++ drivers/gpu/drm/i915/i915_debugfs.c | 16 ++--- 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index 7ea94d201fe6..512afacd2bdc 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -617,6 +617,86 @@ void intel_gt_fini_timelines(struct intel_gt *gt) GEM_BUG_ON(!list_empty(&timelines->hwsp_free_list)); } +void intel_gt_show_timelines(struct intel_gt *gt, + struct drm_printer *m, + void (*show_request)(struct drm_printer *m, + const struct i915_request *rq, + const char *prefix, + int indent)) +{ + struct intel_gt_timelines *timelines = >->timelines; + struct intel_timeline *tl, *tn; + LIST_HEAD(free); + + spin_lock(&timelines->lock); + list_for_each_entry_safe(tl, tn, &timelines->active_list, link) { + unsigned long count, ready, inflight; + struct i915_request *rq, *rn; + struct dma_fence *fence; + + if (!mutex_trylock(&tl->mutex)) { + drm_printf(m, "Timeline %llx: busy; skipping\n", + tl->fence_context); + continue; + } + + intel_timeline_get(tl); + GEM_BUG_ON(!atomic_read(&tl->active_count)); + atomic_inc(&tl->active_count); /* pin the list element */ + spin_unlock(&timelines->lock); + + count = 0; + ready = 0; + inflight = 0; + list_for_each_entry_safe(rq, rn, &tl->requests, link) { + if (i915_request_completed(rq)) + continue; + + count++; + if (i915_request_is_ready(rq)) + ready++; + if (i915_request_is_active(rq)) + inflight++; + } + + drm_printf(m, "Timeline %llx: { ", tl->fence_context); + drm_printf(m, "count: %lu, ready: %lu, inflight: %lu", + count, ready, inflight); + drm_printf(m, ", seqno: { current: %d, last: %d }", + *tl->hwsp_seqno, tl->seqno); + fence = i915_active_fence_get(&tl->last_request); + if (fence) { + drm_printf(m, ", engine: %s", + to_request(fence)->engine->name); + dma_fence_put(fence); + } + drm_printf(m, " }\n"); + + if (show_request) { + list_for_each_entry_safe(rq, rn, &tl->requests, link) + show_request(m, rq, "", 2); + } + + mutex_unlock(&tl->mutex); + spin_lock(&timelines->lock); + + /* Resume list iteration after reacquiring spinlock */ + list_safe_reset_next(tl, tn, link); + if (atomic_dec_and_test(&tl->active_count)) + list_del(&tl->link); + + /* Defer the final release to after the spinlock */ + if (refcount_dec_and_test(&tl->kref.refcount)) { + GEM_BUG_ON(atomic_read(&tl->active_count)); + list_add(&tl->link, &free); + } + } + spin_unlock(&timelines->lock); + + list_for_each_entry_safe(tl, tn, &free, link) + __intel_timeline_free(&tl->kref); +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "gt/selftests/mock_timeline.c" #include "gt/selftest_timeline.c" diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h b/drivers/gpu/drm/i915/gt/intel_timeline.h index 9882cd911d8e..634acebd0c4b 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.h +++ b/drivers/gpu/drm/i915/gt/intel_timeline.h @@ -31,6 +31,8 @@ #include "i915_syncmap.h" #include "intel_timeline_types.h" +struct drm_printer; + struct intel_timeline * __intel_timeline_create(struct intel_gt *gt, struct i915_vma *global_hwsp, @@ -106,4 +108,11 @@ int intel_timeline_read_hwsp(struct i915_request *from, void intel_gt_init_timelines(struct intel_gt *gt); void intel_gt_fini_timelines(struct intel_gt *gt); +void intel_gt_show_timelines(struct intel_gt *gt, + struct drm_printer *m, + void (*show_request)(struct drm_printer *m, + const struct i915_request *rq, + const char *prefix, + int indent)); + #endif diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 77e76b665098..354b95c438d0 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1306,24 +1306,26 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) static int i915_engine_info(struct seq_file *m, void *unused) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_i915_private *i915 = node_to_i915(m->private); struct intel_engine_cs *engine; intel_wakeref_t wakeref; struct drm_printer p; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_runtime_pm_get(&i915->runtime_pm); seq_printf(m, "GT awake? %s [%d]\n", - yesno(dev_priv->gt.awake), - atomic_read(&dev_priv->gt.wakeref.count)); + yesno(i915->gt.awake), + atomic_read(&i915->gt.wakeref.count)); seq_printf(m, "CS timestamp frequency: %u Hz\n", - RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_hz); + RUNTIME_INFO(i915)->cs_timestamp_frequency_hz); p = drm_seq_file_printer(m); - for_each_uabi_engine(engine, dev_priv) + for_each_uabi_engine(engine, i915) intel_engine_dump(engine, &p, "%s\n", engine->name); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_gt_show_timelines(&i915->gt, &p, NULL); + + intel_runtime_pm_put(&i915->runtime_pm, wakeref); return 0; } From b5b349b93b0ec9051a98a401a5e105476fd549dd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Nov 2020 16:56:15 +0000 Subject: [PATCH 0024/5577] drm/i915: Lift waiter/signaler iterators Lift the list iteration defines for traversing the signaler/waiter lists into i915_scheduler.h for reuse. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201119165616.10834-5-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 10 ---------- drivers/gpu/drm/i915/i915_scheduler_types.h | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 5257f3c71366..30759e95da0e 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1836,16 +1836,6 @@ static void virtual_xfer_context(struct virtual_engine *ve, } } -#define for_each_waiter(p__, rq__) \ - list_for_each_entry_lockless(p__, \ - &(rq__)->sched.waiters_list, \ - wait_link) - -#define for_each_signaler(p__, rq__) \ - list_for_each_entry_rcu(p__, \ - &(rq__)->sched.signalers_list, \ - signal_link) - static void defer_request(struct i915_request *rq, struct list_head * const pl) { LIST_HEAD(list); diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h index f72e6c397b08..343ed44d5ed4 100644 --- a/drivers/gpu/drm/i915/i915_scheduler_types.h +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h @@ -81,4 +81,14 @@ struct i915_dependency { #define I915_DEPENDENCY_WEAK BIT(2) }; +#define for_each_waiter(p__, rq__) \ + list_for_each_entry_lockless(p__, \ + &(rq__)->sched.waiters_list, \ + wait_link) + +#define for_each_signaler(p__, rq__) \ + list_for_each_entry_rcu(p__, \ + &(rq__)->sched.signalers_list, \ + signal_link) + #endif /* _I915_SCHEDULER_TYPES_H_ */ From da7ac715d339d53dfb4e6ce325de842e80897814 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 19 Nov 2020 16:56:16 +0000 Subject: [PATCH 0025/5577] drm/i915: Show timeline dependencies for debug Include the signalers each request in the timeline is waiting on, as a means to try and identify the cause of a stall. This can be quite verbose, even as for now we only show each request in the timeline and its immediate antecedents. This generates output like: Timeline 886: { count 1, ready: 0, inflight: 0, seqno: { current: 664, last: 666 }, engine: rcs0 } U 886:29a- prio=0 @ 134ms: gem_exec_parall<4621> U bc1:27a- prio=0 @ 134ms: gem_exec_parall[4917] Timeline 825: { count 1, ready: 0, inflight: 0, seqno: { current: 802, last: 804 }, engine: vcs0 } U 825:324 prio=0 @ 107ms: gem_exec_parall<4518> U b75:140- prio=0 @ 110ms: gem_exec_parall<5486> Timeline b46: { count 1, ready: 0, inflight: 0, seqno: { current: 782, last: 784 }, engine: vcs0 } U b46:310- prio=0 @ 70ms: gem_exec_parall<5428> U c11:170- prio=0 @ 70ms: gem_exec_parall[5501] Timeline 96b: { count 1, ready: 0, inflight: 0, seqno: { current: 632, last: 634 }, engine: vcs0 } U 96b:27a- prio=0 @ 67ms: gem_exec_parall<4878> U b75:19e- prio=0 @ 67ms: gem_exec_parall<5486> Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201119165616.10834-6-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 3 ++- drivers/gpu/drm/i915/i915_scheduler.c | 28 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_scheduler.h | 7 +++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 354b95c438d0..263074c2c097 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -45,6 +45,7 @@ #include "i915_debugfs.h" #include "i915_debugfs_params.h" #include "i915_irq.h" +#include "i915_scheduler.h" #include "i915_trace.h" #include "intel_pm.h" #include "intel_sideband.h" @@ -1323,7 +1324,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) for_each_uabi_engine(engine, i915) intel_engine_dump(engine, &p, "%s\n", engine->name); - intel_gt_show_timelines(&i915->gt, &p, NULL); + intel_gt_show_timelines(&i915->gt, &p, i915_request_show_with_schedule); intel_runtime_pm_put(&i915->runtime_pm, wakeref); diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index cbb880b10c65..b9cf9931ebd7 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -504,6 +504,34 @@ void i915_sched_node_fini(struct i915_sched_node *node) spin_unlock_irq(&schedule_lock); } +void i915_request_show_with_schedule(struct drm_printer *m, + const struct i915_request *rq, + const char *prefix, + int indent) +{ + struct i915_dependency *dep; + + i915_request_show(m, rq, prefix, indent); + if (i915_request_completed(rq)) + return; + + rcu_read_lock(); + for_each_signaler(dep, rq) { + const struct i915_request *signaler = + node_to_request(dep->signaler); + + /* Dependencies along the same timeline are expected. */ + if (signaler->timeline == rq->timeline) + continue; + + if (i915_request_completed(signaler)) + continue; + + i915_request_show(m, signaler, prefix, indent + 2); + } + rcu_read_unlock(); +} + static void i915_global_scheduler_shrink(void) { kmem_cache_shrink(global.slab_dependencies); diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h index 6f0bf00fc569..4501e5ac2637 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.h +++ b/drivers/gpu/drm/i915/i915_scheduler.h @@ -13,6 +13,8 @@ #include "i915_scheduler_types.h" +struct drm_printer; + #define priolist_for_each_request(it, plist, idx) \ for (idx = 0; idx < ARRAY_SIZE((plist)->requests); idx++) \ list_for_each_entry(it, &(plist)->requests[idx], sched.link) @@ -54,4 +56,9 @@ static inline void i915_priolist_free(struct i915_priolist *p) __i915_priolist_free(p); } +void i915_request_show_with_schedule(struct drm_printer *m, + const struct i915_request *rq, + const char *prefix, + int indent); + #endif /* _I915_SCHEDULER_H_ */ From 67dd0b9677e895a60099fc0a4cc275f88cfee5a9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 20 Nov 2020 14:03:12 +0000 Subject: [PATCH 0026/5577] drm/i915/gem: Remove incorrect early dbg print We print out the "logical" context support before we discover whether or not the engines have logical contexts. No one, except Tvrtko, seems to have noticed the error, so the debug message must not be useful to anyone. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201120140314.24749-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 4fd38101bb56..a6299da64de4 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -904,9 +904,6 @@ static void init_contexts(struct i915_gem_contexts *gc) void i915_gem_init__contexts(struct drm_i915_private *i915) { init_contexts(&i915->gem.contexts); - drm_dbg(&i915->drm, "%s context support initialized\n", - DRIVER_CAPS(i915)->has_logical_contexts ? - "logical" : "fake"); } void i915_gem_driver_release__contexts(struct drm_i915_private *i915) From 8005f37ca941d59eda940910185015ed793491d3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 20 Nov 2020 14:03:13 +0000 Subject: [PATCH 0027/5577] drm/i915/selftests: Improve granularity for mocs reset checks Allow us to validate mocs configurations after reset if we have either engine or global reset. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201120140314.24749-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/selftest_mocs.c | 40 +++++++++++++------------ 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_mocs.c b/drivers/gpu/drm/i915/gt/selftest_mocs.c index b25eba50c88e..21dcd91cbd62 100644 --- a/drivers/gpu/drm/i915/gt/selftest_mocs.c +++ b/drivers/gpu/drm/i915/gt/selftest_mocs.c @@ -361,29 +361,34 @@ static int active_engine_reset(struct intel_context *ce, static int __live_mocs_reset(struct live_mocs *mocs, struct intel_context *ce) { + struct intel_gt *gt = ce->engine->gt; int err; - err = intel_engine_reset(ce->engine, "mocs"); - if (err) - return err; + if (intel_has_reset_engine(gt)) { + err = intel_engine_reset(ce->engine, "mocs"); + if (err) + return err; - err = check_mocs_engine(mocs, ce); - if (err) - return err; + err = check_mocs_engine(mocs, ce); + if (err) + return err; - err = active_engine_reset(ce, "mocs"); - if (err) - return err; + err = active_engine_reset(ce, "mocs"); + if (err) + return err; - err = check_mocs_engine(mocs, ce); - if (err) - return err; + err = check_mocs_engine(mocs, ce); + if (err) + return err; + } - intel_gt_reset(ce->engine->gt, ce->engine->mask, "mocs"); + if (intel_has_gpu_reset(gt)) { + intel_gt_reset(gt, ce->engine->mask, "mocs"); - err = check_mocs_engine(mocs, ce); - if (err) - return err; + err = check_mocs_engine(mocs, ce); + if (err) + return err; + } return 0; } @@ -398,9 +403,6 @@ static int live_mocs_reset(void *arg) /* Check the mocs setup is retained over per-engine and global resets */ - if (!intel_has_reset_engine(gt)) - return 0; - err = live_mocs_init(&mocs, gt); if (err) return err; From 16cfcb0f3c4bd20b03739a11f5292a3bb413bb24 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 20 Nov 2020 14:03:14 +0000 Subject: [PATCH 0028/5577] drm/i915/selftests: Small tweak to put the termination conditions together If we run out of ring space, or exceed the desired runtime, we wish to stop the subtest. Put these checks together, so that we always keep the requests flushed on completion. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201120140314.24749-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/selftest_timeline.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c index 2edf2b15885f..e4285d5a0360 100644 --- a/drivers/gpu/drm/i915/gt/selftest_timeline.c +++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c @@ -1090,12 +1090,6 @@ static int live_hwsp_read(void *arg) } count++; - if (8 * watcher[1].rq->ring->emit > - 3 * watcher[1].rq->ring->size) { - i915_request_put(rq); - break; - } - /* Flush the timeline before manually wrapping again */ if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE, @@ -1104,9 +1098,14 @@ static int live_hwsp_read(void *arg) i915_request_put(rq); goto out; } - retire_requests(tl); i915_request_put(rq); + + /* Single requests are limited to half a ring at most */ + if (8 * watcher[1].rq->ring->emit > + 3 * watcher[1].rq->ring->size) + break; + } while (!__igt_timeout(end_time, NULL)); WRITE_ONCE(*(u32 *)tl->hwsp_seqno, 0xdeadbeef); From 4ee73792574643b836b0503f06c27c0904c89f0e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 21 Nov 2020 19:03:52 +0000 Subject: [PATCH 0029/5577] drm/i915/gt: Plug IPS into intel_rps_set The old IPS interface did not match the RPS interface that we tried to plug it into (bool vs int return). Once repaired, our minimal selftesting is finally happy! Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201121190352.15996-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_rps.c | 34 +++++++++++++++++--------- drivers/gpu/drm/i915/gt/selftest_rps.c | 5 +++- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index 0d88f17799ff..b13e7845d483 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -400,7 +400,7 @@ static unsigned int gen5_invert_freq(struct intel_rps *rps, return val; } -static bool gen5_rps_set(struct intel_rps *rps, u8 val) +static int __gen5_rps_set(struct intel_rps *rps, u8 val) { struct intel_uncore *uncore = rps_to_uncore(rps); u16 rgvswctl; @@ -410,7 +410,7 @@ static bool gen5_rps_set(struct intel_rps *rps, u8 val) rgvswctl = intel_uncore_read16(uncore, MEMSWCTL); if (rgvswctl & MEMCTL_CMD_STS) { DRM_DEBUG("gpu busy, RCS change rejected\n"); - return false; /* still busy with another command */ + return -EBUSY; /* still busy with another command */ } /* Invert the frequency bin into an ips delay */ @@ -426,7 +426,18 @@ static bool gen5_rps_set(struct intel_rps *rps, u8 val) rgvswctl |= MEMCTL_CMD_STS; intel_uncore_write16(uncore, MEMSWCTL, rgvswctl); - return true; + return 0; +} + +static int gen5_rps_set(struct intel_rps *rps, u8 val) +{ + int err; + + spin_lock_irq(&mchdev_lock); + err = __gen5_rps_set(rps, val); + spin_unlock_irq(&mchdev_lock); + + return err; } static unsigned long intel_pxfreq(u32 vidfreq) @@ -557,7 +568,7 @@ static bool gen5_rps_enable(struct intel_rps *rps) "stuck trying to change perf mode\n"); mdelay(1); - gen5_rps_set(rps, rps->cur_freq); + __gen5_rps_set(rps, rps->cur_freq); rps->ips.last_count1 = intel_uncore_read(uncore, DMIEC); rps->ips.last_count1 += intel_uncore_read(uncore, DDREC); @@ -599,7 +610,7 @@ static void gen5_rps_disable(struct intel_rps *rps) intel_uncore_write(uncore, MEMINTRSTS, MEMINT_EVAL_CHG); /* Go back to the starting frequency */ - gen5_rps_set(rps, rps->idle_freq); + __gen5_rps_set(rps, rps->idle_freq); mdelay(1); rgvswctl |= MEMCTL_CMD_STS; intel_uncore_write(uncore, MEMSWCTL, rgvswctl); @@ -797,20 +808,19 @@ static int rps_set(struct intel_rps *rps, u8 val, bool update) struct drm_i915_private *i915 = rps_to_i915(rps); int err; - if (INTEL_GEN(i915) < 6) - return 0; - if (val == rps->last_freq) return 0; if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) err = vlv_rps_set(rps, val); - else + else if (INTEL_GEN(i915) >= 6) err = gen6_rps_set(rps, val); + else + err = gen5_rps_set(rps, val); if (err) return err; - if (update) + if (update && INTEL_GEN(i915) >= 6) gen6_rps_set_thresholds(rps, val); rps->last_freq = val; @@ -1794,7 +1804,7 @@ void gen5_rps_irq_handler(struct intel_rps *rps) rps->min_freq_softlimit, rps->max_freq_softlimit); - if (new_freq != rps->cur_freq && gen5_rps_set(rps, new_freq)) + if (new_freq != rps->cur_freq && !__gen5_rps_set(rps, new_freq)) rps->cur_freq = new_freq; spin_unlock(&mchdev_lock); @@ -2105,7 +2115,7 @@ bool i915_gpu_turbo_disable(void) spin_lock_irq(&mchdev_lock); rps->max_freq_softlimit = rps->min_freq; - ret = gen5_rps_set(&i915->gt.rps, rps->min_freq); + ret = !__gen5_rps_set(&i915->gt.rps, rps->min_freq); spin_unlock_irq(&mchdev_lock); drm_dev_put(&i915->drm); diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.c b/drivers/gpu/drm/i915/gt/selftest_rps.c index aa5675ecb5cc..967641fee42a 100644 --- a/drivers/gpu/drm/i915/gt/selftest_rps.c +++ b/drivers/gpu/drm/i915/gt/selftest_rps.c @@ -185,7 +185,10 @@ static u8 rps_set_check(struct intel_rps *rps, u8 freq) { mutex_lock(&rps->lock); GEM_BUG_ON(!intel_rps_is_active(rps)); - intel_rps_set(rps, freq); + if (wait_for(!intel_rps_set(rps, freq), 50)) { + mutex_unlock(&rps->lock); + return 0; + } GEM_BUG_ON(rps->last_freq != freq); mutex_unlock(&rps->lock); From 9d5612ca165a58aacc160465532e7998b9aab270 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Nov 2020 11:37:14 +0000 Subject: [PATCH 0030/5577] drm/i915/gt: Defer enabling the breadcrumb interrupt to after submission Move the register slow register write and readback from out of the critical path for execlists submission and delay it until the following worker, shaving off around 200us. Note that the same signal_irq_work() is allowed to run concurrently on each CPU (but it will only be queued once, once running though it can be requeued and reexecuted) so we have to remember to lock the global interactions as we cannot rely on the signal_irq_work() itself providing the serialisation (in constrast to a tasklet). By pushing the arm/disarm into the central signaling worker we can close the race for disarming the interrupt (and dropping its associated GT wakeref) on parking the engine. If we loose the race, that GT wakeref may be held indefinitely, preventing the machine from sleeping while the GPU is ostensibly idle. v2: Move the self-arming parking of the signal_irq_work to a flush of the irq-work from intel_breadcrumbs_park(). Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2271 Fixes: e23005604b2f ("drm/i915/gt: Hold context/request reference while breadcrumbs are active") Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201123113717.20500-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 109 +++++++++++++------- 1 file changed, 70 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index d8b206e53660..8d85683314e1 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -30,18 +30,21 @@ #include "i915_trace.h" #include "intel_breadcrumbs.h" #include "intel_context.h" +#include "intel_engine_pm.h" #include "intel_gt_pm.h" #include "intel_gt_requests.h" -static void irq_enable(struct intel_engine_cs *engine) +static bool irq_enable(struct intel_engine_cs *engine) { if (!engine->irq_enable) - return; + return false; /* Caller disables interrupts */ spin_lock(&engine->gt->irq_lock); engine->irq_enable(engine); spin_unlock(&engine->gt->irq_lock); + + return true; } static void irq_disable(struct intel_engine_cs *engine) @@ -57,12 +60,11 @@ static void irq_disable(struct intel_engine_cs *engine) static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) { - lockdep_assert_held(&b->irq_lock); - - if (!b->irq_engine || b->irq_armed) - return; - - if (!intel_gt_pm_get_if_awake(b->irq_engine->gt)) + /* + * Since we are waiting on a request, the GPU should be busy + * and should have its own rpm reference. + */ + if (GEM_WARN_ON(!intel_gt_pm_get_if_awake(b->irq_engine->gt))) return; /* @@ -73,25 +75,24 @@ static void __intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) */ WRITE_ONCE(b->irq_armed, true); - /* - * Since we are waiting on a request, the GPU should be busy - * and should have its own rpm reference. This is tracked - * by i915->gt.awake, we can forgo holding our own wakref - * for the interrupt as before i915->gt.awake is released (when - * the driver is idle) we disarm the breadcrumbs. - */ + /* Requests may have completed before we could enable the interrupt. */ + if (!b->irq_enabled++ && irq_enable(b->irq_engine)) + irq_work_queue(&b->irq_work); +} - if (!b->irq_enabled++) - irq_enable(b->irq_engine); +static void intel_breadcrumbs_arm_irq(struct intel_breadcrumbs *b) +{ + if (!b->irq_engine) + return; + + spin_lock(&b->irq_lock); + if (!b->irq_armed) + __intel_breadcrumbs_arm_irq(b); + spin_unlock(&b->irq_lock); } static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) { - lockdep_assert_held(&b->irq_lock); - - if (!b->irq_engine || !b->irq_armed) - return; - GEM_BUG_ON(!b->irq_enabled); if (!--b->irq_enabled) irq_disable(b->irq_engine); @@ -105,8 +106,6 @@ static void add_signaling_context(struct intel_breadcrumbs *b, { intel_context_get(ce); list_add_tail(&ce->signal_link, &b->signalers); - if (list_is_first(&ce->signal_link, &b->signalers)) - __intel_breadcrumbs_arm_irq(b); } static void remove_signaling_context(struct intel_breadcrumbs *b, @@ -197,7 +196,32 @@ static void signal_irq_work(struct irq_work *work) spin_lock(&b->irq_lock); - if (list_empty(&b->signalers)) + /* + * Keep the irq armed until the interrupt after all listeners are gone. + * + * Enabling/disabling the interrupt is rather costly, roughly a couple + * of hundred microseconds. If we are proactive and enable/disable + * the interrupt around every request that wants a breadcrumb, we + * quickly drown in the extra orders of magnitude of latency imposed + * on request submission. + * + * So we try to be lazy, and keep the interrupts enabled until no + * more listeners appear within a breadcrumb interrupt interval (that + * is until a request completes that no one cares about). The + * observation is that listeners come in batches, and will often + * listen to a bunch of requests in succession. Though note on icl+, + * interrupts are always enabled due to concerns with rc6 being + * dysfunctional with per-engine interrupt masking. + * + * We also try to avoid raising too many interrupts, as they may + * be generated by userspace batches and it is unfortunately rather + * too easy to drown the CPU under a flood of GPU interrupts. Thus + * whenever no one appears to be listening, we turn off the interrupts. + * Fewer interrupts should conserve power -- at the very least, fewer + * interrupt draw less ire from other users of the system and tools + * like powertop. + */ + if (b->irq_armed && list_empty(&b->signalers)) __intel_breadcrumbs_disarm_irq(b); list_splice_init(&b->signaled_requests, &signal); @@ -251,6 +275,9 @@ static void signal_irq_work(struct irq_work *work) i915_request_put(rq); } + + if (!READ_ONCE(b->irq_armed) && !list_empty(&b->signalers)) + intel_breadcrumbs_arm_irq(b); } struct intel_breadcrumbs * @@ -292,21 +319,22 @@ void intel_breadcrumbs_reset(struct intel_breadcrumbs *b) void intel_breadcrumbs_park(struct intel_breadcrumbs *b) { - unsigned long flags; - - if (!READ_ONCE(b->irq_armed)) - return; - - spin_lock_irqsave(&b->irq_lock, flags); - __intel_breadcrumbs_disarm_irq(b); - spin_unlock_irqrestore(&b->irq_lock, flags); - - if (!list_empty(&b->signalers)) - irq_work_queue(&b->irq_work); + /* Kick the work once more to drain the signalers */ + irq_work_sync(&b->irq_work); + while (unlikely(READ_ONCE(b->irq_armed))) { + local_irq_disable(); + signal_irq_work(&b->irq_work); + local_irq_enable(); + cond_resched(); + } + GEM_BUG_ON(!list_empty(&b->signalers)); } void intel_breadcrumbs_free(struct intel_breadcrumbs *b) { + irq_work_sync(&b->irq_work); + GEM_BUG_ON(!list_empty(&b->signalers)); + GEM_BUG_ON(b->irq_armed); kfree(b); } @@ -362,9 +390,12 @@ static void insert_breadcrumb(struct i915_request *rq, GEM_BUG_ON(!check_signal_order(ce, rq)); set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); - /* Check after attaching to irq, interrupt may have already fired. */ - if (__request_completed(rq)) - irq_work_queue(&b->irq_work); + /* + * Defer enabling the interrupt to after HW submission and recheck + * the request as it may have completed and raised the interrupt as + * we were attaching it into the lists. + */ + irq_work_queue(&b->irq_work); } bool i915_request_enable_breadcrumb(struct i915_request *rq) From 6cfe66eb71b638968350b5f0fff051fd25eb75fb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Nov 2020 11:37:15 +0000 Subject: [PATCH 0031/5577] drm/i915/gt: Track signaled breadcrumbs outside of the breadcrumb spinlock Make b->signaled_requests a lockless-list so that we can manipulate it outside of the b->irq_lock. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201123113717.20500-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 34 ++++++++++++------- .../gpu/drm/i915/gt/intel_breadcrumbs_types.h | 2 +- drivers/gpu/drm/i915/i915_request.h | 6 +++- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index 8d85683314e1..43cfabb102ea 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -173,26 +173,34 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl) intel_engine_add_retire(b->irq_engine, tl); } -static bool __signal_request(struct i915_request *rq, struct list_head *signals) +static bool __signal_request(struct i915_request *rq) { - clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); - if (!__dma_fence_signal(&rq->fence)) { i915_request_put(rq); return false; } - list_add_tail(&rq->signal_link, signals); return true; } +static struct llist_node * +slist_add(struct llist_node *node, struct llist_node *head) +{ + node->next = head; + return node; +} + static void signal_irq_work(struct irq_work *work) { struct intel_breadcrumbs *b = container_of(work, typeof(*b), irq_work); const ktime_t timestamp = ktime_get(); + struct llist_node *signal, *sn; struct intel_context *ce, *cn; struct list_head *pos, *next; - LIST_HEAD(signal); + + signal = NULL; + if (unlikely(!llist_empty(&b->signaled_requests))) + signal = llist_del_all(&b->signaled_requests); spin_lock(&b->irq_lock); @@ -224,8 +232,6 @@ static void signal_irq_work(struct irq_work *work) if (b->irq_armed && list_empty(&b->signalers)) __intel_breadcrumbs_disarm_irq(b); - list_splice_init(&b->signaled_requests, &signal); - list_for_each_entry_safe(ce, cn, &b->signalers, signal_link) { GEM_BUG_ON(list_empty(&ce->signals)); @@ -242,7 +248,10 @@ static void signal_irq_work(struct irq_work *work) * spinlock as the callback chain may end up adding * more signalers to the same context or engine. */ - __signal_request(rq, &signal); + clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); + if (__signal_request(rq)) + /* We own signal_node now, xfer to local list */ + signal = slist_add(&rq->signal_node, signal); } /* @@ -262,9 +271,9 @@ static void signal_irq_work(struct irq_work *work) spin_unlock(&b->irq_lock); - list_for_each_safe(pos, next, &signal) { + llist_for_each_safe(signal, sn, signal) { struct i915_request *rq = - list_entry(pos, typeof(*rq), signal_link); + llist_entry(signal, typeof(*rq), signal_node); struct list_head cb_list; spin_lock(&rq->lock); @@ -291,7 +300,7 @@ intel_breadcrumbs_create(struct intel_engine_cs *irq_engine) spin_lock_init(&b->irq_lock); INIT_LIST_HEAD(&b->signalers); - INIT_LIST_HEAD(&b->signaled_requests); + init_llist_head(&b->signaled_requests); init_irq_work(&b->irq_work, signal_irq_work); @@ -355,7 +364,8 @@ static void insert_breadcrumb(struct i915_request *rq, * its signal completion. */ if (__request_completed(rq)) { - if (__signal_request(rq, &b->signaled_requests)) + if (__signal_request(rq) && + llist_add(&rq->signal_node, &b->signaled_requests)) irq_work_queue(&b->irq_work); return; } diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h index 8e53b9942695..3fa19820b37a 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h @@ -35,7 +35,7 @@ struct intel_breadcrumbs { struct intel_engine_cs *irq_engine; struct list_head signalers; - struct list_head signaled_requests; + struct llist_head signaled_requests; struct irq_work irq_work; /* for use from inside irq_lock */ diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 8f6173b1c3df..b222f7b46e9c 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -177,7 +177,11 @@ struct i915_request { struct intel_context *context; struct intel_ring *ring; struct intel_timeline __rcu *timeline; - struct list_head signal_link; + + union { + struct list_head signal_link; + struct llist_node signal_node; + }; /* * The rcu epoch of when this request was allocated. Used to judiciously From 3aef910d26ef48b8a79d48b006dc04383b86dd31 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Nov 2020 11:37:16 +0000 Subject: [PATCH 0032/5577] drm/i915/gt: Don't cancel the interrupt shadow too early We currently want to keep the interrupt enabled until the interrupt after which we have no more work to do. This heuristic was broken by us kicking the irq-work on adding a completed request without attaching a signaler -- hence it appearing to the irq-worker that an interrupt had fired when we were idle. Fixes: 2854d866327a ("drm/i915/gt: Replace intel_engine_transfer_stale_breadcrumbs") Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201123113717.20500-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index 43cfabb102ea..cf6e05ea4d8f 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -229,7 +229,7 @@ static void signal_irq_work(struct irq_work *work) * interrupt draw less ire from other users of the system and tools * like powertop. */ - if (b->irq_armed && list_empty(&b->signalers)) + if (!signal && b->irq_armed && list_empty(&b->signalers)) __intel_breadcrumbs_disarm_irq(b); list_for_each_entry_safe(ce, cn, &b->signalers, signal_link) { From 46eecfccb4c2b0f258adbafb2e53ca3b822cd663 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Nov 2020 11:37:17 +0000 Subject: [PATCH 0033/5577] drm/i915/gt: Free stale request on destroying the virtual engine Since preempt-to-busy, we may unsubmit a request while it is still on the HW and completes asynchronously. That means it may be retired and in the process destroy the virtual engine (as the user has closed their context), but that engine may still be holding onto the unsubmitted compelted request. Therefore we need to potentially cleanup the old request on destroying the virtual engine. We also have to keep the virtual_engine alive until after the sibling's execlists_dequeue() have finished peeking into the virtual engines, for which we serialise with RCU. v2: Be paranoid and flush the tasklet as well. v3: And flush the tasklet before the engines, as the tasklet may re-attach an rb_node after our removal from the siblings. Fixes: 6d06779e8672 ("drm/i915: Load balancing across a virtual engine") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201123113717.20500-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 60 +++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 30759e95da0e..30aa59fb7271 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -182,6 +182,7 @@ struct virtual_engine { struct intel_engine_cs base; struct intel_context context; + struct rcu_work rcu; /* * We allow only a single request through the virtual engine at a time @@ -5470,33 +5471,57 @@ static struct list_head *virtual_queue(struct virtual_engine *ve) return &ve->base.execlists.default_priolist.requests[0]; } -static void virtual_context_destroy(struct kref *kref) +static void rcu_virtual_context_destroy(struct work_struct *wrk) { struct virtual_engine *ve = - container_of(kref, typeof(*ve), context.ref); + container_of(wrk, typeof(*ve), rcu.work); unsigned int n; - GEM_BUG_ON(!list_empty(virtual_queue(ve))); - GEM_BUG_ON(ve->request); GEM_BUG_ON(ve->context.inflight); + /* Preempt-to-busy may leave a stale request behind. */ + if (unlikely(ve->request)) { + struct i915_request *old; + + spin_lock_irq(&ve->base.active.lock); + + old = fetch_and_zero(&ve->request); + if (old) { + GEM_BUG_ON(!i915_request_completed(old)); + __i915_request_submit(old); + i915_request_put(old); + } + + spin_unlock_irq(&ve->base.active.lock); + } + + /* + * Flush the tasklet in case it is still running on another core. + * + * This needs to be done before we remove ourselves from the siblings' + * rbtrees as in the case it is running in parallel, it may reinsert + * the rb_node into a sibling. + */ + tasklet_kill(&ve->base.execlists.tasklet); + + /* Decouple ourselves from the siblings, no more access allowed. */ for (n = 0; n < ve->num_siblings; n++) { struct intel_engine_cs *sibling = ve->siblings[n]; struct rb_node *node = &ve->nodes[sibling->id].rb; - unsigned long flags; if (RB_EMPTY_NODE(node)) continue; - spin_lock_irqsave(&sibling->active.lock, flags); + spin_lock_irq(&sibling->active.lock); /* Detachment is lazily performed in the execlists tasklet */ if (!RB_EMPTY_NODE(node)) rb_erase_cached(node, &sibling->execlists.virtual); - spin_unlock_irqrestore(&sibling->active.lock, flags); + spin_unlock_irq(&sibling->active.lock); } GEM_BUG_ON(__tasklet_is_scheduled(&ve->base.execlists.tasklet)); + GEM_BUG_ON(!list_empty(virtual_queue(ve))); if (ve->context.state) __execlists_context_fini(&ve->context); @@ -5509,6 +5534,27 @@ static void virtual_context_destroy(struct kref *kref) kfree(ve); } +static void virtual_context_destroy(struct kref *kref) +{ + struct virtual_engine *ve = + container_of(kref, typeof(*ve), context.ref); + + GEM_BUG_ON(!list_empty(&ve->context.signals)); + + /* + * When destroying the virtual engine, we have to be aware that + * it may still be in use from an hardirq/softirq context causing + * the resubmission of a completed request (background completion + * due to preempt-to-busy). Before we can free the engine, we need + * to flush the submission code and tasklets that are still potentially + * accessing the engine. Flushing the tasklets requires process context, + * and since we can guard the resubmit onto the engine with an RCU read + * lock, we can delegate the free of the engine to an RCU worker. + */ + INIT_RCU_WORK(&ve->rcu, rcu_virtual_context_destroy); + queue_rcu_work(system_wq, &ve->rcu); +} + static void virtual_engine_initial_hint(struct virtual_engine *ve) { int swp; From 016669752c36eb67c95f91c3fbcf3b4c890d0703 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 20 Nov 2020 09:56:35 +0000 Subject: [PATCH 0034/5577] drm/i915/guc: Use correct lock for accessing guc->mmio_msg Guc->mmio_msg is set under the guc->irq_lock in guc_get_mmio_msg so it should be consumed under the same lock from guc_handle_mmio_msg. I am not sure if the overall flow here makes complete sense but at least the correct lock is now used. Signed-off-by: Tvrtko Ursulin Cc: Daniele Ceraolo Spurio Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201120095636.1987395-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/gt/uc/intel_uc.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c index 4e6070e95fe9..220626c3ad81 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c @@ -175,19 +175,15 @@ static void guc_get_mmio_msg(struct intel_guc *guc) static void guc_handle_mmio_msg(struct intel_guc *guc) { - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; - /* we need communication to be enabled to reply to GuC */ GEM_BUG_ON(!guc_communication_enabled(guc)); - if (!guc->mmio_msg) - return; - - spin_lock_irq(&i915->irq_lock); - intel_guc_to_host_process_recv_msg(guc, &guc->mmio_msg, 1); - spin_unlock_irq(&i915->irq_lock); - - guc->mmio_msg = 0; + spin_lock_irq(&guc->irq_lock); + if (guc->mmio_msg) { + intel_guc_to_host_process_recv_msg(guc, &guc->mmio_msg, 1); + guc->mmio_msg = 0; + } + spin_unlock_irq(&guc->irq_lock); } static void guc_reset_interrupts(struct intel_guc *guc) From 2f87c053ac489309c04b51f788e2b4f13a737ca9 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 20 Nov 2020 09:56:36 +0000 Subject: [PATCH 0035/5577] drm/i915/guc: Use correct lock for CT event handler CT event handler is called under the gt->irq_lock from the interrupt handling paths so make it the same from the init path. I don't think this mismatch caused any functional issue but we need to wean the code of the global i915->irq_lock. Signed-off-by: Tvrtko Ursulin Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20201120095636.1987395-2-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/gt/uc/intel_uc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c index 220626c3ad81..6a0452815c41 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c @@ -203,7 +203,8 @@ static void guc_disable_interrupts(struct intel_guc *guc) static int guc_enable_communication(struct intel_guc *guc) { - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; + struct intel_gt *gt = guc_to_gt(guc); + struct drm_i915_private *i915 = gt->i915; int ret; GEM_BUG_ON(guc_communication_enabled(guc)); @@ -223,9 +224,9 @@ static int guc_enable_communication(struct intel_guc *guc) guc_enable_interrupts(guc); /* check for CT messages received before we enabled interrupts */ - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(>->irq_lock); intel_guc_ct_event_handler(&guc->ct); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(>->irq_lock); drm_dbg(&i915->drm, "GuC communication enabled\n"); From 977933b5da7c16f39295c4c1d4259a58ece65dbe Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 26 Nov 2020 14:08:41 +0000 Subject: [PATCH 0036/5577] drm/i915/gt: Program mocs:63 for cache eviction on gen9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ville noticed that the last mocs entry is used unconditionally by the HW when it performs cache evictions, and noted that while the value is not meant to be writable by the driver, we should program it to a reasonable value nevertheless. As it turns out, we can change the value of mocs:63 and the value we were programming into it would cause hard hangs in conjunction with atomic operations. v2: Add details from bspec about how it is used by HW Suggested-by: Ville Syrjälä Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2707 Fixes: 3bbaba0ceaa2 ("drm/i915: Added Programming of the MOCS") Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Jason Ekstrand Cc: # v4.3+ Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201126140841.1982-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_mocs.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c index 254873e1646e..b8d0c32ae9dd 100644 --- a/drivers/gpu/drm/i915/gt/intel_mocs.c +++ b/drivers/gpu/drm/i915/gt/intel_mocs.c @@ -131,7 +131,19 @@ static const struct drm_i915_mocs_entry skl_mocs_table[] = { GEN9_MOCS_ENTRIES, MOCS_ENTRY(I915_MOCS_CACHED, LE_3_WB | LE_TC_2_LLC_ELLC | LE_LRUM(3), - L3_3_WB) + L3_3_WB), + + /* + * mocs:63 + * - used by the L3 for all of its evictions. + * Thus it is expected to allow LLC cacheability to enable coherent + * flows to be maintained. + * - used to force L3 uncachable cycles. + * Thus it is expected to make the surface L3 uncacheable. + */ + MOCS_ENTRY(63, + LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), + L3_1_UC) }; /* NOTE: the LE_TGT_CACHE is not used on Broxton */ From b8e2bd98a2c9c3a90856c1909aab30d25d379c31 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 26 Nov 2020 14:04:03 +0000 Subject: [PATCH 0037/5577] drm/i915/gt: Decouple completed requests on unwind Since the introduction of preempt-to-busy, requests can complete in the background, even while they are not on the engine->active.requests list. As such, the engine->active.request list itself is not in strict retirement order, and we have to scan the entire list while unwinding to not miss any. However, if the request is completed we currently leave it on the list [until retirement], but we could just as simply remove it and stop treating it as active. We would only have to then traverse it once while unwinding in quick succession. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201126140407.31952-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 6 ++++-- drivers/gpu/drm/i915/i915_request.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 30aa59fb7271..cf11cbac241b 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1116,8 +1116,10 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine) list_for_each_entry_safe_reverse(rq, rn, &engine->active.requests, sched.link) { - if (i915_request_completed(rq)) - continue; /* XXX */ + if (i915_request_completed(rq)) { + list_del_init(&rq->sched.link); + continue; + } __i915_request_unsubmit(rq); diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 8d7d29c9e375..a9db1376b996 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -321,7 +321,8 @@ bool i915_request_retire(struct i915_request *rq) * after removing the breadcrumb and signaling it, so that we do not * inadvertently attach the breadcrumb to a completed request. */ - remove_from_engine(rq); + if (!list_empty(&rq->sched.link)) + remove_from_engine(rq); GEM_BUG_ON(!llist_empty(&rq->execute_cb)); __list_del_entry(&rq->link); /* poison neither prev/next (RCU walks) */ From a58559898abe3bb3f8aebef6ccbef66260625be5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 26 Nov 2020 14:04:04 +0000 Subject: [PATCH 0038/5577] drm/i915/gt: Check for a completed last request once Pull the repeated check for the last active request being completed to a single spot, when deciding whether or not execlist preemption is required. In doing so, we remove the tasklet kick, introduced with the completion checks in commit 35f3fd8182ba ("drm/i915/execlists: Workaround switching back to a completed context"), if we find the request was completed but have not yet seen the corresponding CS event. This was devolving into a busy spin of the tasklet while we waited for the event as the delivery was not as instantaneous as expected. Under load this is sufficient to exhaust the tasklet softirq timeslice, and force ksoftirqd. Quite noticeable overhead for no apparent improvement in latency. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201126140407.31952-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index cf11cbac241b..43703efb36d1 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2141,12 +2141,9 @@ static void execlists_dequeue(struct intel_engine_cs *engine) */ if ((last = *active)) { - if (need_preempt(engine, last, rb)) { - if (i915_request_completed(last)) { - tasklet_hi_schedule(&execlists->tasklet); - return; - } - + if (i915_request_completed(last)) { + goto check_secondary; + } else if (need_preempt(engine, last, rb)) { ENGINE_TRACE(engine, "preempting last=%llx:%lld, prio=%d, hint=%d\n", last->fence.context, @@ -2174,11 +2171,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine) last = NULL; } else if (need_timeslice(engine, last, rb) && timeslice_expired(execlists, last)) { - if (i915_request_completed(last)) { - tasklet_hi_schedule(&execlists->tasklet); - return; - } - ENGINE_TRACE(engine, "expired last=%llx:%lld, prio=%d, hint=%d, yield?=%s\n", last->fence.context, @@ -2214,6 +2206,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) * we hopefully coalesce several updates into a single * submission. */ +check_secondary: if (!list_is_last(&last->sched.link, &engine->active.requests)) { /* From 14d1eaf08845c534963c83f754afe0cb14cb2512 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 26 Nov 2020 14:04:05 +0000 Subject: [PATCH 0039/5577] drm/i915/gt: Protect context lifetime with RCU Allow a brief period for continued access to a dead intel_context by deferring the release of the struct until after an RCU grace period. As we are using a dedicated slab cache for the contexts, we can defer the release of the slab pages via RCU, with the caveat that individual structs may be reused from the freelist within an RCU grace period. To handle that, we have to avoid clearing members of the zombie struct. This is required for a later patch to handle locking around virtual requests in the signaler, as those requests may want to move between engines and be destroyed while we are holding b->irq_lock on a physical engine. v2: Drop mutex_reinit(), if we never mark the mutex as destroyed we don't need to reset the debug code, at the loss of having the mutex debug code spot us attempting to destroy a locked mutex. v3: As the intended use will remain strongly referenced counted, with very little inflight access across reuse, drop the ctor. v4: Drop the unrequired change to remove the temporary reference around dropping the active context, and add back some more missing ctor operations. v5: The ctor is back. Tvrtko spotted that ce->signal_lock [introduced later] maybe accessed under RCU and so needs special care not to be reinitialised. v6: Don't mix SLAB_TYPESAFE_BY_RCU and RCU list iteration. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201126140407.31952-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_context.c | 12 +++++++++--- drivers/gpu/drm/i915/gt/intel_context_types.h | 11 ++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index 92a3f25c4006..d3a835212167 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -25,9 +25,16 @@ static struct intel_context *intel_context_alloc(void) return kmem_cache_zalloc(global.slab_ce, GFP_KERNEL); } +static void rcu_context_free(struct rcu_head *rcu) +{ + struct intel_context *ce = container_of(rcu, typeof(*ce), rcu); + + kmem_cache_free(global.slab_ce, ce); +} + void intel_context_free(struct intel_context *ce) { - kmem_cache_free(global.slab_ce, ce); + call_rcu(&ce->rcu, rcu_context_free); } struct intel_context * @@ -356,8 +363,7 @@ static int __intel_context_active(struct i915_active *active) } void -intel_context_init(struct intel_context *ce, - struct intel_engine_cs *engine) +intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine) { GEM_BUG_ON(!engine->cops); GEM_BUG_ON(!engine->gt->vm); diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 552cb57a2e8c..20cb5835d1c3 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -44,7 +44,16 @@ struct intel_context_ops { }; struct intel_context { - struct kref ref; + /* + * Note: Some fields may be accessed under RCU. + * + * Unless otherwise noted a field can safely be assumed to be protected + * by strong reference counting. + */ + union { + struct kref ref; /* no kref_get_unless_zero()! */ + struct rcu_head rcu; + }; struct intel_engine_cs *engine; struct intel_engine_cs *inflight; From c744d50363b714783bbc88d986cc16def13710f7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 26 Nov 2020 14:04:06 +0000 Subject: [PATCH 0040/5577] drm/i915/gt: Split the breadcrumb spinlock between global and contexts As we funnel more and more contexts into the breadcrumbs on an engine, the hold time of b->irq_lock grows. As we may then contend with the b->irq_lock during request submission, this increases the burden upon the engine->active.lock and so directly impacts both our execution latency and client latency. If we split the b->irq_lock by introducing a per-context spinlock to manage the signalers within a context, we then only need the b->irq_lock for enabling/disabling the interrupt and can avoid taking the lock for walking the list of contexts within the signal worker. Even with the current setup, this greatly reduces the number of times we have to take and fight for b->irq_lock. Furthermore, this closes the race between enabling the signaling context while it is in the process of being signaled and removed: <4>[ 416.208555] list_add corruption. prev->next should be next (ffff8881951d5910), but was dead000000000100. (prev=ffff8882781bb870). <4>[ 416.208573] WARNING: CPU: 7 PID: 0 at lib/list_debug.c:28 __list_add_valid+0x4d/0x70 <4>[ 416.208575] Modules linked in: i915(+) vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio mei_hdcp x86_pkg_temp_thermal coretemp ax88179_178a usbnet mii crct10dif_pclmul snd_intel_dspcfg crc32_pclmul snd_hda_codec snd_hwdep ghash_clmulni_intel snd_hda_core e1000e snd_pcm ptp pps_core mei_me mei prime_numbers intel_lpss_pci [last unloaded: i915] <4>[ 416.208611] CPU: 7 PID: 0 Comm: swapper/7 Tainted: G U 5.8.0-CI-CI_DRM_8852+ #1 <4>[ 416.208614] Hardware name: Intel Corporation Ice Lake Client Platform/IceLake Y LPDDR4x T4 RVP TLC, BIOS ICLSFWR1.R00.3212.A00.1905212112 05/21/2019 <4>[ 416.208627] RIP: 0010:__list_add_valid+0x4d/0x70 <4>[ 416.208631] Code: c3 48 89 d1 48 c7 c7 60 18 33 82 48 89 c2 e8 ea e0 b6 ff 0f 0b 31 c0 c3 48 89 c1 4c 89 c6 48 c7 c7 b0 18 33 82 e8 d3 e0 b6 ff <0f> 0b 31 c0 c3 48 89 f2 4c 89 c1 48 89 fe 48 c7 c7 00 19 33 82 e8 <4>[ 416.208633] RSP: 0018:ffffc90000280e18 EFLAGS: 00010086 <4>[ 416.208636] RAX: 0000000000000000 RBX: ffff888250a44880 RCX: 0000000000000105 <4>[ 416.208639] RDX: 0000000000000105 RSI: ffffffff82320c5b RDI: 00000000ffffffff <4>[ 416.208641] RBP: ffff8882781bb870 R08: 0000000000000000 R09: 0000000000000001 <4>[ 416.208643] R10: 00000000054d2957 R11: 000000006abbd991 R12: ffff8881951d58c8 <4>[ 416.208646] R13: ffff888286073880 R14: ffff888286073848 R15: ffff8881951d5910 <4>[ 416.208669] FS: 0000000000000000(0000) GS:ffff88829c180000(0000) knlGS:0000000000000000 <4>[ 416.208671] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4>[ 416.208673] CR2: 0000556231326c48 CR3: 0000000005610001 CR4: 0000000000760ee0 <4>[ 416.208675] PKRU: 55555554 <4>[ 416.208677] Call Trace: <4>[ 416.208679] <4>[ 416.208751] i915_request_enable_breadcrumb+0x278/0x400 [i915] <4>[ 416.208839] __i915_request_submit+0xca/0x2a0 [i915] <4>[ 416.208892] __execlists_submission_tasklet+0x480/0x1830 [i915] <4>[ 416.208942] execlists_submission_tasklet+0xc4/0x130 [i915] <4>[ 416.208947] tasklet_action_common.isra.17+0x6c/0x1c0 <4>[ 416.208954] __do_softirq+0xdf/0x498 <4>[ 416.208960] ? handle_fasteoi_irq+0x150/0x150 <4>[ 416.208964] asm_call_on_stack+0xf/0x20 <4>[ 416.208966] <4>[ 416.208969] do_softirq_own_stack+0xa1/0xc0 <4>[ 416.208972] irq_exit_rcu+0xb5/0xc0 <4>[ 416.208976] common_interrupt+0xf7/0x260 <4>[ 416.208980] asm_common_interrupt+0x1e/0x40 <4>[ 416.208985] RIP: 0010:cpuidle_enter_state+0xb6/0x410 <4>[ 416.208987] Code: 00 31 ff e8 9c 3e 89 ff 80 7c 24 0b 00 74 12 9c 58 f6 c4 02 0f 85 31 03 00 00 31 ff e8 e3 6c 90 ff e8 fe a4 94 ff fb 45 85 ed <0f> 88 c7 02 00 00 49 63 c5 4c 2b 24 24 48 8d 14 40 48 8d 14 90 48 <4>[ 416.208989] RSP: 0018:ffffc90000143e70 EFLAGS: 00000206 <4>[ 416.208991] RAX: 0000000000000007 RBX: ffffe8ffffda8070 RCX: 0000000000000000 <4>[ 416.208993] RDX: 0000000000000000 RSI: ffffffff8238b4ee RDI: ffffffff8233184f <4>[ 416.208995] RBP: ffffffff826b4e00 R08: 0000000000000000 R09: 0000000000000000 <4>[ 416.208997] R10: 0000000000000001 R11: 0000000000000000 R12: 00000060e7f24a8f <4>[ 416.208998] R13: 0000000000000003 R14: 0000000000000003 R15: 0000000000000003 <4>[ 416.209012] cpuidle_enter+0x24/0x40 <4>[ 416.209016] do_idle+0x22f/0x2d0 <4>[ 416.209022] cpu_startup_entry+0x14/0x20 <4>[ 416.209025] start_secondary+0x158/0x1a0 <4>[ 416.209030] secondary_startup_64+0xa4/0xb0 <4>[ 416.209039] irq event stamp: 10186977 <4>[ 416.209042] hardirqs last enabled at (10186976): [] tasklet_action_common.isra.17+0xe3/0x1c0 <4>[ 416.209044] hardirqs last disabled at (10186977): [] _raw_spin_lock_irqsave+0xd/0x50 <4>[ 416.209047] softirqs last enabled at (10186968): [] irq_enter_rcu+0x6a/0x70 <4>[ 416.209049] softirqs last disabled at (10186969): [] asm_call_on_stack+0xf/0x20 <4>[ 416.209317] list_del corruption, ffff8882781bb870->next is LIST_POISON1 (dead000000000100) <4>[ 416.209317] WARNING: CPU: 7 PID: 46 at lib/list_debug.c:47 __list_del_entry_valid+0x4e/0x90 <4>[ 416.209317] Modules linked in: i915(+) vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio mei_hdcp x86_pkg_temp_thermal coretemp ax88179_178a usbnet mii crct10dif_pclmul snd_intel_dspcfg crc32_pclmul snd_hda_codec snd_hwdep ghash_clmulni_intel snd_hda_core e1000e snd_pcm ptp pps_core mei_me mei prime_numbers intel_lpss_pci [last unloaded: i915] <4>[ 416.209317] CPU: 7 PID: 46 Comm: ksoftirqd/7 Tainted: G U W 5.8.0-CI-CI_DRM_8852+ #1 <4>[ 416.209317] Hardware name: Intel Corporation Ice Lake Client Platform/IceLake Y LPDDR4x T4 RVP TLC, BIOS ICLSFWR1.R00.3212.A00.1905212112 05/21/2019 <4>[ 416.209317] RIP: 0010:__list_del_entry_valid+0x4e/0x90 <4>[ 416.209317] Code: 2e 48 8b 32 48 39 fe 75 3a 48 8b 50 08 48 39 f2 75 48 b8 01 00 00 00 c3 48 89 fe 48 89 c2 48 c7 c7 38 19 33 82 e8 62 e0 b6 ff <0f> 0b 31 c0 c3 48 89 fe 48 c7 c7 70 19 33 82 e8 4e e0 b6 ff 0f 0b <4>[ 416.209317] RSP: 0018:ffffc90000280de8 EFLAGS: 00010086 <4>[ 416.209317] RAX: 0000000000000000 RBX: ffff8882781bb848 RCX: 0000000000010104 <4>[ 416.209317] RDX: 0000000000010104 RSI: ffffffff8238b4ee RDI: 00000000ffffffff <4>[ 416.209317] RBP: ffff8882781bb880 R08: 0000000000000000 R09: 0000000000000001 <4>[ 416.209317] R10: 000000009fb6666e R11: 00000000feca9427 R12: ffffc90000280e18 <4>[ 416.209317] R13: ffff8881951d5930 R14: dead0000000000d8 R15: ffff8882781bb880 <4>[ 416.209317] FS: 0000000000000000(0000) GS:ffff88829c180000(0000) knlGS:0000000000000000 <4>[ 416.209317] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4>[ 416.209317] CR2: 0000556231326c48 CR3: 0000000005610001 CR4: 0000000000760ee0 <4>[ 416.209317] PKRU: 55555554 <4>[ 416.209317] Call Trace: <4>[ 416.209317] <4>[ 416.209317] remove_signaling_context.isra.13+0xd/0x70 [i915] <4>[ 416.209513] signal_irq_work+0x1f7/0x4b0 [i915] This is caused by virtual engines where although we take the breadcrumb lock on each of the active engines, they may be different engines on different requests, It turns out that the b->irq_lock was not a sufficient proxy for the engine->active.lock in the case of more than one request, so introduce an explicit lock around ce->signals. v2: ce->signal_lock is acquired with only RCU protection and so must be treated carefully and not cleared during reallocation. We also then need to confirm that the ce we lock is the same as we found in the breadcrumb list. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2276 Fixes: c18636f76344 ("drm/i915: Remove requirement for holding i915_request.lock for breadcrumbs") Fixes: 2854d866327a ("drm/i915/gt: Replace intel_engine_transfer_stale_breadcrumbs") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201126140407.31952-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 168 ++++++++---------- .../gpu/drm/i915/gt/intel_breadcrumbs_types.h | 6 +- drivers/gpu/drm/i915/gt/intel_context.c | 3 +- drivers/gpu/drm/i915/gt/intel_context_types.h | 12 +- drivers/gpu/drm/i915/i915_request.h | 6 +- 5 files changed, 90 insertions(+), 105 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index cf6e05ea4d8f..a24cc1ff08a0 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -101,18 +101,37 @@ static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) intel_gt_pm_put_async(b->irq_engine->gt); } +static void intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b) +{ + spin_lock(&b->irq_lock); + if (b->irq_armed) + __intel_breadcrumbs_disarm_irq(b); + spin_unlock(&b->irq_lock); +} + static void add_signaling_context(struct intel_breadcrumbs *b, struct intel_context *ce) { - intel_context_get(ce); - list_add_tail(&ce->signal_link, &b->signalers); + lockdep_assert_held(&ce->signal_lock); + + spin_lock(&b->signalers_lock); + list_add_rcu(&ce->signal_link, &b->signalers); + spin_unlock(&b->signalers_lock); } -static void remove_signaling_context(struct intel_breadcrumbs *b, +static bool remove_signaling_context(struct intel_breadcrumbs *b, struct intel_context *ce) { - list_del(&ce->signal_link); - intel_context_put(ce); + lockdep_assert_held(&ce->signal_lock); + + if (!list_empty(&ce->signals)) + return false; + + spin_lock(&b->signalers_lock); + list_del_rcu(&ce->signal_link); + spin_unlock(&b->signalers_lock); + + return true; } static inline bool __request_completed(const struct i915_request *rq) @@ -175,6 +194,8 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl) static bool __signal_request(struct i915_request *rq) { + GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)); + if (!__dma_fence_signal(&rq->fence)) { i915_request_put(rq); return false; @@ -195,15 +216,12 @@ static void signal_irq_work(struct irq_work *work) struct intel_breadcrumbs *b = container_of(work, typeof(*b), irq_work); const ktime_t timestamp = ktime_get(); struct llist_node *signal, *sn; - struct intel_context *ce, *cn; - struct list_head *pos, *next; + struct intel_context *ce; signal = NULL; if (unlikely(!llist_empty(&b->signaled_requests))) signal = llist_del_all(&b->signaled_requests); - spin_lock(&b->irq_lock); - /* * Keep the irq armed until the interrupt after all listeners are gone. * @@ -229,47 +247,44 @@ static void signal_irq_work(struct irq_work *work) * interrupt draw less ire from other users of the system and tools * like powertop. */ - if (!signal && b->irq_armed && list_empty(&b->signalers)) - __intel_breadcrumbs_disarm_irq(b); + if (!signal && READ_ONCE(b->irq_armed) && list_empty(&b->signalers)) + intel_breadcrumbs_disarm_irq(b); - list_for_each_entry_safe(ce, cn, &b->signalers, signal_link) { - GEM_BUG_ON(list_empty(&ce->signals)); + rcu_read_lock(); + list_for_each_entry_rcu(ce, &b->signalers, signal_link) { + struct i915_request *rq; - list_for_each_safe(pos, next, &ce->signals) { - struct i915_request *rq = - list_entry(pos, typeof(*rq), signal_link); + list_for_each_entry_rcu(rq, &ce->signals, signal_link) { + bool release; - GEM_BUG_ON(!check_signal_order(ce, rq)); if (!__request_completed(rq)) break; + if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, + &rq->fence.flags)) + break; + /* * Queue for execution after dropping the signaling * spinlock as the callback chain may end up adding * more signalers to the same context or engine. */ - clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); + spin_lock(&ce->signal_lock); + list_del_rcu(&rq->signal_link); + release = remove_signaling_context(b, ce); + spin_unlock(&ce->signal_lock); + if (__signal_request(rq)) /* We own signal_node now, xfer to local list */ signal = slist_add(&rq->signal_node, signal); - } - /* - * We process the list deletion in bulk, only using a list_add - * (not list_move) above but keeping the status of - * rq->signal_link known with the I915_FENCE_FLAG_SIGNAL bit. - */ - if (!list_is_first(pos, &ce->signals)) { - /* Advance the list to the first incomplete request */ - __list_del_many(&ce->signals, pos); - if (&ce->signals == pos) { /* now empty */ + if (release) { add_retire(b, ce->timeline); - remove_signaling_context(b, ce); + intel_context_put(ce); } } } - - spin_unlock(&b->irq_lock); + rcu_read_unlock(); llist_for_each_safe(signal, sn, signal) { struct i915_request *rq = @@ -298,14 +313,15 @@ intel_breadcrumbs_create(struct intel_engine_cs *irq_engine) if (!b) return NULL; - spin_lock_init(&b->irq_lock); + b->irq_engine = irq_engine; + + spin_lock_init(&b->signalers_lock); INIT_LIST_HEAD(&b->signalers); init_llist_head(&b->signaled_requests); + spin_lock_init(&b->irq_lock); init_irq_work(&b->irq_work, signal_irq_work); - b->irq_engine = irq_engine; - return b; } @@ -347,9 +363,9 @@ void intel_breadcrumbs_free(struct intel_breadcrumbs *b) kfree(b); } -static void insert_breadcrumb(struct i915_request *rq, - struct intel_breadcrumbs *b) +static void insert_breadcrumb(struct i915_request *rq) { + struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs; struct intel_context *ce = rq->context; struct list_head *pos; @@ -371,6 +387,7 @@ static void insert_breadcrumb(struct i915_request *rq, } if (list_empty(&ce->signals)) { + intel_context_get(ce); add_signaling_context(b, ce); pos = &ce->signals; } else { @@ -396,8 +413,9 @@ static void insert_breadcrumb(struct i915_request *rq, break; } } - list_add(&rq->signal_link, pos); + list_add_rcu(&rq->signal_link, pos); GEM_BUG_ON(!check_signal_order(ce, rq)); + GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)); set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); /* @@ -410,7 +428,7 @@ static void insert_breadcrumb(struct i915_request *rq, bool i915_request_enable_breadcrumb(struct i915_request *rq) { - struct intel_breadcrumbs *b; + struct intel_context *ce = rq->context; /* Serialises with i915_request_retire() using rq->lock */ if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)) @@ -425,67 +443,30 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq) if (!test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) return true; - /* - * rq->engine is locked by rq->engine->active.lock. That however - * is not known until after rq->engine has been dereferenced and - * the lock acquired. Hence we acquire the lock and then validate - * that rq->engine still matches the lock we hold for it. - * - * Here, we are using the breadcrumb lock as a proxy for the - * rq->engine->active.lock, and we know that since the breadcrumb - * will be serialised within i915_request_submit/i915_request_unsubmit, - * the engine cannot change while active as long as we hold the - * breadcrumb lock on that engine. - * - * From the dma_fence_enable_signaling() path, we are outside of the - * request submit/unsubmit path, and so we must be more careful to - * acquire the right lock. - */ - b = READ_ONCE(rq->engine)->breadcrumbs; - spin_lock(&b->irq_lock); - while (unlikely(b != READ_ONCE(rq->engine)->breadcrumbs)) { - spin_unlock(&b->irq_lock); - b = READ_ONCE(rq->engine)->breadcrumbs; - spin_lock(&b->irq_lock); - } - - /* - * Now that we are finally serialised with request submit/unsubmit, - * [with b->irq_lock] and with i915_request_retire() [via checking - * SIGNALED with rq->lock] confirm the request is indeed active. If - * it is no longer active, the breadcrumb will be attached upon - * i915_request_submit(). - */ + spin_lock(&ce->signal_lock); if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) - insert_breadcrumb(rq, b); - - spin_unlock(&b->irq_lock); + insert_breadcrumb(rq); + spin_unlock(&ce->signal_lock); return true; } void i915_request_cancel_breadcrumb(struct i915_request *rq) { - struct intel_breadcrumbs *b = rq->engine->breadcrumbs; + struct intel_context *ce = rq->context; + bool release; - /* - * We must wait for b->irq_lock so that we know the interrupt handler - * has released its reference to the intel_context and has completed - * the DMA_FENCE_FLAG_SIGNALED_BIT/I915_FENCE_FLAG_SIGNAL dance (if - * required). - */ - spin_lock(&b->irq_lock); - if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) { - struct intel_context *ce = rq->context; + if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) + return; - list_del(&rq->signal_link); - if (list_empty(&ce->signals)) - remove_signaling_context(b, ce); + spin_lock(&ce->signal_lock); + list_del_rcu(&rq->signal_link); + release = remove_signaling_context(rq->engine->breadcrumbs, ce); + spin_unlock(&ce->signal_lock); + if (release) + intel_context_put(ce); - clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags); - i915_request_put(rq); - } - spin_unlock(&b->irq_lock); + i915_request_put(rq); } static void print_signals(struct intel_breadcrumbs *b, struct drm_printer *p) @@ -495,18 +476,17 @@ static void print_signals(struct intel_breadcrumbs *b, struct drm_printer *p) drm_printf(p, "Signals:\n"); - spin_lock_irq(&b->irq_lock); - list_for_each_entry(ce, &b->signalers, signal_link) { - list_for_each_entry(rq, &ce->signals, signal_link) { + rcu_read_lock(); + list_for_each_entry_rcu(ce, &b->signalers, signal_link) { + list_for_each_entry_rcu(rq, &ce->signals, signal_link) drm_printf(p, "\t[%llx:%llx%s] @ %dms\n", rq->fence.context, rq->fence.seqno, i915_request_completed(rq) ? "!" : i915_request_started(rq) ? "*" : "", jiffies_to_msecs(jiffies - rq->emitted_jiffies)); - } } - spin_unlock_irq(&b->irq_lock); + rcu_read_unlock(); } void intel_engine_print_breadcrumbs(struct intel_engine_cs *engine, diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h index 3fa19820b37a..a74bb3062bd8 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h @@ -29,18 +29,16 @@ * the overhead of waking that client is much preferred. */ struct intel_breadcrumbs { - spinlock_t irq_lock; /* protects the lists used in hardirq context */ - /* Not all breadcrumbs are attached to physical HW */ struct intel_engine_cs *irq_engine; + spinlock_t signalers_lock; /* protects the list of signalers */ struct list_head signalers; struct llist_head signaled_requests; + spinlock_t irq_lock; /* protects the interrupt from hardirq context */ struct irq_work irq_work; /* for use from inside irq_lock */ - unsigned int irq_enabled; - bool irq_armed; }; diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index d3a835212167..349e7fa1488d 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -379,7 +379,8 @@ intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine) ce->vm = i915_vm_get(engine->gt->vm); - INIT_LIST_HEAD(&ce->signal_link); + /* NB ce->signal_link/lock is used under RCU */ + spin_lock_init(&ce->signal_lock); INIT_LIST_HEAD(&ce->signals); mutex_init(&ce->pin_mutex); diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 20cb5835d1c3..52fa9c132746 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -25,6 +25,7 @@ DECLARE_EWMA(runtime, 3, 8); struct i915_gem_context; struct i915_gem_ww_ctx; struct i915_vma; +struct intel_breadcrumbs; struct intel_context; struct intel_ring; @@ -63,8 +64,15 @@ struct intel_context { struct i915_address_space *vm; struct i915_gem_context __rcu *gem_context; - struct list_head signal_link; - struct list_head signals; + /* + * @signal_lock protects the list of requests that need signaling, + * @signals. While there are any requests that need signaling, + * we add the context to the breadcrumbs worker, and remove it + * upon completion/cancellation of the last request. + */ + struct list_head signal_link; /* Accessed under RCU */ + struct list_head signals; /* Guarded by signal_lock */ + spinlock_t signal_lock; /* protects signals, the list of requests */ struct i915_vma *state; struct intel_ring *ring; diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index b222f7b46e9c..92e4320c50c4 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -178,10 +178,8 @@ struct i915_request { struct intel_ring *ring; struct intel_timeline __rcu *timeline; - union { - struct list_head signal_link; - struct llist_node signal_node; - }; + struct list_head signal_link; + struct llist_node signal_node; /* * The rcu epoch of when this request was allocated. Used to judiciously From 85cc2917a3965a3a747a6407d6e3028cfeb1534e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 26 Nov 2020 14:04:07 +0000 Subject: [PATCH 0041/5577] drm/i915/gt: Move the breadcrumb to the signaler if completed upon cancel If while we are cancelling the breadcrumb signaling, we find that the request is already completed, move it to the irq signaler and let it be signaled. v2: Tweak reference counting so that we only acquire a new reference on adding to a signal list, as opposed to a hidden i915_request_put of the caller's reference. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201126140407.31952-5-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 41 +++++++++++---------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index a24cc1ff08a0..00918300f53f 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -192,18 +192,6 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl) intel_engine_add_retire(b->irq_engine, tl); } -static bool __signal_request(struct i915_request *rq) -{ - GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)); - - if (!__dma_fence_signal(&rq->fence)) { - i915_request_put(rq); - return false; - } - - return true; -} - static struct llist_node * slist_add(struct llist_node *node, struct llist_node *head) { @@ -274,9 +262,11 @@ static void signal_irq_work(struct irq_work *work) release = remove_signaling_context(b, ce); spin_unlock(&ce->signal_lock); - if (__signal_request(rq)) + if (__dma_fence_signal(&rq->fence)) /* We own signal_node now, xfer to local list */ signal = slist_add(&rq->signal_node, signal); + else + i915_request_put(rq); if (release) { add_retire(b, ce->timeline); @@ -363,6 +353,17 @@ void intel_breadcrumbs_free(struct intel_breadcrumbs *b) kfree(b); } +static void irq_signal_request(struct i915_request *rq, + struct intel_breadcrumbs *b) +{ + if (!__dma_fence_signal(&rq->fence)) + return; + + i915_request_get(rq); + if (llist_add(&rq->signal_node, &b->signaled_requests)) + irq_work_queue(&b->irq_work); +} + static void insert_breadcrumb(struct i915_request *rq) { struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs; @@ -372,17 +373,13 @@ static void insert_breadcrumb(struct i915_request *rq) if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) return; - i915_request_get(rq); - /* * If the request is already completed, we can transfer it * straight onto a signaled list, and queue the irq worker for * its signal completion. */ if (__request_completed(rq)) { - if (__signal_request(rq) && - llist_add(&rq->signal_node, &b->signaled_requests)) - irq_work_queue(&b->irq_work); + irq_signal_request(rq, b); return; } @@ -413,6 +410,8 @@ static void insert_breadcrumb(struct i915_request *rq) break; } } + + i915_request_get(rq); list_add_rcu(&rq->signal_link, pos); GEM_BUG_ON(!check_signal_order(ce, rq)); GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)); @@ -453,6 +452,7 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq) void i915_request_cancel_breadcrumb(struct i915_request *rq) { + struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs; struct intel_context *ce = rq->context; bool release; @@ -461,11 +461,14 @@ void i915_request_cancel_breadcrumb(struct i915_request *rq) spin_lock(&ce->signal_lock); list_del_rcu(&rq->signal_link); - release = remove_signaling_context(rq->engine->breadcrumbs, ce); + release = remove_signaling_context(b, ce); spin_unlock(&ce->signal_lock); if (release) intel_context_put(ce); + if (__request_completed(rq)) + irq_signal_request(rq, b); + i915_request_put(rq); } From 9afdda82ee7f69b25cb5e6968e2d3d63e2313d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 25 Nov 2020 15:32:23 +0100 Subject: [PATCH 0042/5577] drm/radeon: fix check order in radeon_bo_move MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reorder the code to fix checking if blitting is available. Signed-off-by: Christian König Fixes: 28a68f828266 ("drm/radeon/ttm: use multihop") Reviewed-by: Daniel Vetter Reviewed-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/403847/ --- drivers/gpu/drm/radeon/radeon_ttm.c | 60 +++++++++++++---------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 0ca381b95d3d..2b598141225f 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -216,27 +216,15 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *old_mem = &bo->mem; int r; - if ((old_mem->mem_type == TTM_PL_SYSTEM && - new_mem->mem_type == TTM_PL_VRAM) || - (old_mem->mem_type == TTM_PL_VRAM && - new_mem->mem_type == TTM_PL_SYSTEM)) { - hop->fpfn = 0; - hop->lpfn = 0; - hop->mem_type = TTM_PL_TT; - hop->flags = 0; - return -EMULTIHOP; - } - if (new_mem->mem_type == TTM_PL_TT) { r = radeon_ttm_tt_bind(bo->bdev, bo->ttm, new_mem); if (r) return r; } - radeon_bo_move_notify(bo, evict, new_mem); r = ttm_bo_wait_ctx(bo, ctx); if (r) - goto fail; + return r; /* Can't move a pinned BO */ rbo = container_of(bo, struct radeon_bo, tbo); @@ -246,12 +234,12 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, rdev = radeon_get_rdev(bo->bdev); if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { ttm_bo_move_null(bo, new_mem); - return 0; + goto out; } if (old_mem->mem_type == TTM_PL_SYSTEM && new_mem->mem_type == TTM_PL_TT) { ttm_bo_move_null(bo, new_mem); - return 0; + goto out; } if (old_mem->mem_type == TTM_PL_TT && @@ -259,31 +247,37 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, radeon_ttm_tt_unbind(bo->bdev, bo->ttm); ttm_resource_free(bo, &bo->mem); ttm_bo_assign_mem(bo, new_mem); - return 0; + goto out; } - if (!rdev->ring[radeon_copy_ring_index(rdev)].ready || - rdev->asic->copy.copy == NULL) { - /* use memcpy */ - goto memcpy; - } - - r = radeon_move_blit(bo, evict, new_mem, old_mem); - if (r) { -memcpy: - r = ttm_bo_move_memcpy(bo, ctx, new_mem); - if (r) { - goto fail; + if (rdev->ring[radeon_copy_ring_index(rdev)].ready && + rdev->asic->copy.copy != NULL) { + if ((old_mem->mem_type == TTM_PL_SYSTEM && + new_mem->mem_type == TTM_PL_VRAM) || + (old_mem->mem_type == TTM_PL_VRAM && + new_mem->mem_type == TTM_PL_SYSTEM)) { + hop->fpfn = 0; + hop->lpfn = 0; + hop->mem_type = TTM_PL_TT; + hop->flags = 0; + return -EMULTIHOP; } + + r = radeon_move_blit(bo, evict, new_mem, old_mem); + } else { + r = -ENODEV; } + if (r) { + r = ttm_bo_move_memcpy(bo, ctx, new_mem); + if (r) + return r; + } + +out: /* update statistics */ atomic64_add((u64)bo->num_pages << PAGE_SHIFT, &rdev->num_bytes_moved); + radeon_bo_move_notify(bo, evict, new_mem); return 0; -fail: - swap(*new_mem, bo->mem); - radeon_bo_move_notify(bo, false, new_mem); - swap(*new_mem, bo->mem); - return r; } static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_resource *mem) From 444fbf5d7058099447c5366ba8bb60d610aeb44b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 27 Nov 2020 10:25:40 +0000 Subject: [PATCH 0043/5577] drm/i915/gt: Declare gen9 has 64 mocs entries! We checked the table size against a hardcoded number of entries, and that number was excluding the special mocs registers at the end. Fixes: 977933b5da7c ("drm/i915/gt: Program mocs:63 for cache eviction on gen9") Signed-off-by: Chris Wilson Cc: # v4.3+ Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201127102540.13117-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_mocs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c index b8d0c32ae9dd..ab6870242e18 100644 --- a/drivers/gpu/drm/i915/gt/intel_mocs.c +++ b/drivers/gpu/drm/i915/gt/intel_mocs.c @@ -59,8 +59,7 @@ struct drm_i915_mocs_table { #define _L3_CACHEABILITY(value) ((value) << 4) /* Helper defines */ -#define GEN9_NUM_MOCS_ENTRIES 62 /* 62 out of 64 - 63 & 64 are reserved. */ -#define GEN11_NUM_MOCS_ENTRIES 64 /* 63-64 are reserved, but configured. */ +#define GEN9_NUM_MOCS_ENTRIES 64 /* 63-64 are reserved, but configured. */ /* (e)LLC caching options */ /* @@ -361,15 +360,15 @@ static unsigned int get_mocs_settings(const struct drm_i915_private *i915, if (IS_DG1(i915)) { table->size = ARRAY_SIZE(dg1_mocs_table); table->table = dg1_mocs_table; - table->n_entries = GEN11_NUM_MOCS_ENTRIES; + table->n_entries = GEN9_NUM_MOCS_ENTRIES; } else if (INTEL_GEN(i915) >= 12) { table->size = ARRAY_SIZE(tgl_mocs_table); table->table = tgl_mocs_table; - table->n_entries = GEN11_NUM_MOCS_ENTRIES; + table->n_entries = GEN9_NUM_MOCS_ENTRIES; } else if (IS_GEN(i915, 11)) { table->size = ARRAY_SIZE(icl_mocs_table); table->table = icl_mocs_table; - table->n_entries = GEN11_NUM_MOCS_ENTRIES; + table->n_entries = GEN9_NUM_MOCS_ENTRIES; } else if (IS_GEN9_BC(i915) || IS_CANNONLAKE(i915)) { table->size = ARRAY_SIZE(skl_mocs_table); table->n_entries = GEN9_NUM_MOCS_ENTRIES; From 584e599bd090fbb0dac4b3bf2ab823d7f2ae3dd4 Mon Sep 17 00:00:00 2001 From: Bernard Zhao Date: Wed, 18 Nov 2020 23:29:55 -0800 Subject: [PATCH 0044/5577] via/via_irq: use __func__ to replace string function name This change also fix checkpatch.pl warning: WARNING: Prefer using '"%s...", __func__' to using 'via_driver_irq_postinstall', this function's name, in a string + DRM_DEBUG("via_driver_irq_postinstall\n"); Signed-off-by: Bernard Zhao Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201119072957.108941-1-bernard@vivo.com --- drivers/gpu/drm/via/via_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index a3e0fb5b8671..faeae5d881fb 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c @@ -308,7 +308,7 @@ int via_driver_irq_postinstall(struct drm_device *dev) drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; - DRM_DEBUG("via_driver_irq_postinstall\n"); + DRM_DEBUG("fun: %s\n", __func__); if (!dev_priv) return -EINVAL; From c6c90c70db4d9a0989111d6b994d545659410f7a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 26 Nov 2020 19:17:52 -0800 Subject: [PATCH 0045/5577] fbdev: aty: SPARC64 requires FB_ATY_CT It looks like SPARC64 requires FB_ATY_CT to build without errors, so have FB_ATY select FB_ATY_CT if both SPARC64 and PCI are enabled instead of using "default y if SPARC64 && PCI", which is not strong enough to prevent build errors. As it currently is, FB_ATY_CT can be disabled, resulting in build errors: ERROR: modpost: "aty_postdividers" [drivers/video/fbdev/aty/atyfb.ko] undefined! ERROR: modpost: "aty_ld_pll_ct" [drivers/video/fbdev/aty/atyfb.ko] undefined! Reviewed-by: Geert Uytterhoeven Fixes: f7018c213502 ("video: move fbdev to drivers/video/fbdev") Signed-off-by: Randy Dunlap Cc: "David S. Miller" Cc: sparclinux@vger.kernel.org Cc: Tomi Valkeinen Cc: dri-devel@lists.freedesktop.org Cc: linux-fbdev@vger.kernel.org Cc: Daniel Vetter Cc: David Airlie Cc: Bartlomiej Zolnierkiewicz Cc: Geert Uytterhoeven Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201127031752.10371-1-rdunlap@infradead.org --- drivers/video/fbdev/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index cfb7f5612ef0..4f02db65dede 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1269,6 +1269,7 @@ config FB_ATY select FB_CFB_IMAGEBLIT select FB_BACKLIGHT if FB_ATY_BACKLIGHT select FB_MACMODES if PPC + select FB_ATY_CT if SPARC64 && PCI help This driver supports graphics boards with the ATI Mach64 chips. Say Y if you have such a graphics board. @@ -1279,7 +1280,6 @@ config FB_ATY config FB_ATY_CT bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" depends on PCI && FB_ATY - default y if SPARC64 && PCI help Say Y here to support use of ATI's 64-bit Rage boards (or other boards based on the Mach64 CT, VT, GT, and LT chipsets) as a From 57fcd550eb15bce14a7154736379dfd4ed60ae81 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 28 Oct 2020 12:31:20 +0100 Subject: [PATCH 0046/5577] drm/ttm: Warn on pinning without holding a reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not technically a problem for ttm, but very likely a driver bug and pretty big time confusing for reviewing code. So warn about it, both at cleanup time (so we catch these for sure) and at pin/unpin time (so we know who's the culprit). Reviewed-by: Huang Rui Reviewed-by: Christian König Signed-off-by: Daniel Vetter Cc: Christian Koenig Cc: Huang Rui Link: https://patchwork.freedesktop.org/patch/msgid/20201028113120.3641237-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/ttm/ttm_bo.c | 2 +- include/drm/ttm/ttm_bo_api.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 9a03c7834b1e..fc6b619c0329 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -514,7 +514,7 @@ static void ttm_bo_release(struct kref *kref) * shrinkers, now that they are queued for * destruction. */ - if (bo->pin_count) { + if (WARN_ON(bo->pin_count)) { bo->pin_count = 0; ttm_bo_del_from_lru(bo); ttm_bo_add_mem_to_lru(bo, &bo->mem); diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 2564e66e67d7..79b9367e0ffd 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -600,6 +600,7 @@ static inline bool ttm_bo_uses_embedded_gem_object(struct ttm_buffer_object *bo) static inline void ttm_bo_pin(struct ttm_buffer_object *bo) { dma_resv_assert_held(bo->base.resv); + WARN_ON_ONCE(!kref_read(&bo->kref)); ++bo->pin_count; } @@ -613,6 +614,7 @@ static inline void ttm_bo_unpin(struct ttm_buffer_object *bo) { dma_resv_assert_held(bo->base.resv); WARN_ON_ONCE(!bo->pin_count); + WARN_ON_ONCE(!kref_read(&bo->kref)); --bo->pin_count; } From e5346a1ff38a405c14ce8e595269e9b7dcfbb2e9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 27 Nov 2020 14:57:48 +0000 Subject: [PATCH 0047/5577] Revert "drm/i915: re-order if/else ladder for hpd_irq_setup" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now use ilk_hpd_irq_setup for all GMCH platforms that do not have hotplug. These are early gen3 and gen2 devices that now explode on boot as they try to access non-existent registers. Fixes: 794d61a19090 ("drm/i915: re-order if/else ladder for hpd_irq_setup") Signed-off-by: Chris Wilson Cc: Lucas De Marchi Cc: José Roberto de Souza Cc: Jani Nikula Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201127145748.29491-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index dc6febc63f1c..c80eeac53952 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4242,18 +4242,21 @@ void intel_irq_init(struct drm_i915_private *dev_priv) */ dev_priv->hotplug.hpd_short_storm_enabled = !HAS_DP_MST(dev_priv); - if (HAS_PCH_DG1(dev_priv)) - dev_priv->display.hpd_irq_setup = dg1_hpd_irq_setup; - else if (INTEL_GEN(dev_priv) >= 11) - dev_priv->display.hpd_irq_setup = gen11_hpd_irq_setup; - else if (IS_GEN9_LP(dev_priv)) - dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) - dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup; - else if (HAS_GMCH(dev_priv) && I915_HAS_HOTPLUG(dev_priv)) - dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; - else - dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; + if (HAS_GMCH(dev_priv)) { + if (I915_HAS_HOTPLUG(dev_priv)) + dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; + } else { + if (HAS_PCH_DG1(dev_priv)) + dev_priv->display.hpd_irq_setup = dg1_hpd_irq_setup; + else if (INTEL_GEN(dev_priv) >= 11) + dev_priv->display.hpd_irq_setup = gen11_hpd_irq_setup; + else if (IS_GEN9_LP(dev_priv)) + dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; + else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) + dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup; + else + dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; + } } /** From c33f83fd481a0441e2f14cb03226197110d57a99 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Fri, 27 Nov 2020 08:28:28 -0800 Subject: [PATCH 0048/5577] drm/i915: remove trailing semicolon in macro definition The macro use will already have a semicolon. Signed-off-by: Tom Rix Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201127162828.2660230-1-trix@redhat.com --- drivers/gpu/drm/i915/intel_device_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index e67cec8fa2aa..ef767f04c37c 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -104,7 +104,7 @@ void intel_device_info_print_static(const struct intel_device_info *info, drm_printf(p, "ppgtt-type: %d\n", info->ppgtt_type); drm_printf(p, "dma_mask_size: %u\n", info->dma_mask_size); -#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->name)); +#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->name)) DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG); #undef PRINT_FLAG From a9d71f76ccfd309f3bd5f7c9b60e91a4decae792 Mon Sep 17 00:00:00 2001 From: Venkata Ramana Nayana Date: Fri, 27 Nov 2020 12:07:16 +0000 Subject: [PATCH 0049/5577] drm/i915/gt: Retain default context state across shrinking As we use a shmemfs file to hold the context state, when not in use it may be swapped out, such as across suspend. Since we wrote into the shmemfs without marking the pages as dirty, the contents may be dropped instead of being written back to swap. On re-using the shmemfs file, such as creating a new context after resume, the contents of that file were likely garbage and so the new context could then hang the GPU. Simply mark the page as being written when copying into the shmemfs file, and it the new contents will be retained across swapout. Fixes: be1cb55a07bf ("drm/i915/gt: Keep a no-frills swappable copy of the default context state") Cc: Sudeep Dutt Cc: Matthew Auld Cc: Tvrtko Ursulin Cc: Ramalingam C Signed-off-by: CQ Tang Signed-off-by: Venkata Ramana Nayana Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Cc: # v5.8+ Link: https://patchwork.freedesktop.org/patch/msgid/20201127120718.454037-161-matthew.auld@intel.com --- drivers/gpu/drm/i915/gt/shmem_utils.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c index f011ea42487e..463af675fadd 100644 --- a/drivers/gpu/drm/i915/gt/shmem_utils.c +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c @@ -103,10 +103,13 @@ static int __shmem_rw(struct file *file, loff_t off, return PTR_ERR(page); vaddr = kmap(page); - if (write) + if (write) { memcpy(vaddr + offset_in_page(off), ptr, this); - else + set_page_dirty(page); + } else { memcpy(ptr, vaddr + offset_in_page(off), this); + } + mark_page_accessed(page); kunmap(page); put_page(page); From 5cc2b61fb251d06f732b14b04f8f6510f3b31365 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 27 Nov 2020 21:00:59 +0000 Subject: [PATCH 0050/5577] drm/i915/display: Suppress "Combo PHY A HW state changed unexpectedly" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We know a problem exists in the ifwi shipped with the early pre-production Tigerlake and DG1 prototypes, later revisions are fine. However, CI still relies on the earlier ifwi and we grow tired of the volume of warnings as we wait for replacements. Since the warning is a bug, we do not want to lose the warning in its entirety, so only suppress the warning for the platforms currently exhibiting the issue. Suggested-by: José Roberto de Souza Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2411 Signed-off-by: Chris Wilson Cc: José Roberto de Souza Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20201127210059.10702-1-chris@chris-wilson.co.uk --- .../gpu/drm/i915/display/intel_combo_phy.c | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c index d5ad61e4083e..996ae0608a62 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy.c +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c @@ -427,10 +427,22 @@ static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv) u32 val; if (phy == PHY_A && - !icl_combo_phy_verify_state(dev_priv, phy)) - drm_warn(&dev_priv->drm, - "Combo PHY %c HW state changed unexpectedly\n", - phy_name(phy)); + !icl_combo_phy_verify_state(dev_priv, phy)) { + if (IS_TIGERLAKE(dev_priv) || IS_DG1(dev_priv)) { + /* + * A known problem with old ifwi: + * https://gitlab.freedesktop.org/drm/intel/-/issues/2411 + * Suppress the warning for CI. Remove ASAP! + */ + drm_dbg_kms(&dev_priv->drm, + "Combo PHY %c HW state changed unexpectedly\n", + phy_name(phy)); + } else { + drm_warn(&dev_priv->drm, + "Combo PHY %c HW state changed unexpectedly\n", + phy_name(phy)); + } + } if (!has_phy_misc(dev_priv, phy)) goto skip_phy_misc; From d6bff5b0bddbf294e2db80f2cccdac7be6d0a4d1 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 28 Nov 2020 17:16:06 +0000 Subject: [PATCH 0051/5577] drm/ingenic: Add basic PM support Call drm_mode_config_helper_suspend() and drm_mode_config_helper_resume() on suspend and resume, respectively. This makes sure that the display stack is properly disabled when the hardware is put to sleep. Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201128171606.132830-1-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 368bfef8b340..286e08b8ace2 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -1167,6 +1168,22 @@ static int ingenic_drm_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused ingenic_drm_suspend(struct device *dev) +{ + struct ingenic_drm *priv = dev_get_drvdata(dev); + + return drm_mode_config_helper_suspend(&priv->drm); +} + +static int __maybe_unused ingenic_drm_resume(struct device *dev) +{ + struct ingenic_drm *priv = dev_get_drvdata(dev); + + return drm_mode_config_helper_resume(&priv->drm); +} + +static SIMPLE_DEV_PM_OPS(ingenic_drm_pm_ops, ingenic_drm_suspend, ingenic_drm_resume); + static const u32 jz4740_formats[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, @@ -1246,6 +1263,7 @@ MODULE_DEVICE_TABLE(of, ingenic_drm_of_match); static struct platform_driver ingenic_drm_driver = { .driver = { .name = "ingenic-drm", + .pm = pm_ptr(&ingenic_drm_pm_ops), .of_match_table = of_match_ptr(ingenic_drm_of_match), }, .probe = ingenic_drm_probe, From 8d989f4448947c866b47cb6789b88b31d5f79fe3 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 4 Nov 2020 20:33:39 +0530 Subject: [PATCH 0052/5577] drm/i915/perf: replace idr_init() by idr_init_base() idr_init() uses base 0 which is an invalid identifier. The new function idr_init_base allows IDR to set the ID lookup from base 1. This avoids all lookups that otherwise starts from 0 since 0 is always unused. References: commit 6ce711f27500 ("idr: Make 1-based IDRs more efficient") Signed-off-by: Deepak R Varma Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201104150339.GA68663@localhost --- drivers/gpu/drm/i915/i915_perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index e94976976571..2d033255b7cf 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -4367,7 +4367,7 @@ void i915_perf_init(struct drm_i915_private *i915) RUNTIME_INFO(i915)->cs_timestamp_frequency_hz / 2; mutex_init(&perf->metrics_lock); - idr_init(&perf->metrics_idr); + idr_init_base(&perf->metrics_idr, 1); /* We set up some ratelimit state to potentially throttle any * _NOTES about spurious, invalid OA reports which we don't From 6762b50d7daa2dbf2a3e54e433b55705462af3a6 Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Sat, 24 Oct 2020 14:53:21 +1100 Subject: [PATCH 0053/5577] drm/rockchip: dw_hdmi: fix incorrect clock in vpll clock error message Error message incorrectly refers to grf clock instead of vpll clock. Signed-off-by: Jonathan Liu Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20201024035321.4898-1-net147@gmail.com --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 23de359a1dec..830bdd5e9b7c 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -202,7 +202,7 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) { return -EPROBE_DEFER; } else if (IS_ERR(hdmi->vpll_clk)) { - DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n"); + DRM_DEV_ERROR(hdmi->dev, "failed to get vpll clock\n"); return PTR_ERR(hdmi->vpll_clk); } From f8c8c7d86da8fbdae0e45e679d387a0744bb5065 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Mon, 16 Nov 2020 15:16:09 +0100 Subject: [PATCH 0054/5577] drm/rockchip: for error print, use the correct device pointer There is a use of DRM_DEV_ERROR(dsi->dev,..) which should be replaced with DRM_DEV_ERROR(dev, ..) since dsi->dev is set later Signed-off-by: Dafna Hirschfeld Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20201116141609.26719-2-dafna.hirschfeld@collabora.com --- drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index e84325e56d98..24a71091759c 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -1089,7 +1089,7 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); if (IS_ERR(dsi->grf_regmap)) { - DRM_DEV_ERROR(dsi->dev, "Unable to get rockchip,grf\n"); + DRM_DEV_ERROR(dev, "Unable to get rockchip,grf\n"); return PTR_ERR(dsi->grf_regmap); } From a218a397f00994035780292f41301a3bfd5ebb6c Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Mon, 16 Nov 2020 15:16:08 +0100 Subject: [PATCH 0055/5577] drm/rockchip: fix typo in Kconfig 's/HDMI/dsi/' In the help of ROCKCHIP_DW_MIPI_DSI it said it is a HDMI driver instead of a dsi driver. Signed-off-by: Dafna Hirschfeld Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20201116141609.26719-1-dafna.hirschfeld@collabora.com --- drivers/gpu/drm/rockchip/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index 310aa1546893..cb25c0e8fc9b 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -49,7 +49,7 @@ config ROCKCHIP_DW_MIPI_DSI select GENERIC_PHY_MIPI_DPHY help This selects support for Rockchip SoC specific extensions - for the Synopsys DesignWare HDMI driver. If you want to + for the Synopsys DesignWare dsi driver. If you want to enable MIPI DSI on RK3288 or RK3399 based SoC, you should select this option. From 891948966ba52d74e9446bb7d3dded971e54cf4f Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:47 +0100 Subject: [PATCH 0056/5577] video: Fix kernel-doc warnings in of_display_timing + of_videomode Fix kernel-doc warnings reported when using W=1. v3: - Do not replace '-' with ':' (Thomas) v2: - Improve subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Lee Jones Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-2-sam@ravnborg.org --- drivers/video/of_display_timing.c | 1 + drivers/video/of_videomode.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index abc9ada798ee..f93b6abbe258 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -52,6 +52,7 @@ static int parse_timing_property(const struct device_node *np, const char *name, /** * of_parse_display_timing - parse display_timing entry from device_node * @np: device_node with the properties + * @dt: display_timing that contains the result. I may be partially written in case of errors **/ static int of_parse_display_timing(const struct device_node *np, struct display_timing *dt) diff --git a/drivers/video/of_videomode.c b/drivers/video/of_videomode.c index 67aff2421c29..e7d10ffd3b66 100644 --- a/drivers/video/of_videomode.c +++ b/drivers/video/of_videomode.c @@ -14,9 +14,9 @@ /** * of_get_videomode - get the videomode # from devicetree - * @np - devicenode with the display_timings - * @vm - set to return value - * @index - index into list of display_timings + * @np: devicenode with the display_timings + * @vm: set to return value + * @index: index into list of display_timings * (Set this to OF_USE_NATIVE_MODE to use whatever mode is * specified as native mode in the DT.) * From b1cba76de6c7cbf8f5fc9d66e7e7ef81293684dc Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:48 +0100 Subject: [PATCH 0057/5577] video: fbcon: Fix warnings by using pr_debug() in fbcon Replacing DPRINTK() statements with pr_debug fixes set but not used warnings. And moves to a more standard logging setup at the same time. v2: - Fix indent (Joe) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Joe Perches Cc: Greg Kroah-Hartman Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: Sam Ravnborg Cc: Jiri Slaby Cc: Peilin Ye Cc: Tetsuo Handa Cc: George Kennedy Cc: Nathan Chancellor Cc: Peter Rosin Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-3-sam@ravnborg.org --- drivers/video/fbdev/core/fbcon.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index bf61598bf1c3..44a5cd2f54cc 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -56,8 +56,6 @@ * more details. */ -#undef FBCONDEBUG - #include #include #include @@ -82,12 +80,6 @@ #include "fbcon.h" -#ifdef FBCONDEBUG -# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) -#else -# define DPRINTK(fmt, args...) -#endif - /* * FIXME: Locking * @@ -1015,11 +1007,11 @@ static const char *fbcon_startup(void) rows /= vc->vc_font.height; vc_resize(vc, cols, rows); - DPRINTK("mode: %s\n", info->fix.id); - DPRINTK("visual: %d\n", info->fix.visual); - DPRINTK("res: %dx%d-%d\n", info->var.xres, - info->var.yres, - info->var.bits_per_pixel); + pr_debug("mode: %s\n", info->fix.id); + pr_debug("visual: %d\n", info->fix.visual); + pr_debug("res: %dx%d-%d\n", info->var.xres, + info->var.yres, + info->var.bits_per_pixel); fbcon_add_cursor_timer(info); return display_desc; @@ -2013,7 +2005,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, y_diff < 0 || y_diff > virt_fh) { const struct fb_videomode *mode; - DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); + pr_debug("attempting resize %ix%i\n", var.xres, var.yres); mode = fb_find_best_mode(&var, &info->modelist); if (mode == NULL) return -EINVAL; @@ -2023,7 +2015,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh) return -EINVAL; - DPRINTK("resize now %ix%i\n", var.xres, var.yres); + pr_debug("resize now %ix%i\n", var.xres, var.yres); if (con_is_visible(vc)) { var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; @@ -3299,8 +3291,7 @@ static void fbcon_exit(void) if (info->queue.func) pending = cancel_work_sync(&info->queue); - DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" : - "no")); + pr_debug("fbcon: %s pending work\n", (pending ? "canceled" : "no")); for (j = first_fb_vc; j <= last_fb_vc; j++) { if (con2fb_map[j] == i) { From 6fdf38e61310b46e058d618e09e173a837e4c68e Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:14 +0100 Subject: [PATCH 0058/5577] video: fbdev: s1d13xxxfb: Fix kernel-doc and set but not used warnings Fix following W=1 warnings: - Fix set but not used variables that were used only for logging. Fixed by introducing no_printk() to trick compiler to think variables are used - Fix kernel-doc warning by deleting an empty comment line v3: - Fix grammar in commit message (Thomas) v2: - Subject updated (Lee) Signed-off-by: Sam Ravnborg Reviewed-by: Thomas Zimmermann Cc: Kristoffer Ericson Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-29-sam@ravnborg.org --- drivers/video/fbdev/s1d13xxxfb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c index 4541afcf9386..d1b5f965bc96 100644 --- a/drivers/video/fbdev/s1d13xxxfb.c +++ b/drivers/video/fbdev/s1d13xxxfb.c @@ -45,7 +45,7 @@ #if 0 #define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0) #else -#define dbg(fmt, args...) do { } while (0) +#define dbg(fmt, args...) do { no_printk(KERN_INFO fmt, ## args); } while (0) #endif /* @@ -512,7 +512,6 @@ s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area) } /** - * * s1d13xxxfb_bitblt_solidfill - accelerated solidfill function * @info : framebuffer structure * @rect : fb_fillrect structure From 95e22f8ca15abebde8772c75d82992da8d091d3f Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Fri, 27 Nov 2020 11:05:08 -0800 Subject: [PATCH 0059/5577] omapfb: fbcon: remove trailing semicolon in macro definition The macro use will already have a semicolon. Signed-off-by: Tom Rix Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201127190508.2842786-1-trix@redhat.com --- drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c | 2 +- drivers/video/fbdev/omap2/omapfb/dss/dsi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c b/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c index 3417618310ff..cc2ad787d493 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c @@ -75,7 +75,7 @@ static void dispc_dump_irqs(struct seq_file *s) seq_printf(s, "irqs %d\n", stats.irq_count); #define PIS(x) \ - seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]); + seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]) PIS(FRAMEDONE); PIS(VSYNC); diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c index 6f9c25fec994..101fa66f9b58 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c @@ -1554,7 +1554,7 @@ static void dsi_dump_dsidev_irqs(struct platform_device *dsidev, seq_printf(s, "irqs %d\n", stats.irq_count); #define PIS(x) \ - seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); + seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]) seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1); PIS(VC0); From eba0d703b3ca5f1f24df3798c936906f2da39058 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Nov 2020 10:21:37 +0300 Subject: [PATCH 0060/5577] drm/kmb: Remove an unnecessary NULL check The NULL checking isn't done consistently in this function and it leads to a static checker warning: drivers/gpu/drm/kmb/kmb_drv.c:561 kmb_pm_suspend() error: we previously assumed 'drm' could be null (see line 559) Fortunately "drm" cannot be NULL at this point so the check can just be removed. Signed-off-by: Dan Carpenter Reviewed-by: Anitha Chrisanthus Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201117072137.GB1111239@mwanda --- drivers/gpu/drm/kmb/kmb_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c index a31a840ce634..66df3aade088 100644 --- a/drivers/gpu/drm/kmb/kmb_drv.c +++ b/drivers/gpu/drm/kmb/kmb_drv.c @@ -556,7 +556,7 @@ MODULE_DEVICE_TABLE(of, kmb_of_match); static int __maybe_unused kmb_pm_suspend(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); - struct kmb_drm_private *kmb = drm ? to_kmb(drm) : NULL; + struct kmb_drm_private *kmb = to_kmb(drm); drm_kms_helper_poll_disable(drm); From 131f909ad55f798f7bd0c3119d93778da312694a Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 9 Nov 2020 17:00:55 -0800 Subject: [PATCH 0061/5577] drm: panel: simple: Fixup the struct panel_desc kernel doc When I run: scripts/kernel-doc -rst drivers/gpu/drm/panel/panel-simple.c I see that several of the kernel-doc entries aren't showing up because they don't specify the full path down the hierarchy. Let's fix that and also move to inline kernel docs. Signed-off-by: Douglas Anderson Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201109170018.v4.1.Icaa86f0a4ca45a9a7184da4bc63386b29792d613@changeid --- drivers/gpu/drm/panel/panel-simple.c | 59 ++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 41bbec72b2da..c6f152789a4e 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -64,33 +64,58 @@ struct panel_desc { unsigned int bpc; - /** - * @width: width (in millimeters) of the panel's active display area - * @height: height (in millimeters) of the panel's active display area - */ struct { + /** + * @size.width: Width (in mm) of the active display area. + */ unsigned int width; + + /** + * @size.height: Height (in mm) of the active display area. + */ unsigned int height; } size; - /** - * @prepare: the time (in milliseconds) that it takes for the panel to - * become ready and start receiving video data - * @hpd_absent_delay: Add this to the prepare delay if we know Hot - * Plug Detect isn't used. - * @enable: the time (in milliseconds) that it takes for the panel to - * display the first valid frame after starting to receive - * video data - * @disable: the time (in milliseconds) that it takes for the panel to - * turn the display off (no content is visible) - * @unprepare: the time (in milliseconds) that it takes for the panel - * to power itself down completely - */ struct { + /** + * @delay.prepare: Time for the panel to become ready. + * + * The time (in milliseconds) that it takes for the panel to + * become ready and start receiving video data + */ unsigned int prepare; + + /** + * @delay.hpd_absent_delay: Time to wait if HPD isn't hooked up. + * + * Add this to the prepare delay if we know Hot Plug Detect + * isn't used. + */ unsigned int hpd_absent_delay; + + /** + * @delay.enable: Time for the panel to display a valid frame. + * + * The time (in milliseconds) that it takes for the panel to + * display the first valid frame after starting to receive + * video data. + */ unsigned int enable; + + /** + * @delay.disable: Time for the panel to turn the display off. + * + * The time (in milliseconds) that it takes for the panel to + * turn the display off (no content is visible). + */ unsigned int disable; + + /** + * @delay.unprepare: Time to power down completely. + * + * The time (in milliseconds) that it takes for the panel + * to power itself down completely. + */ unsigned int unprepare; } delay; From e5e30dfcf3db1534019c40d94ed58fd2869f9359 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 9 Nov 2020 17:00:56 -0800 Subject: [PATCH 0062/5577] drm: panel: simple: Defer unprepare delay till next prepare to shorten it It is believed that all of the current users of the "unprepare" delay don't actually need to wait the amount of time specified directly in the unprepare phase. The purpose of the delay that's specified is to allow the panel to fully power off so that we don't try to power it back on before it's managed to full power down. Let's use this observation to avoid the fixed delay that we currently have. Instead of delaying, we'll note the current time when the unprepare happens. If someone then tries to prepare the panel later and not enough time has passed, we'll do the delay before starting the prepare phase. Signed-off-by: Douglas Anderson Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201109170018.v4.2.I06a95d83e7fa1bd919c8edd63dacacb5436e495a@changeid --- drivers/gpu/drm/panel/panel-simple.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index c6f152789a4e..72c120a68266 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -115,6 +115,11 @@ struct panel_desc { * * The time (in milliseconds) that it takes for the panel * to power itself down completely. + * + * This time is used to prevent a future "prepare" from + * starting until at least this many milliseconds has passed. + * If at prepare time less time has passed since unprepare + * finished, the driver waits for the remaining time. */ unsigned int unprepare; } delay; @@ -130,6 +135,8 @@ struct panel_simple { bool enabled; bool no_hpd; + ktime_t unprepared_time; + const struct panel_desc *desc; struct regulator *supply; @@ -257,6 +264,20 @@ static int panel_simple_get_non_edid_modes(struct panel_simple *panel, return num; } +static void panel_simple_wait(ktime_t start_ktime, unsigned int min_ms) +{ + ktime_t now_ktime, min_ktime; + + if (!min_ms) + return; + + min_ktime = ktime_add(start_ktime, ms_to_ktime(min_ms)); + now_ktime = ktime_get(); + + if (ktime_before(now_ktime, min_ktime)) + msleep(ktime_to_ms(ktime_sub(min_ktime, now_ktime)) + 1); +} + static int panel_simple_disable(struct drm_panel *panel) { struct panel_simple *p = to_panel_simple(panel); @@ -283,10 +304,8 @@ static int panel_simple_unprepare(struct drm_panel *panel) regulator_disable(p->supply); - if (p->desc->delay.unprepare) - msleep(p->desc->delay.unprepare); - p->prepared = false; + p->unprepared_time = ktime_get(); return 0; } @@ -326,6 +345,8 @@ static int panel_simple_prepare(struct drm_panel *panel) if (p->prepared) return 0; + panel_simple_wait(p->unprepared_time, p->desc->delay.unprepare); + err = regulator_enable(p->supply); if (err < 0) { dev_err(panel->dev, "failed to enable supply: %d\n", err); From 4beb04beb24afe5268bf91407b44864f42f448ed Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 9 Nov 2020 17:00:57 -0800 Subject: [PATCH 0063/5577] drm: panel: simple: Allow specifying the delay from prepare to enable On the panel I'm looking at, there's an 80 ms minimum time between HPD being asserted by the panel and setting the backlight enable GPIO. While we could just add an 80 ms "enable" delay, this is not ideal. Link training is allowed to happen in parallel with this delay so the fixed 80 ms delay over-delays. We'll support this by logging the time at the end of prepare and then delaying in enable if enough time hasn't passed. Signed-off-by: Douglas Anderson Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201109170018.v4.3.Ib9ce3c6482f464bf594161581521ced46bbd54ed@changeid --- drivers/gpu/drm/panel/panel-simple.c | 44 ++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 72c120a68266..cd30f3f51964 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -93,6 +93,36 @@ struct panel_desc { */ unsigned int hpd_absent_delay; + /** + * @delay.prepare_to_enable: Time between prepare and enable. + * + * The minimum time, in milliseconds, that needs to have passed + * between when prepare finished and enable may begin. If at + * enable time less time has passed since prepare finished, + * the driver waits for the remaining time. + * + * If a fixed enable delay is also specified, we'll start + * counting before delaying for the fixed delay. + * + * If a fixed prepare delay is also specified, we won't start + * counting until after the fixed delay. We can't overlap this + * fixed delay with the min time because the fixed delay + * doesn't happen at the end of the function if a HPD GPIO was + * specified. + * + * In other words: + * prepare() + * ... + * // do fixed prepare delay + * // wait for HPD GPIO if applicable + * // start counting for prepare_to_enable + * + * enable() + * // do fixed enable delay + * // enforce prepare_to_enable min time + */ + unsigned int prepare_to_enable; + /** * @delay.enable: Time for the panel to display a valid frame. * @@ -131,10 +161,10 @@ struct panel_desc { struct panel_simple { struct drm_panel base; - bool prepared; bool enabled; bool no_hpd; + ktime_t prepared_time; ktime_t unprepared_time; const struct panel_desc *desc; @@ -297,14 +327,14 @@ static int panel_simple_unprepare(struct drm_panel *panel) { struct panel_simple *p = to_panel_simple(panel); - if (!p->prepared) + if (p->prepared_time == 0) return 0; gpiod_set_value_cansleep(p->enable_gpio, 0); regulator_disable(p->supply); - p->prepared = false; + p->prepared_time = 0; p->unprepared_time = ktime_get(); return 0; @@ -342,7 +372,7 @@ static int panel_simple_prepare(struct drm_panel *panel) int err; int hpd_asserted; - if (p->prepared) + if (p->prepared_time != 0) return 0; panel_simple_wait(p->unprepared_time, p->desc->delay.unprepare); @@ -381,7 +411,7 @@ static int panel_simple_prepare(struct drm_panel *panel) } } - p->prepared = true; + p->prepared_time = ktime_get(); return 0; } @@ -396,6 +426,8 @@ static int panel_simple_enable(struct drm_panel *panel) if (p->desc->delay.enable) msleep(p->desc->delay.enable); + panel_simple_wait(p->prepared_time, p->desc->delay.prepare_to_enable); + p->enabled = true; return 0; @@ -562,7 +594,7 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) return -ENOMEM; panel->enabled = false; - panel->prepared = false; + panel->prepared_time = 0; panel->desc = desc; panel->no_hpd = of_property_read_bool(dev->of_node, "no-hpd"); From 981963a2118bc74c3ed9e4499048d2fe3353fbaf Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 9 Nov 2020 17:00:59 -0800 Subject: [PATCH 0064/5577] dt-bindings: dt-bindings: display: simple: Add BOE NV110WTM-N61 Add yet another eDP panel. Signed-off-by: Douglas Anderson Acked-by: Rob Herring Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201109170018.v4.5.I28d9e32b3cc0aae980ecc39d364263a3f9871298@changeid --- .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 27fffafe5b5c..35b42ee4ed1d 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -76,6 +76,8 @@ properties: # BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel - boe,nv101wxmn51 # BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel + - boe,nv110wtm-n61 + # BOE NV110WTM-N61 11.0" 2160x1440 TFT LCD Panel - boe,nv133fhm-n61 # BOE NV133FHM-N62 13.3" FHD (1920x1080) TFT LCD Panel - boe,nv133fhm-n62 From a96ee0f6b58de5c4f627489b2d31a5099a779cb9 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 9 Nov 2020 17:00:58 -0800 Subject: [PATCH 0065/5577] drm: panel: simple: Add BOE NV110WTM-N61 Add support for the BOE NV110WTM-N61 panel. The EDID lists two modes (one for 60 Hz refresh rate and one for 40 Hz), so we'll list both of them here. Note that the panel datasheet requires 80 ms between HPD asserting and the backlight power being turned on. We'll use the new timing constraints structure to do this cleanly. This assumes that the backlight will be enabled _after_ the panel enable finishes. This is how it works today and seems a sane assumption. Signed-off-by: Douglas Anderson Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201109170018.v4.4.I71b2118dfc00fd7b43b02d28e7b890081c2acfa2@changeid --- drivers/gpu/drm/panel/panel-simple.c | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index cd30f3f51964..216cde33b5c4 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1396,6 +1396,49 @@ static const struct panel_desc boe_nv101wxmn51 = { }, }; +static const struct drm_display_mode boe_nv110wtm_n61_modes[] = { + { + .clock = 207800, + .hdisplay = 2160, + .hsync_start = 2160 + 48, + .hsync_end = 2160 + 48 + 32, + .htotal = 2160 + 48 + 32 + 100, + .vdisplay = 1440, + .vsync_start = 1440 + 3, + .vsync_end = 1440 + 3 + 6, + .vtotal = 1440 + 3 + 6 + 31, + }, + { + .clock = 138500, + .hdisplay = 2160, + .hsync_start = 2160 + 48, + .hsync_end = 2160 + 48 + 32, + .htotal = 2160 + 48 + 32 + 100, + .vdisplay = 1440, + .vsync_start = 1440 + 3, + .vsync_end = 1440 + 3 + 6, + .vtotal = 1440 + 3 + 6 + 31, + }, +}; + +static const struct panel_desc boe_nv110wtm_n61 = { + .modes = boe_nv110wtm_n61_modes, + .num_modes = ARRAY_SIZE(boe_nv110wtm_n61_modes), + .bpc = 8, + .size = { + .width = 233, + .height = 155, + }, + .delay = { + .hpd_absent_delay = 200, + .prepare_to_enable = 80, + .unprepare = 500, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DATA_MSB_TO_LSB, + .connector_type = DRM_MODE_CONNECTOR_eDP, +}; + /* Also used for boe_nv133fhm_n62 */ static const struct drm_display_mode boe_nv133fhm_n61_modes = { .clock = 147840, @@ -4111,6 +4154,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "boe,nv101wxmn51", .data = &boe_nv101wxmn51, + }, { + .compatible = "boe,nv110wtm-n61", + .data = &boe_nv110wtm_n61, }, { .compatible = "boe,nv133fhm-n61", .data = &boe_nv133fhm_n61, From bc2532ab7c20844d16c5cda97d0806eb80ab1275 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 23 Nov 2020 12:56:45 +0100 Subject: [PATCH 0066/5577] drm/cma-helper: Remove prime infix from GEM object functions These functions are not directly related to PRIME interfaces any longer, but are now GEM object functions. Rename them accordingly and fix the docs. Signed-off-by: Thomas Zimmermann Acked-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201123115646.11004-2-tzimmermann@suse.de --- drivers/gpu/drm/drm_gem_cma_helper.c | 20 ++++++++++---------- drivers/gpu/drm/vc4/vc4_bo.c | 4 ++-- include/drm/drm_gem_cma_helper.h | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 4d5c1d86b022..6a4ef335ebc9 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -36,8 +36,8 @@ static const struct drm_gem_object_funcs drm_gem_cma_default_funcs = { .free = drm_gem_cma_free_object, .print_info = drm_gem_cma_print_info, - .get_sg_table = drm_gem_cma_prime_get_sg_table, - .vmap = drm_gem_cma_prime_vmap, + .get_sg_table = drm_gem_cma_get_sg_table, + .vmap = drm_gem_cma_vmap, .vm_ops = &drm_gem_cma_vm_ops, }; @@ -424,18 +424,18 @@ void drm_gem_cma_print_info(struct drm_printer *p, unsigned int indent, EXPORT_SYMBOL(drm_gem_cma_print_info); /** - * drm_gem_cma_prime_get_sg_table - provide a scatter/gather table of pinned + * drm_gem_cma_get_sg_table - provide a scatter/gather table of pinned * pages for a CMA GEM object * @obj: GEM object * - * This function exports a scatter/gather table suitable for PRIME usage by + * This function exports a scatter/gather table by * calling the standard DMA mapping API. Drivers using the CMA helpers should * set this as their &drm_gem_object_funcs.get_sg_table callback. * * Returns: * A pointer to the scatter/gather table of pinned pages or NULL on failure. */ -struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj) +struct sg_table *drm_gem_cma_get_sg_table(struct drm_gem_object *obj) { struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); struct sg_table *sgt; @@ -456,7 +456,7 @@ out: kfree(sgt); return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table); +EXPORT_SYMBOL_GPL(drm_gem_cma_get_sg_table); /** * drm_gem_cma_prime_import_sg_table - produce a CMA GEM object from another @@ -528,13 +528,13 @@ int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); /** - * drm_gem_cma_prime_vmap - map a CMA GEM object into the kernel's virtual + * drm_gem_cma_vmap - map a CMA GEM object into the kernel's virtual * address space * @obj: GEM object * @map: Returns the kernel virtual address of the CMA GEM object's backing * store. * - * This function maps a buffer exported via DRM PRIME into the kernel's + * This function maps a buffer into the kernel's * virtual address space. Since the CMA buffers are already mapped into the * kernel virtual address space this simply returns the cached virtual * address. Drivers using the CMA helpers should set this as their DRM @@ -543,7 +543,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); * Returns: * 0 on success, or a negative error code otherwise. */ -int drm_gem_cma_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) +int drm_gem_cma_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) { struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); @@ -551,7 +551,7 @@ int drm_gem_cma_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) return 0; } -EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap); +EXPORT_SYMBOL_GPL(drm_gem_cma_vmap); /** * drm_gem_cma_prime_import_sg_table_vmap - PRIME import another driver's diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 469d1b4f2643..813e6cb3f9af 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -385,7 +385,7 @@ static const struct vm_operations_struct vc4_vm_ops = { static const struct drm_gem_object_funcs vc4_gem_object_funcs = { .free = vc4_free_object, .export = vc4_prime_export, - .get_sg_table = drm_gem_cma_prime_get_sg_table, + .get_sg_table = drm_gem_cma_get_sg_table, .vmap = vc4_prime_vmap, .vm_ops = &vc4_vm_ops, }; @@ -794,7 +794,7 @@ int vc4_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) return -EINVAL; } - return drm_gem_cma_prime_vmap(obj, map); + return drm_gem_cma_vmap(obj, map); } struct drm_gem_object * diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index 5605c1b8f779..4680275ab339 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -96,14 +96,14 @@ unsigned long drm_gem_cma_get_unmapped_area(struct file *filp, void drm_gem_cma_print_info(struct drm_printer *p, unsigned int indent, const struct drm_gem_object *obj); -struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj); +struct sg_table *drm_gem_cma_get_sg_table(struct drm_gem_object *obj); struct drm_gem_object * drm_gem_cma_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); -int drm_gem_cma_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); +int drm_gem_cma_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); /** * DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE - CMA GEM driver operations From f5ca8eb6f9bd5ea76e11bbcee09528e2d71fa920 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 23 Nov 2020 12:56:46 +0100 Subject: [PATCH 0067/5577] drm/cma-helper: Implement mmap as GEM CMA object functions The new GEM object function drm_gem_cma_mmap() sets the VMA flags and offset as in the old implementation and immediately maps in the buffer's memory pages. Changing CMA helpers to use the GEM object function allows for the removal of the special implementations for mmap and gem_prime_mmap callbacks. The regular functions drm_gem_mmap() and drm_gem_prime_mmap() are now used. Signed-off-by: Thomas Zimmermann Acked-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201123115646.11004-3-tzimmermann@suse.de --- drivers/gpu/drm/drm_file.c | 3 +- drivers/gpu/drm/drm_gem_cma_helper.c | 121 +++++++++------------------ drivers/gpu/drm/pl111/pl111_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_bo.c | 2 +- include/drm/drm_gem_cma_helper.h | 10 +-- 5 files changed, 44 insertions(+), 94 deletions(-) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index b50380fa80ce..80886d50d0f1 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -113,8 +113,7 @@ bool drm_dev_needs_global_mutex(struct drm_device *dev) * The memory mapping implementation will vary depending on how the driver * manages memory. Legacy drivers will use the deprecated drm_legacy_mmap() * function, modern drivers should use one of the provided memory-manager - * specific implementations. For GEM-based drivers this is drm_gem_mmap(), and - * for drivers which use the CMA GEM helpers it's drm_gem_cma_mmap(). + * specific implementations. For GEM-based drivers this is drm_gem_mmap(). * * No other file operations are supported by the DRM userspace API. Overall the * following is an example &file_operations structure:: diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 6a4ef335ebc9..7942cf05cd93 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -38,6 +38,7 @@ static const struct drm_gem_object_funcs drm_gem_cma_default_funcs = { .print_info = drm_gem_cma_print_info, .get_sg_table = drm_gem_cma_get_sg_table, .vmap = drm_gem_cma_vmap, + .mmap = drm_gem_cma_mmap, .vm_ops = &drm_gem_cma_vm_ops, }; @@ -277,62 +278,6 @@ const struct vm_operations_struct drm_gem_cma_vm_ops = { }; EXPORT_SYMBOL_GPL(drm_gem_cma_vm_ops); -static int drm_gem_cma_mmap_obj(struct drm_gem_cma_object *cma_obj, - struct vm_area_struct *vma) -{ - int ret; - - /* - * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the - * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map - * the whole buffer. - */ - vma->vm_flags &= ~VM_PFNMAP; - vma->vm_pgoff = 0; - - ret = dma_mmap_wc(cma_obj->base.dev->dev, vma, cma_obj->vaddr, - cma_obj->paddr, vma->vm_end - vma->vm_start); - if (ret) - drm_gem_vm_close(vma); - - return ret; -} - -/** - * drm_gem_cma_mmap - memory-map a CMA GEM object - * @filp: file object - * @vma: VMA for the area to be mapped - * - * This function implements an augmented version of the GEM DRM file mmap - * operation for CMA objects: In addition to the usual GEM VMA setup it - * immediately faults in the entire object instead of using on-demaind - * faulting. Drivers which employ the CMA helpers should use this function - * as their ->mmap() handler in the DRM device file's file_operations - * structure. - * - * Instead of directly referencing this function, drivers should use the - * DEFINE_DRM_GEM_CMA_FOPS().macro. - * - * Returns: - * 0 on success or a negative error code on failure. - */ -int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_gem_cma_object *cma_obj; - struct drm_gem_object *gem_obj; - int ret; - - ret = drm_gem_mmap(filp, vma); - if (ret) - return ret; - - gem_obj = vma->vm_private_data; - cma_obj = to_drm_gem_cma_obj(gem_obj); - - return drm_gem_cma_mmap_obj(cma_obj, vma); -} -EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); - #ifndef CONFIG_MMU /** * drm_gem_cma_get_unmapped_area - propose address for mapping in noMMU cases @@ -500,33 +445,6 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev, } EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table); -/** - * drm_gem_cma_prime_mmap - memory-map an exported CMA GEM object - * @obj: GEM object - * @vma: VMA for the area to be mapped - * - * This function maps a buffer imported via DRM PRIME into a userspace - * process's address space. Drivers that use the CMA helpers should set this - * as their &drm_driver.gem_prime_mmap callback. - * - * Returns: - * 0 on success or a negative error code on failure. - */ -int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma) -{ - struct drm_gem_cma_object *cma_obj; - int ret; - - ret = drm_gem_mmap_obj(obj, obj->size, vma); - if (ret < 0) - return ret; - - cma_obj = to_drm_gem_cma_obj(obj); - return drm_gem_cma_mmap_obj(cma_obj, vma); -} -EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); - /** * drm_gem_cma_vmap - map a CMA GEM object into the kernel's virtual * address space @@ -553,6 +471,43 @@ int drm_gem_cma_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) } EXPORT_SYMBOL_GPL(drm_gem_cma_vmap); +/** + * drm_gem_cma_mmap - memory-map an exported CMA GEM object + * @obj: GEM object + * @vma: VMA for the area to be mapped + * + * This function maps a buffer into a userspace process's address space. + * In addition to the usual GEM VMA setup it immediately faults in the entire + * object instead of using on-demand faulting. Drivers that use the CMA + * helpers should set this as their &drm_gem_object_funcs.mmap callback. + * + * Returns: + * 0 on success or a negative error code on failure. + */ +int drm_gem_cma_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + struct drm_gem_cma_object *cma_obj; + int ret; + + /* + * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the + * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map + * the whole buffer. + */ + vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); + vma->vm_flags &= ~VM_PFNMAP; + + cma_obj = to_drm_gem_cma_obj(obj); + + ret = dma_mmap_wc(cma_obj->base.dev->dev, vma, cma_obj->vaddr, + cma_obj->paddr, vma->vm_end - vma->vm_start); + if (ret) + drm_gem_vm_close(vma); + + return ret; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); + /** * drm_gem_cma_prime_import_sg_table_vmap - PRIME import another driver's * scatter/gather table and get the virtual address of the buffer diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index 40e6708fbbe2..e4dcaef6c143 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -228,7 +228,7 @@ static const struct drm_driver pl111_drm_driver = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import_sg_table = pl111_gem_import_sg_table, - .gem_prime_mmap = drm_gem_cma_prime_mmap, + .gem_prime_mmap = drm_gem_prime_mmap, #if defined(CONFIG_DEBUG_FS) .debugfs_init = pl111_debugfs_init, diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 813e6cb3f9af..dc316cb79e00 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -782,7 +782,7 @@ int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) return -EINVAL; } - return drm_gem_cma_prime_mmap(obj, vma); + return drm_gem_prime_mmap(obj, vma); } int vc4_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index 4680275ab339..0a9711caa3e8 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -59,7 +59,7 @@ struct drm_gem_cma_object { .poll = drm_poll,\ .read = drm_read,\ .llseek = noop_llseek,\ - .mmap = drm_gem_cma_mmap,\ + .mmap = drm_gem_mmap,\ DRM_GEM_CMA_UNMAPPED_AREA_FOPS \ } @@ -76,9 +76,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_device *drm, struct drm_mode_create_dumb *args); -/* set vm_flags and we can change the VM attribute to other one at here */ -int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); - /* allocate physical memory */ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, size_t size); @@ -101,9 +98,8 @@ struct drm_gem_object * drm_gem_cma_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); -int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma); int drm_gem_cma_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); +int drm_gem_cma_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); /** * DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE - CMA GEM driver operations @@ -123,7 +119,7 @@ int drm_gem_cma_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); .prime_handle_to_fd = drm_gem_prime_handle_to_fd, \ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, \ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, \ - .gem_prime_mmap = drm_gem_cma_prime_mmap + .gem_prime_mmap = drm_gem_prime_mmap /** * DRM_GEM_CMA_DRIVER_OPS - CMA GEM driver operations From 0575ff3d33cd62123991d2a5d0d8459d72592388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 8 Oct 2020 13:01:35 +0200 Subject: [PATCH 0068/5577] drm/radeon: stop using pages with drm_prime_sg_to_page_addr_arrays v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is deprecated. v2: also use ttm_sg_tt_init to avoid allocating the page array. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/403832/ --- drivers/gpu/drm/radeon/radeon_ttm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 2b598141225f..917419bf1578 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -395,8 +395,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_bo_device *bdev, struct ttm_tt * if (r) goto release_sg; - drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, - gtt->ttm.dma_address, ttm->num_pages); + drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, gtt->ttm.dma_address, + ttm->num_pages); return 0; @@ -536,7 +536,7 @@ static struct ttm_tt *radeon_ttm_tt_create(struct ttm_buffer_object *bo, else caching = ttm_cached; - if (ttm_dma_tt_init(>t->ttm, bo, page_flags, caching)) { + if (ttm_sg_tt_init(>t->ttm, bo, page_flags, caching)) { kfree(gtt); return NULL; } @@ -574,8 +574,9 @@ static int radeon_ttm_tt_populate(struct ttm_bo_device *bdev, } if (slave && ttm->sg) { - drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, - gtt->ttm.dma_address, ttm->num_pages); + drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, + gtt->ttm.dma_address, + ttm->num_pages); return 0; } From 4e7b9000b6d8ec609d5bff1a1eb4bf6cece35dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 8 Oct 2020 13:02:06 +0200 Subject: [PATCH 0069/5577] drm/amdgpu: stop using pages with drm_prime_sg_to_page_addr_arrays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is deprecated. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/403836/ --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index c438d290a6db..02748e030322 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -918,8 +918,8 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_bo_device *bdev, goto release_sg; /* convert SG to linear array of pages and dma addresses */ - drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, - gtt->ttm.dma_address, ttm->num_pages); + drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, gtt->ttm.dma_address, + ttm->num_pages); return 0; @@ -1264,7 +1264,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_bo_device *bdev, ttm->sg = sgt; } - drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, + drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, gtt->ttm.dma_address, ttm->num_pages); return 0; From 470cfe71b420698ab3715d27021a34d45872f554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 9 Oct 2020 15:44:48 +0200 Subject: [PATCH 0070/5577] drm/nouveau: stop using pages with drm_prime_sg_to_page_addr_arrays v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is deprecated, also drop the comment about faults. v2: also use ttm_sg_tt_init to avoid allocating the page array. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/403835/ --- drivers/gpu/drm/nouveau/nouveau_bo.c | 6 +++--- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7aa4286784ae..c30f088cefcc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1235,9 +1235,9 @@ nouveau_ttm_tt_populate(struct ttm_bo_device *bdev, return 0; if (slave && ttm->sg) { - /* make userspace faulting work */ - drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, - ttm_dma->dma_address, ttm->num_pages); + drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, + ttm_dma->dma_address, + ttm->num_pages); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index a2e23fd4906c..1cf52635ea74 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -84,7 +84,7 @@ nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo, uint32_t page_flags) if (!nvbe) return NULL; - if (ttm_dma_tt_init(&nvbe->ttm, bo, page_flags, caching)) { + if (ttm_sg_tt_init(&nvbe->ttm, bo, page_flags, caching)) { kfree(nvbe); return NULL; } From 4c515bb187ee3cc4c75a9d4a413b97d719f15f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 23 Nov 2020 14:53:05 +0100 Subject: [PATCH 0071/5577] drm/vmwgfx: switch to ttm_sg_tt_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to Daniel VMWGFX doesn't support DMA-buf anyway. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/403834/ --- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 6a04261ce760..1c75f73538c0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -611,8 +611,8 @@ static struct ttm_tt *vmw_ttm_tt_create(struct ttm_buffer_object *bo, vmw_be->mob = NULL; if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent) - ret = ttm_dma_tt_init(&vmw_be->dma_ttm, bo, page_flags, - ttm_cached); + ret = ttm_sg_tt_init(&vmw_be->dma_ttm, bo, page_flags, + ttm_cached); else ret = ttm_tt_init(&vmw_be->dma_ttm, bo, page_flags, ttm_cached); From 2705d14a3145d840d13527e5e04748dd78c442fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 23 Nov 2020 14:54:36 +0100 Subject: [PATCH 0072/5577] drm/qxl: switch to ttm_sg_tt_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function qxl_gem_prime_import_sg_table is not fully implemented. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/403833/ --- drivers/gpu/drm/qxl/qxl_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 128c38c8a837..d42e750cbdd3 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -115,7 +115,7 @@ static struct ttm_tt *qxl_ttm_tt_create(struct ttm_buffer_object *bo, ttm = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL); if (ttm == NULL) return NULL; - if (ttm_dma_tt_init(ttm, bo, page_flags, ttm_cached)) { + if (ttm_sg_tt_init(ttm, bo, page_flags, ttm_cached)) { kfree(ttm); return NULL; } From 18f7608a67fca8b8305b3557e2c00bca54785acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 23 Nov 2020 14:56:49 +0100 Subject: [PATCH 0073/5577] drm/ttm: nuke ttm_dma_tt_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used any more. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/403837/ --- drivers/gpu/drm/ttm/ttm_tt.c | 13 ------------- include/drm/ttm/ttm_tt.h | 2 -- 2 files changed, 15 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index da9eeffe0c6d..77ba784425dd 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -162,19 +162,6 @@ void ttm_tt_fini(struct ttm_tt *ttm) } EXPORT_SYMBOL(ttm_tt_fini); -int ttm_dma_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo, - uint32_t page_flags, enum ttm_caching caching) -{ - ttm_tt_init_fields(ttm, bo, page_flags, caching); - - if (ttm_dma_tt_alloc_page_directory(ttm)) { - pr_err("Failed allocating page table\n"); - return -ENOMEM; - } - return 0; -} -EXPORT_SYMBOL(ttm_dma_tt_init); - int ttm_sg_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo, uint32_t page_flags, enum ttm_caching caching) { diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index da27e9d8fa64..6c8eb9a4de81 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -99,8 +99,6 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc); */ int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo, uint32_t page_flags, enum ttm_caching caching); -int ttm_dma_tt_init(struct ttm_tt *ttm_dma, struct ttm_buffer_object *bo, - uint32_t page_flags, enum ttm_caching caching); int ttm_sg_tt_init(struct ttm_tt *ttm_dma, struct ttm_buffer_object *bo, uint32_t page_flags, enum ttm_caching caching); From c67e62790f5c156705fb162da840c6d89d0af6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 8 Oct 2020 12:57:32 +0200 Subject: [PATCH 0074/5577] drm/prime: split array import functions v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mapping the imported pages of a DMA-buf into an userspace process doesn't work as expected. But we have reoccurring requests on this approach, so split the functions for this and document that dma_buf_mmap() needs to be used instead. v2: split it into two functions v3: rebased on latest changes v4: update commit message a bit Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/403838/ --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 ++- drivers/gpu/drm/drm_prime.c | 68 +++++++++++++-------- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 3 +- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 2 +- drivers/gpu/drm/msm/msm_gem.c | 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 5 +- drivers/gpu/drm/omapdrm/omap_gem.c | 3 +- drivers/gpu/drm/radeon/radeon_ttm.c | 9 ++- drivers/gpu/drm/vgem/vgem_drv.c | 3 +- drivers/gpu/drm/xen/xen_drm_front_gem.c | 4 +- include/drm/drm_prime.h | 7 ++- 11 files changed, 62 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 02748e030322..a34fedcc8b61 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -918,8 +918,8 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_bo_device *bdev, goto release_sg; /* convert SG to linear array of pages and dma addresses */ - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, gtt->ttm.dma_address, - ttm->num_pages); + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, + ttm->num_pages); return 0; @@ -1264,9 +1264,8 @@ static int amdgpu_ttm_tt_populate(struct ttm_bo_device *bdev, ttm->sg = sgt; } - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, - gtt->ttm.dma_address, - ttm->num_pages); + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, + ttm->num_pages); return 0; } diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 7db55fce35d8..683aa29ecd3b 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -978,44 +978,58 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, EXPORT_SYMBOL(drm_gem_prime_import); /** - * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array + * drm_prime_sg_to_page_array - convert an sg table into a page array * @sgt: scatter-gather table to convert - * @pages: optional array of page pointers to store the page array in - * @addrs: optional array to store the dma bus address of each page - * @max_entries: size of both the passed-in arrays + * @pages: array of page pointers to store the pages in + * @max_entries: size of the passed-in array * - * Exports an sg table into an array of pages and addresses. This is currently - * required by the TTM driver in order to do correct fault handling. + * Exports an sg table into an array of pages. * - * Drivers can use this in their &drm_driver.gem_prime_import_sg_table - * implementation. + * This function is deprecated and strongly discouraged to be used. + * The page array is only useful for page faults and those can corrupt fields + * in the struct page if they are not handled by the exporting driver. */ -int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, - dma_addr_t *addrs, int max_entries) +int __deprecated drm_prime_sg_to_page_array(struct sg_table *sgt, + struct page **pages, + int max_entries) { - struct sg_dma_page_iter dma_iter; struct sg_page_iter page_iter; struct page **p = pages; - dma_addr_t *a = addrs; - if (pages) { - for_each_sgtable_page(sgt, &page_iter, 0) { - if (WARN_ON(p - pages >= max_entries)) - return -1; - *p++ = sg_page_iter_page(&page_iter); - } + for_each_sgtable_page(sgt, &page_iter, 0) { + if (WARN_ON(p - pages >= max_entries)) + return -1; + *p++ = sg_page_iter_page(&page_iter); } - if (addrs) { - for_each_sgtable_dma_page(sgt, &dma_iter, 0) { - if (WARN_ON(a - addrs >= max_entries)) - return -1; - *a++ = sg_page_iter_dma_address(&dma_iter); - } - } - return 0; } -EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); +EXPORT_SYMBOL(drm_prime_sg_to_page_array); + +/** + * drm_prime_sg_to_dma_addr_array - convert an sg table into a dma addr array + * @sgt: scatter-gather table to convert + * @addrs: array to store the dma bus address of each page + * @max_entries: size of both the passed-in arrays + * + * Exports an sg table into an array of addresses. + * + * Drivers should use this in their &drm_driver.gem_prime_import_sg_table + * implementation. + */ +int drm_prime_sg_to_dma_addr_array(struct sg_table *sgt, dma_addr_t *addrs, + int max_entries) +{ + struct sg_dma_page_iter dma_iter; + dma_addr_t *a = addrs; + + for_each_sgtable_dma_page(sgt, &dma_iter, 0) { + if (WARN_ON(a - addrs >= max_entries)) + return -1; + *a++ = sg_page_iter_dma_address(&dma_iter); + } + return 0; +} +EXPORT_SYMBOL(drm_prime_sg_to_dma_addr_array); /** * drm_prime_gem_destroy - helper to clean up a PRIME-imported GEM object diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index d9bd83203a15..b390dd4d60b7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -135,8 +135,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, goto fail; } - ret = drm_prime_sg_to_page_addr_arrays(sgt, etnaviv_obj->pages, - NULL, npages); + ret = drm_prime_sg_to_page_array(sgt, etnaviv_obj->pages, npages); if (ret) goto fail; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 28a2ee1336ef..280ea0d5e840 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -260,7 +260,7 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) return -ENOMEM; } - drm_prime_sg_to_page_addr_arrays(sgt, mtk_gem->pages, NULL, npages); + drm_prime_sg_to_page_array(sgt, mtk_gem->pages, npages); mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 311721ceee50..f995cb02b63d 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1180,7 +1180,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, goto fail; } - ret = drm_prime_sg_to_page_addr_arrays(sgt, msm_obj->pages, NULL, npages); + ret = drm_prime_sg_to_page_array(sgt, msm_obj->pages, npages); if (ret) { mutex_unlock(&msm_obj->lock); goto fail; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index c30f088cefcc..645e7091dffc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1235,9 +1235,8 @@ nouveau_ttm_tt_populate(struct ttm_bo_device *bdev, return 0; if (slave && ttm->sg) { - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, - ttm_dma->dma_address, - ttm->num_pages); + drm_prime_sg_to_dma_addr_array(ttm->sg, ttm_dma->dma_address, + ttm->num_pages); return 0; } diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 30d299ca8795..38af6195d959 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1324,8 +1324,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, } omap_obj->pages = pages; - ret = drm_prime_sg_to_page_addr_arrays(sgt, pages, NULL, - npages); + ret = drm_prime_sg_to_page_array(sgt, pages, npages); if (ret) { omap_gem_free_object(obj); obj = ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 917419bf1578..f1f7adb67c8e 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -395,8 +395,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_bo_device *bdev, struct ttm_tt * if (r) goto release_sg; - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, gtt->ttm.dma_address, - ttm->num_pages); + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, + ttm->num_pages); return 0; @@ -574,9 +574,8 @@ static int radeon_ttm_tt_populate(struct ttm_bo_device *bdev, } if (slave && ttm->sg) { - drm_prime_sg_to_page_addr_arrays(ttm->sg, NULL, - gtt->ttm.dma_address, - ttm->num_pages); + drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address, + ttm->num_pages); return 0; } diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index f8635ccaf9a1..a0e75f1d5d01 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -356,8 +356,7 @@ static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev, } obj->pages_pin_count++; /* perma-pinned */ - drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL, - npages); + drm_prime_sg_to_page_array(obj->table, obj->pages, npages); return &obj->base; } diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c index 74db5a840bed..b293c67230ef 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_gem.c +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c @@ -220,8 +220,8 @@ xen_drm_front_gem_import_sg_table(struct drm_device *dev, xen_obj->sgt_imported = sgt; - ret = drm_prime_sg_to_page_addr_arrays(sgt, xen_obj->pages, - NULL, xen_obj->num_pages); + ret = drm_prime_sg_to_page_array(sgt, xen_obj->pages, + xen_obj->num_pages); if (ret < 0) return ERR_PTR(ret); diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index 0991a47a1567..54f2c58305d2 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -105,8 +105,9 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); -int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, - dma_addr_t *addrs, int max_pages); - +int drm_prime_sg_to_page_array(struct sg_table *sgt, struct page **pages, + int max_pages); +int drm_prime_sg_to_dma_addr_array(struct sg_table *sgt, dma_addr_t *addrs, + int max_pages); #endif /* __DRM_PRIME_H__ */ From f7ed83cc1925f0b8ce2515044d674354035c3af9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 24 Nov 2020 18:35:21 +0000 Subject: [PATCH 0075/5577] drm/i915/gt: Limit frequency drop to RPe on parking We treat idling the GT (intel_rps_park) as a downclock event, and reduce the frequency we intend to restart the GT with. Since the two workloads are likely related (e.g. a compositor rendering every 16ms), we want to carry the frequency and load information from across the idling. However, we do also need to update the frequencies so that workloads that run for less than 1ms are autotuned by RPS (otherwise we leave compositors running at max clocks, draining excess power). Conversely, if we try to run too slowly, the next workload has to run longer. Since there is a hysteresis in the power graph, below a certain frequency running a short workload for longer consumes more energy than running it slightly higher for less time. The exact balance point is unknown beforehand, but measurements with 30fps media playback indicate that RPe is a better choice. Reported-by: Edward Baker Tested-by: Edward Baker Fixes: 043cd2d14ede ("drm/i915/gt: Leave rps->cur_freq on unpark") Signed-off-by: Chris Wilson Cc: Edward Baker Cc: Andi Shyti Cc: Lyude Paul Cc: # v5.8+ Reviewed-by: Rodrigo Vivi Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20201124183521.28623-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_rps.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index b13e7845d483..f74d5e09e176 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -907,6 +907,10 @@ void intel_rps_park(struct intel_rps *rps) adj = -2; rps->last_adj = adj; rps->cur_freq = max_t(int, rps->cur_freq + adj, rps->min_freq); + if (rps->cur_freq < rps->efficient_freq) { + rps->cur_freq = rps->efficient_freq; + rps->last_adj = 0; + } GT_TRACE(rps_to_gt(rps), "park:%x\n", rps->cur_freq); } From 77acab40a61ad079e31892d15d0b0ab9714ed099 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Mon, 30 Nov 2020 14:18:08 +0000 Subject: [PATCH 0076/5577] drm/i915/selftest: also consider non-contiguous objects In igt_ppgtt_sanity_check we should also exercise the non-contiguous option for LMEM, since this will give us slightly different sg layouts and alignment. Signed-off-by: Matthew Auld Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130141809.65330-1-matthew.auld@intel.com --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 1f35e71429b4..0bf93947d89d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1333,6 +1333,7 @@ static int igt_ppgtt_sanity_check(void *arg) unsigned int flags; } backends[] = { { igt_create_system, 0, }, + { igt_create_local, 0, }, { igt_create_local, I915_BO_ALLOC_CONTIGUOUS, }, }; struct { From e96434e1137e9a110014e2d5717348623f68ea77 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Mon, 30 Nov 2020 14:18:09 +0000 Subject: [PATCH 0077/5577] drm/i915/selftest: assert we get 2M GTT pages For the LMEM case if we have suitable alignment and 2M physical pages we should always get 2M GTT pages within the constraints of the hugepages selftest. If we don't then something might be wrong in our construction of the backing pages. References: 330b7d33056b ("drm/i915/region: fix order when adding blocks") Signed-off-by: Matthew Auld Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130141809.65330-2-matthew.auld@intel.com --- .../gpu/drm/i915/gem/selftests/huge_pages.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 0bf93947d89d..aacf4856ccb4 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -368,6 +368,27 @@ static int igt_check_page_sizes(struct i915_vma *vma) err = -EINVAL; } + /* + * The dma-api is like a box of chocolates when it comes to the + * alignment of dma addresses, however for LMEM we have total control + * and so can guarantee alignment, likewise when we allocate our blocks + * they should appear in descending order, and if we know that we align + * to the largest page size for the GTT address, we should be able to + * assert that if we see 2M physical pages then we should also get 2M + * GTT pages. If we don't then something might be wrong in our + * construction of the backing pages. + * + * Maintaining alignment is required to utilise huge pages in the ppGGT. + */ + if (i915_gem_object_is_lmem(obj) && + IS_ALIGNED(vma->node.start, SZ_2M) && + vma->page_sizes.sg & SZ_2M && + vma->page_sizes.gtt < SZ_2M) { + pr_err("gtt pages mismatch for LMEM, expected 2M GTT pages, sg(%u), gtt(%u)\n", + vma->page_sizes.sg, vma->page_sizes.gtt); + err = -EINVAL; + } + if (obj->mm.page_sizes.gtt) { pr_err("obj->page_sizes.gtt(%u) should never be set\n", obj->mm.page_sizes.gtt); From d2cf0125d4a133a857d3327f7ac1625c84624219 Mon Sep 17 00:00:00 2001 From: Venkata Sandeep Dhanalakota Date: Mon, 30 Nov 2020 13:47:21 +0000 Subject: [PATCH 0078/5577] drm/i915/lmem: Limit block size to 4G Block sizes are only limited by the largest power-of-two that will fit in the region size, but to construct an object we also require feeding it into an sg list, where the upper limit of the sg entry is at most UINT_MAX. Therefore to prevent issues with allocating blocks that are too large, add the flag I915_ALLOC_MAX_SEGMENT_SIZE which should limit block sizes to the i915_sg_segment_size(). v2: (matt) - query the max segment. - prefer flag to limit block size to 4G, since it's best not to assume the user will feed the blocks into an sg list. - simple selftest so we don't have to guess. Cc: Niranjana Vishwanathapura Cc: Matthew Auld Cc: CQ Tang Signed-off-by: Venkata Sandeep Dhanalakota Signed-off-by: Matthew Auld Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130134721.54457-1-matthew.auld@intel.com --- drivers/gpu/drm/i915/gem/i915_gem_region.c | 2 +- drivers/gpu/drm/i915/intel_memory_region.c | 18 ++++++- drivers/gpu/drm/i915/intel_memory_region.h | 5 +- .../drm/i915/selftests/intel_memory_region.c | 51 +++++++++++++++++++ 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index 1515384d7e0e..e72d78074c9e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -42,7 +42,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) return -ENOMEM; } - flags = I915_ALLOC_MIN_PAGE_SIZE; + flags = I915_ALLOC_MIN_PAGE_SIZE | I915_ALLOC_MAX_SEGMENT_SIZE; if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) flags |= I915_ALLOC_CONTIGUOUS; diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index b326993a1026..ae36e2f6d6e3 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -72,6 +72,7 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem, struct list_head *blocks) { unsigned int min_order = 0; + unsigned int max_order; unsigned long n_pages; GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.chunk_size)); @@ -92,13 +93,28 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem, n_pages = size >> ilog2(mem->mm.chunk_size); + /* + * If we going to feed this into an sg list we should limit the block + * sizes such that we don't exceed the i915_sg_segment_size(). + */ + if (flags & I915_ALLOC_MAX_SEGMENT_SIZE) { + unsigned int max_segment = i915_sg_segment_size(); + + if (GEM_WARN_ON(max_segment < mem->mm.chunk_size)) + max_order = 0; + else + max_order = ilog2(max_segment) - ilog2(mem->mm.chunk_size); + } else { + max_order = mem->mm.max_order; + } + mutex_lock(&mem->mm_lock); do { struct i915_buddy_block *block; unsigned int order; - order = fls(n_pages) - 1; + order = min_t(u32, fls(n_pages) - 1, max_order); GEM_BUG_ON(order > mem->mm.max_order); GEM_BUG_ON(order < min_order); diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h index 232490d89a83..5fb9bcf86b97 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.h +++ b/drivers/gpu/drm/i915/intel_memory_region.h @@ -44,8 +44,9 @@ enum intel_region_id { #define MEMORY_TYPE_FROM_REGION(r) (ilog2((r) >> INTEL_MEMORY_TYPE_SHIFT)) #define MEMORY_INSTANCE_FROM_REGION(r) (ilog2((r) & 0xffff)) -#define I915_ALLOC_MIN_PAGE_SIZE BIT(0) -#define I915_ALLOC_CONTIGUOUS BIT(1) +#define I915_ALLOC_MIN_PAGE_SIZE BIT(0) +#define I915_ALLOC_CONTIGUOUS BIT(1) +#define I915_ALLOC_MAX_SEGMENT_SIZE BIT(2) #define for_each_memory_region(mr, i915, id) \ for (id = 0; id < ARRAY_SIZE((i915)->mm.regions); id++) \ diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 0aeba8e3af28..55ccd957a009 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -337,6 +337,56 @@ out_put: return err; } +#define SZ_8G BIT_ULL(33) + +static int igt_mock_max_segment(void *arg) +{ + struct intel_memory_region *mem = arg; + struct drm_i915_private *i915 = mem->i915; + struct drm_i915_gem_object *obj; + struct i915_buddy_block *block; + LIST_HEAD(objects); + u64 size; + int err = 0; + + /* + * The size of block are only limited by the largest power-of-two that + * will fit in the region size, but to construct an object we also + * require feeding it into an sg list, where the upper limit of the sg + * entry is at most UINT_MAX, therefore when allocating with + * I915_ALLOC_MAX_SEGMENT_SIZE we shouldn't see blocks larger than + * i915_sg_segment_size(). + */ + + size = SZ_8G; + mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0); + if (IS_ERR(mem)) + return PTR_ERR(mem); + + obj = igt_object_create(mem, &objects, size, 0); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto out_put; + } + + list_for_each_entry(block, &obj->mm.blocks, link) { + if (i915_buddy_block_size(&mem->mm, block) > i915_sg_segment_size()) { + pr_err("%s found block size(%llu) larger than max sg_segment_size(%u)", + __func__, + i915_buddy_block_size(&mem->mm, block), + i915_sg_segment_size()); + err = -EINVAL; + goto out_close; + } + } + +out_close: + close_objects(mem, &objects); +out_put: + intel_memory_region_put(mem); + return err; +} + static int igt_gpu_write_dw(struct intel_context *ce, struct i915_vma *vma, u32 dword, @@ -848,6 +898,7 @@ int intel_memory_region_mock_selftests(void) SUBTEST(igt_mock_fill), SUBTEST(igt_mock_contiguous), SUBTEST(igt_mock_splintered_region), + SUBTEST(igt_mock_max_segment), }; struct intel_memory_region *mem; struct drm_i915_private *i915; From cb2ce93e5b050fb9182eb6b6ff64428333436f73 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 27 Nov 2020 19:53:34 +0000 Subject: [PATCH 0079/5577] drm/i915/gem: Differentiate oom failures from invalid map types After a cursory check on the parameters to i915_gem_object_pin_map(), where we return a precise error, if the backend rejects the mapping we always return PTR_ERR(-ENOMEM). Let us also return a more precise error here so we can differentiate between running out of memory and programming errors (or situations where we may be trying different paths and looking for an error from an unsupported map). Signed-off-by: Chris Wilson Cc: Matthew Auld Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20201127195334.13134-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 26 +++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index e2c7b2a7895f..6dad9ea8eaa3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -238,7 +238,7 @@ unlock: /* The 'mapping' part of i915_gem_object_pin_map() below */ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, - enum i915_map_type type) + enum i915_map_type type) { unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i; struct page *stack[32], **pages = stack, *page; @@ -281,7 +281,7 @@ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, /* Too big for stack -- allocate temporary array instead */ pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); if (!pages) - return NULL; + return ERR_PTR(-ENOMEM); } i = 0; @@ -294,7 +294,7 @@ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, } static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, - enum i915_map_type type) + enum i915_map_type type) { resource_size_t iomap = obj->mm.region->iomap.base - obj->mm.region->region.start; @@ -305,13 +305,13 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, void *vaddr; if (type != I915_MAP_WC) - return NULL; + return ERR_PTR(-ENODEV); if (n_pfn > ARRAY_SIZE(stack)) { /* Too big for stack -- allocate temporary array instead */ pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL); if (!pfns) - return NULL; + return ERR_PTR(-ENOMEM); } i = 0; @@ -349,8 +349,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj)); err = ____i915_gem_object_get_pages(obj); - if (err) - goto err_unlock; + if (err) { + ptr = ERR_PTR(err); + goto out_unlock; + } smp_mb__before_atomic(); } @@ -362,7 +364,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, ptr = page_unpack_bits(obj->mm.mapping, &has_type); if (ptr && has_type != type) { if (pinned) { - err = -EBUSY; + ptr = ERR_PTR(-EBUSY); goto err_unpin; } @@ -374,15 +376,13 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, if (!ptr) { if (GEM_WARN_ON(type == I915_MAP_WC && !static_cpu_has(X86_FEATURE_PAT))) - ptr = NULL; + ptr = ERR_PTR(-ENODEV); else if (i915_gem_object_has_struct_page(obj)) ptr = i915_gem_object_map_page(obj, type); else ptr = i915_gem_object_map_pfn(obj, type); - if (!ptr) { - err = -ENOMEM; + if (IS_ERR(ptr)) goto err_unpin; - } obj->mm.mapping = page_pack_bits(ptr, type); } @@ -393,8 +393,6 @@ out_unlock: err_unpin: atomic_dec(&obj->mm.pages_pin_count); -err_unlock: - ptr = ERR_PTR(err); goto out_unlock; } From 288b23719ce0cfa56be33b96a33a44edeef45506 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:50 +0100 Subject: [PATCH 0080/5577] video: fbdev: aty: Delete unused variable in radeon_monitor Fix warning about variable that is asssigned a value but never used. The variable was indeed never used so delete it. Keep the call to radeon_probe_i2c_connector() as it may have side-effects. It is unlikely but I could not verify that is was safe to drop the call. Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Benjamin Herrenschmidt Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-5-sam@ravnborg.org --- drivers/video/fbdev/aty/radeon_monitor.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/video/fbdev/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c index 9966c58aa26c..df55e23b7a5a 100644 --- a/drivers/video/fbdev/aty/radeon_monitor.c +++ b/drivers/video/fbdev/aty/radeon_monitor.c @@ -488,12 +488,10 @@ void radeon_probe_screens(struct radeonfb_info *rinfo, #if defined(DEBUG) && defined(CONFIG_FB_RADEON_I2C) { u8 *EDIDs[4] = { NULL, NULL, NULL, NULL }; - int mon_types[4] = {MT_NONE, MT_NONE, MT_NONE, MT_NONE}; int i; for (i = 0; i < 4; i++) - mon_types[i] = radeon_probe_i2c_connector(rinfo, - i+1, &EDIDs[i]); + radeon_probe_i2c_connector(rinfo, i + 1, &EDIDs[i]); } #endif /* DEBUG */ /* From 580054562651ae4d7f731ba7f625123e0e3d965c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:51 +0100 Subject: [PATCH 0081/5577] video: fbdev: aty: Fix set but not used warnings Fix W=1 warnings about variables assigned but never used. - Drop variables that were set but never used - Make variable definition conditional on ATARI v2: - Fix m68k build error (kernel test robot) - Improve subject (Lee Jones) Signed-off-by: Sam Ravnborg Reported-by: kernel test robot # m68k build fix Acked-by: Thomas Zimmermann Cc: Lee Jones Cc: Bartlomiej Zolnierkiewicz Cc: Sam Ravnborg Cc: Daniel Vetter Cc: Joe Perches Cc: Vaibhav Gupta Cc: Jason Yan Cc: Randy Dunlap Cc: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-6-sam@ravnborg.org --- drivers/video/fbdev/aty/atyfb_base.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index c8feff0ee8da..83c8e809955a 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -2353,6 +2353,9 @@ static int aty_init(struct fb_info *info) int gtb_memsize, has_var = 0; struct fb_var_screeninfo var; int ret; +#ifdef CONFIG_ATARI + u8 dac_type; +#endif init_waitqueue_head(&par->vblank.wait); spin_lock_init(&par->int_lock); @@ -2360,13 +2363,12 @@ static int aty_init(struct fb_info *info) #ifdef CONFIG_FB_ATY_GX if (!M64_HAS(INTEGRATED)) { u32 stat0; - u8 dac_type, dac_subtype, clk_type; + u8 dac_subtype, clk_type; stat0 = aty_ld_le32(CNFG_STAT0, par); par->bus_type = (stat0 >> 0) & 0x07; par->ram_type = (stat0 >> 3) & 0x07; ramname = aty_gx_ram[par->ram_type]; /* FIXME: clockchip/RAMDAC probing? */ - dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07; #ifdef CONFIG_ATARI clk_type = CLK_ATI18818_1; dac_type = (stat0 >> 9) & 0x07; @@ -2375,7 +2377,6 @@ static int aty_init(struct fb_info *info) else dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type; #else - dac_type = DAC_IBMRGB514; dac_subtype = DAC_IBMRGB514; clk_type = CLK_IBMRGB514; #endif @@ -3062,7 +3063,6 @@ static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, if (dp == of_console_device) { struct fb_var_screeninfo *var = &default_var; unsigned int N, P, Q, M, T, R; - u32 v_total, h_total; struct crtc crtc; u8 pll_regs[16]; u8 clock_cntl; @@ -3078,9 +3078,6 @@ static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); aty_crtc_to_var(&crtc, var); - h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin; - v_total = var->yres + var->lower_margin + var->vsync_len + var->upper_margin; - /* * Read the PLL to figure actual Refresh Rate. */ From 055646137637b627b6d1b8f033f7defef14a4c00 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:52 +0100 Subject: [PATCH 0082/5577] video: fbdev: aty: Fix set but not used warnings in mach64_ct Fix W=1 warnings about variables assigned but never used. - One variable is only used when CONFIG_FB_ATY_GENERIC_LCD is defined Fix so variable is only defined with CONFIG_FB_ATY_GENERIC_LCD - Several variables was only assigned by a call to aty_ld_le32(). Drop the variables but keep the call to aty_ld_le32() as it may have unexpected side-effects. v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-7-sam@ravnborg.org --- drivers/video/fbdev/aty/mach64_ct.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c index f87cc81f4fa2..011b07e44e0d 100644 --- a/drivers/video/fbdev/aty/mach64_ct.c +++ b/drivers/video/fbdev/aty/mach64_ct.c @@ -281,10 +281,13 @@ static u32 aty_pll_to_var_ct(const struct fb_info *info, const union aty_pll *pl void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll) { struct atyfb_par *par = (struct atyfb_par *) info->par; - u32 crtc_gen_cntl, lcd_gen_cntrl; + u32 crtc_gen_cntl; u8 tmp, tmp2; - lcd_gen_cntrl = 0; +#ifdef CONFIG_FB_ATY_GENERIC_LCD + u32 lcd_gen_cntrl = 0; +#endif + #ifdef DEBUG printk("atyfb(%s): about to program:\n" "pll_ext_cntl=0x%02x pll_gen_cntl=0x%02x pll_vclk_cntl=0x%02x\n", @@ -402,7 +405,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll) struct atyfb_par *par = (struct atyfb_par *) info->par; u8 mpost_div, xpost_div, sclk_post_div_real; u32 q, memcntl, trp; - u32 dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off; + u32 dsp_config; #ifdef DEBUG int pllmclk, pllsclk; #endif @@ -488,9 +491,9 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll) /* Allow BIOS to override */ dsp_config = aty_ld_le32(DSP_CONFIG, par); - dsp_on_off = aty_ld_le32(DSP_ON_OFF, par); - vga_dsp_config = aty_ld_le32(VGA_DSP_CONFIG, par); - vga_dsp_on_off = aty_ld_le32(VGA_DSP_ON_OFF, par); + aty_ld_le32(DSP_ON_OFF, par); + aty_ld_le32(VGA_DSP_CONFIG, par); + aty_ld_le32(VGA_DSP_ON_OFF, par); if (dsp_config) pll->ct.dsp_loop_latency = (dsp_config & DSP_LOOP_LATENCY) >> 16; From 50b82a2d695753013cc83d70cbd328c6a507c1bf Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:53 +0100 Subject: [PATCH 0083/5577] video: fbdev: sis: Fix defined but not used warnings init.h defines static symbols, so it should only be included once. Drop the include from sis.h as it is not needed. This fixes a lot of warnings seen with a W=1 build. v2: - Update subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Thomas Winischhofer Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-8-sam@ravnborg.org --- drivers/video/fbdev/sis/sis.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/sis/sis.h b/drivers/video/fbdev/sis/sis.h index 9f4c3093ccb3..d632f096083b 100644 --- a/drivers/video/fbdev/sis/sis.h +++ b/drivers/video/fbdev/sis/sis.h @@ -15,7 +15,6 @@ #include "vgatypes.h" #include "vstruct.h" -#include "init.h" #define VER_MAJOR 1 #define VER_MINOR 8 From e8a254362de604f2988f5b843e96b0745246e78a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:54 +0100 Subject: [PATCH 0084/5577] video: fbdev: sis: Fix defined but not used warning of SiS_TVDelay Fix W=1 warning by commenting unused SiS_TVDelay* variables. The SiS_TVDelay* variables seem to contain some magic numbers so looks like data worth keeping around but not as code we build. v2: - Update subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Thomas Winischhofer Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-9-sam@ravnborg.org --- drivers/video/fbdev/sis/oem310.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/sis/oem310.h b/drivers/video/fbdev/sis/oem310.h index 8fce56e4482c..ed28755715ce 100644 --- a/drivers/video/fbdev/sis/oem310.h +++ b/drivers/video/fbdev/sis/oem310.h @@ -200,6 +200,7 @@ static const unsigned char SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 0x33,0x33 }; +#if 0 /* Not used */ static const unsigned char SiS_TVDelay661_301[] = /* 661, 301 */ { 0x44,0x44, @@ -219,6 +220,7 @@ static const unsigned char SiS_TVDelay661_301B[] = /* 661, 301B et al */ 0x44,0x44, 0x44,0x44 }; +#endif static const unsigned char SiS310_TVDelayCompensation_LVDS[] = /* LVDS */ { From 2a74e8682a39d00e04ca278459ae7d7ecbdfb394 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:55 +0100 Subject: [PATCH 0085/5577] video: fbdev: sis: Fix set but not used warnings in init.c Fix "set but not used" warnings by removing the code the assign the variables and the definition of the variables. A register read is kept as it may have unknown side-effects. This removes a lot of unused code - which is always a good thing to do. v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Thomas Winischhofer Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-10-sam@ravnborg.org --- drivers/video/fbdev/sis/init.c | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/video/fbdev/sis/init.c b/drivers/video/fbdev/sis/init.c index fde27feae5d0..b77ea1a8825a 100644 --- a/drivers/video/fbdev/sis/init.c +++ b/drivers/video/fbdev/sis/init.c @@ -2648,7 +2648,7 @@ static void SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI) { - unsigned short data, infoflag = 0, modeflag, resindex; + unsigned short data, infoflag = 0, modeflag; #ifdef CONFIG_FB_SIS_315 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; unsigned short data2, data3; @@ -2659,7 +2659,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, if(SiS_Pr->UseCustomMode) { infoflag = SiS_Pr->CInfoFlag; } else { - resindex = SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex); + SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex); if(ModeNo > 0x13) { infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag; } @@ -3538,17 +3538,13 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, struct fb_var_screeninfo *var, bool writeres ) { - unsigned short HRE, HBE, HRS, HBS, HDE, HT; - unsigned short VRE, VBE, VRS, VBS, VDE, VT; - unsigned char sr_data, cr_data, cr_data2; - int A, B, C, D, E, F, temp; + unsigned short HRE, HBE, HRS, HDE; + unsigned short VRE, VBE, VRS, VDE; + unsigned char sr_data, cr_data; + int B, C, D, E, F, temp; sr_data = crdata[14]; - /* Horizontal total */ - HT = crdata[0] | ((unsigned short)(sr_data & 0x03) << 8); - A = HT + 5; - /* Horizontal display enable end */ HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6); E = HDE + 1; @@ -3557,9 +3553,6 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2); F = HRS - E - 3; - /* Horizontal blank start */ - HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4); - sr_data = crdata[15]; cr_data = crdata[5]; @@ -3588,13 +3581,6 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, sr_data = crdata[13]; cr_data = crdata[7]; - /* Vertical total */ - VT = crdata[6] | - ((unsigned short)(cr_data & 0x01) << 8) | - ((unsigned short)(cr_data & 0x20) << 4) | - ((unsigned short)(sr_data & 0x01) << 10); - A = VT + 2; - /* Vertical display enable end */ VDE = crdata[10] | ((unsigned short)(cr_data & 0x02) << 7) | @@ -3609,14 +3595,6 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, ((unsigned short)(sr_data & 0x08) << 7); F = VRS + 1 - E; - cr_data2 = (crdata[16] & 0x01) << 5; - - /* Vertical blank start */ - VBS = crdata[11] | - ((unsigned short)(cr_data & 0x08) << 5) | - ((unsigned short)(cr_data2 & 0x20) << 4) | - ((unsigned short)(sr_data & 0x04) << 8); - /* Vertical blank end */ VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4); temp = VBE - ((E - 1) & 511); From 1a608758df9eef2237fde69acf6a156e8a8aaa6d Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:56 +0100 Subject: [PATCH 0086/5577] video: fbdev: sis: Fix set but not used warnings in sis_main Fix warnings by dropping unused variable and the unused assignments. v2: - Update subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Thomas Winischhofer Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-11-sam@ravnborg.org --- drivers/video/fbdev/sis/sis_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 03c736f6f3d0..266a5582f94d 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c @@ -5029,7 +5029,6 @@ static void sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb) static const u8 cs168[8] = { 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u8 reg; u8 v1; u8 v2; u8 v3; @@ -5037,9 +5036,9 @@ static void sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb) SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */ SiS_SetReg(SISCR, 0x82, 0x77); SiS_SetReg(SISCR, 0x86, 0x00); - reg = SiS_GetReg(SISCR, 0x86); + SiS_GetReg(SISCR, 0x86); SiS_SetReg(SISCR, 0x86, 0x88); - reg = SiS_GetReg(SISCR, 0x86); + SiS_GetReg(SISCR, 0x86); v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb]; if (ivideo->haveXGIROM) { v1 = bios[regb + 0x168]; @@ -5049,9 +5048,9 @@ static void sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb) SiS_SetReg(SISCR, 0x86, v1); SiS_SetReg(SISCR, 0x82, 0x77); SiS_SetReg(SISCR, 0x85, 0x00); - reg = SiS_GetReg(SISCR, 0x85); + SiS_GetReg(SISCR, 0x85); SiS_SetReg(SISCR, 0x85, 0x88); - reg = SiS_GetReg(SISCR, 0x85); + SiS_GetReg(SISCR, 0x85); SiS_SetReg(SISCR, 0x85, v2); SiS_SetReg(SISCR, 0x82, v3); SiS_SetReg(SISCR, 0x98, 0x01); From 9403c18953f787d879e8170256add1a71aed867a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:57 +0100 Subject: [PATCH 0087/5577] video: fbdev: via: Fix set but not used warning for mode_crt_table Fix warning by deleting the variable. The function call viafb_get_best_mode() was verified to have no side-effects, and thus could be dropped too. v2: - Update subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Florian Tobias Schandinat Cc: linux-fbdev@vger.kernel.org Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-12-sam@ravnborg.org --- drivers/video/fbdev/via/lcd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/video/fbdev/via/lcd.c b/drivers/video/fbdev/via/lcd.c index 4a869402d120..088b962076b5 100644 --- a/drivers/video/fbdev/via/lcd.c +++ b/drivers/video/fbdev/via/lcd.c @@ -537,11 +537,9 @@ void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres, u32 clock; struct via_display_timing timing; struct fb_var_screeninfo panel_var; - const struct fb_videomode *mode_crt_table, *panel_crt_table; + const struct fb_videomode *panel_crt_table; DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n"); - /* Get mode table */ - mode_crt_table = viafb_get_best_mode(set_hres, set_vres, 60); /* Get panel table Pointer */ panel_crt_table = viafb_get_best_mode(panel_hres, panel_vres, 60); viafb_fill_var_timing_info(&panel_var, panel_crt_table); From f686b34c9364a89a0964b8f78bbd4561cd2e97ac Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:58 +0100 Subject: [PATCH 0088/5577] video: fbdev: tdfx: Fix set but not used warning in att_outb() The tmp variable was assigned but the result was never used, so delete the tmp variable. v2: - Update subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: "Gustavo A. R. Silva" Cc: Sam Ravnborg Cc: Jani Nikula Cc: Daniel Vetter Cc: Arnd Bergmann Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-13-sam@ravnborg.org --- drivers/video/fbdev/tdfxfb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c index f056d80f6359..67e37a62b07c 100644 --- a/drivers/video/fbdev/tdfxfb.c +++ b/drivers/video/fbdev/tdfxfb.c @@ -206,9 +206,7 @@ static inline u8 crt_inb(struct tdfx_par *par, u32 idx) static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val) { - unsigned char tmp; - - tmp = vga_inb(par, IS1_R); + vga_inb(par, IS1_R); vga_outb(par, ATT_IW, idx); vga_outb(par, ATT_IW, val); } From 5c7ddcc801d7c19119c54ae420c90f0aa7b8c485 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:40:59 +0100 Subject: [PATCH 0089/5577] video: fbdev: riva: Fix kernel-doc and set but not used warnings Fix W=1 warnings: - Fix kernel-doc - Drop unused variables/code v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Antonino Daplas Cc: linux-fbdev@vger.kernel.org Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-14-sam@ravnborg.org --- drivers/video/fbdev/riva/fbdev.c | 9 ++++----- drivers/video/fbdev/riva/riva_hw.c | 28 ++++++++-------------------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index ce55b9d2e862..55554b0433cb 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -464,7 +464,7 @@ static inline void reverse_order(u32 *l) /** * rivafb_load_cursor_image - load cursor image to hardware - * @data: address to monochrome bitmap (1 = foreground color, 0 = background) + * @data8: address to monochrome bitmap (1 = foreground color, 0 = background) * @par: pointer to private data * @w: width of cursor image in pixels * @h: height of cursor image in scanlines @@ -843,9 +843,9 @@ static void riva_update_var(struct fb_var_screeninfo *var, /** * rivafb_do_maximize - * @info: pointer to fb_info object containing info for current riva board - * @var: - * @nom: - * @den: + * @var: standard kernel fb changeable data + * @nom: nom + * @den: den * * DESCRIPTION: * . @@ -1214,7 +1214,6 @@ out: /** * rivafb_pan_display * @var: standard kernel fb changeable data - * @con: TODO * @info: pointer to fb_info object containing info for current riva board * * DESCRIPTION: diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c index bcf9c4b4de31..8b829b720064 100644 --- a/drivers/video/fbdev/riva/riva_hw.c +++ b/drivers/video/fbdev/riva/riva_hw.c @@ -836,17 +836,17 @@ static void nv10CalcArbitration nv10_sim_state *arb ) { - int data, pagemiss, cas,width, video_enable, bpp; - int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs; - int nvclk_fill, us_extra; + int data, pagemiss, width, video_enable, bpp; + int nvclks, mclks, pclks, vpagemiss, crtpagemiss; + int nvclk_fill; int found, mclk_extra, mclk_loop, cbs, m1; int mclk_freq, pclk_freq, nvclk_freq, mp_enable; - int us_m, us_m_min, us_n, us_p, video_drain_rate, crtc_drain_rate; - int vus_m, vus_n, vus_p; - int vpm_us, us_video, vlwm, cpm_us, us_crt,clwm; + int us_m, us_m_min, us_n, us_p, crtc_drain_rate; + int vus_m; + int vpm_us, us_video, cpm_us, us_crt,clwm; int clwm_rnd_down; - int craw, m2us, us_pipe, us_pipe_min, vus_pipe, p1clk, p2; - int pclks_2_top_fifo, min_mclk_extra; + int m2us, us_pipe_min, p1clk, p2; + int min_mclk_extra; int us_min_mclk_extra; fifo->valid = 1; @@ -854,16 +854,13 @@ static void nv10CalcArbitration mclk_freq = arb->mclk_khz; nvclk_freq = arb->nvclk_khz; pagemiss = arb->mem_page_miss; - cas = arb->mem_latency; width = arb->memory_width/64; video_enable = arb->enable_video; bpp = arb->pix_bpp; mp_enable = arb->enable_mp; clwm = 0; - vlwm = 1024; cbs = 512; - vbs = 512; pclks = 4; /* lwm detect. */ @@ -924,17 +921,11 @@ static void nv10CalcArbitration us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq; us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */ us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */ - us_pipe = us_m + us_n + us_p; us_pipe_min = us_m_min + us_n + us_p; - us_extra = 0; vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */ - vus_n = (4)*1000*1000 / nvclk_freq;/* nvclk latency in us */ - vus_p = 0*1000*1000 / pclk_freq;/* pclk latency in us */ - vus_pipe = vus_m + vus_n + vus_p; if(video_enable) { - video_drain_rate = pclk_freq * 4; /* MB/s */ crtc_drain_rate = pclk_freq * bpp/8; /* MB/s */ vpagemiss = 1; /* self generating page miss */ @@ -993,7 +984,6 @@ static void nv10CalcArbitration else if(crtc_drain_rate * 100 >= nvclk_fill * 98) { clwm = 1024; cbs = 512; - us_extra = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ; } } } @@ -1010,7 +1000,6 @@ static void nv10CalcArbitration m1 = clwm + cbs - 1024; /* Amount of overfill */ m2us = us_pipe_min + us_min_mclk_extra; - pclks_2_top_fifo = (1024-clwm)/(8*width); /* pclk cycles to drain */ p1clk = m2us * pclk_freq/(1000*1000); @@ -1038,7 +1027,6 @@ static void nv10CalcArbitration min_mclk_extra--; } } - craw = clwm; if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8; data = (int)(clwm); From b47e6ca3c0d570cc74557fb2da3d3d8fa62a3960 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:00 +0100 Subject: [PATCH 0090/5577] video: fbdev: pm2fb: Fix kernel-doc warnings Fixed a few kernel-doc issues to fix the warnings. v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Sam Ravnborg Cc: "Gustavo A. R. Silva" Cc: Randy Dunlap Cc: Arnd Bergmann Cc: Bartlomiej Zolnierkiewicz Cc: Jani Nikula Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-15-sam@ravnborg.org --- drivers/video/fbdev/pm2fb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c index 27893fa139b0..c68725eebee3 100644 --- a/drivers/video/fbdev/pm2fb.c +++ b/drivers/video/fbdev/pm2fb.c @@ -1508,8 +1508,8 @@ static const struct fb_ops pm2fb_ops = { * * Initialise and allocate resource for PCI device. * - * @param pdev PCI device. - * @param id PCI device ID. + * @pdev: PCI device. + * @id: PCI device ID. */ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -1715,7 +1715,7 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id) * * Release all device resources. * - * @param pdev PCI device to clean up. + * @pdev: PCI device to clean up. */ static void pm2fb_remove(struct pci_dev *pdev) { @@ -1756,7 +1756,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table); #ifndef MODULE -/** +/* * Parse user specified options. * * This is, comma-separated options following `video=pm2fb:'. From 2f71315eaae7b5be294dcd5bb5fe6df3d497cdc1 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:03 +0100 Subject: [PATCH 0091/5577] video: fbdev: tgafb: Fix kernel-doc and set but not used warnings Fix W=1 warnings: - Fix kernel-doc - Drop unused code v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Sam Ravnborg Cc: Jani Nikula Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Arnd Bergmann Cc: Joe Perches Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-18-sam@ravnborg.org --- drivers/video/fbdev/tgafb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c index 666fbe2f671c..ae0cf5540636 100644 --- a/drivers/video/fbdev/tgafb.c +++ b/drivers/video/fbdev/tgafb.c @@ -555,7 +555,7 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, /** * tgafb_blank - Optional function. Blanks the display. - * @blank_mode: the blank mode we want. + * @blank: the blank mode we want. * @info: frame buffer structure that represents a single frame buffer */ static int @@ -837,7 +837,7 @@ tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image) u32 *palette = ((u32 *)info->pseudo_palette); unsigned long pos, line_length, i, j; const unsigned char *data; - void __iomem *regs_base, *fb_base; + void __iomem *fb_base; dx = image->dx; dy = image->dy; @@ -855,7 +855,6 @@ tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image) if (dy + height > vyres) height = vyres - dy; - regs_base = par->tga_regs_base; fb_base = par->tga_fb_base; pos = dy * line_length + (dx * 4); @@ -1034,7 +1033,7 @@ tgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) regs_base + TGA_MODE_REG); } -/** +/* * tgafb_copyarea - REQUIRED function. Can use generic routines if * non acclerated hardware and packed pixel based. * Copies on area of the screen to another area. From 9b028f48e72d31189819eb9989fbfef905d97402 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:04 +0100 Subject: [PATCH 0092/5577] video: fbdev: mx3fb: Fix kernel-doc, set but not used and string warnings Fix W=1 warnings: - Fix kernel-doc - Drop unused code/variables - Use memcpy to copy a string without zero-termination strncpy() generates a warning v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Sam Ravnborg Cc: Jani Nikula Cc: Laurent Pinchart Cc: Daniel Vetter Cc: Xiaofei Tan Cc: Arnd Bergmann Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-19-sam@ravnborg.org --- drivers/video/fbdev/mx3fb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index 894617ddabcb..fabb271337ed 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -445,7 +445,6 @@ static void sdc_enable_channel(struct mx3fb_info *mx3_fbi) static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) { struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - uint32_t enabled; unsigned long flags; if (mx3_fbi->txd == NULL) @@ -453,7 +452,7 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) spin_lock_irqsave(&mx3fb->lock, flags); - enabled = sdc_fb_uninit(mx3_fbi); + sdc_fb_uninit(mx3_fbi); spin_unlock_irqrestore(&mx3fb->lock, flags); @@ -732,7 +731,7 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi); /** * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings. - * @info: framebuffer information pointer + * @fbi: framebuffer information pointer * @return: 0 on success or negative error code on failure. */ static int mx3fb_set_fix(struct fb_info *fbi) @@ -740,7 +739,7 @@ static int mx3fb_set_fix(struct fb_info *fbi) struct fb_fix_screeninfo *fix = &fbi->fix; struct fb_var_screeninfo *var = &fbi->var; - strncpy(fix->id, "DISP3 BG", 8); + memcpy(fix->id, "DISP3 BG", 8); fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; @@ -1105,6 +1104,8 @@ static void __blank(int blank, struct fb_info *fbi) /** * mx3fb_blank() - blank the display. + * @blank: blank value for the panel + * @fbi: framebuffer information pointer */ static int mx3fb_blank(int blank, struct fb_info *fbi) { @@ -1126,7 +1127,7 @@ static int mx3fb_blank(int blank, struct fb_info *fbi) /** * mx3fb_pan_display() - pan or wrap the display * @var: variable screen buffer information. - * @info: framebuffer information pointer. + * @fbi: framebuffer information pointer. * * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag */ @@ -1387,6 +1388,8 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi) /** * mx3fb_init_fbinfo() - initialize framebuffer information object. + * @dev: the device + * @ops: framebuffer device operations * @return: initialized framebuffer structure. */ static struct fb_info *mx3fb_init_fbinfo(struct device *dev, From 57e4bc8a48dd751eacae80b5ea3b0f08dd3452b0 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:05 +0100 Subject: [PATCH 0093/5577] video: fbdev: sstfb: Updated logging to fix set but not used warnings Fix set but not used warnings by introducing no_printk variants for the internal logging system for this driver. Fix a new warning that popped up now that logging was checked for correct printf format strings. A more invasive fix had been to replace all the internal logging with standard logging primitives - thats for another day. v2: - Update subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Sam Ravnborg Cc: Daniel Vetter Cc: Arnd Bergmann Cc: Bartlomiej Zolnierkiewicz Cc: Alex Dewar Cc: Jani Nikula Cc: linux-fbdev@vger.kernel.org Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-20-sam@ravnborg.org --- drivers/video/fbdev/sstfb.c | 2 +- include/video/sstfb.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/sstfb.c b/drivers/video/fbdev/sstfb.c index c05cdabeb11c..27d4b0ace2d6 100644 --- a/drivers/video/fbdev/sstfb.c +++ b/drivers/video/fbdev/sstfb.c @@ -1390,7 +1390,7 @@ static int sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) fix->smem_start, info->screen_base, fix->smem_len >> 20); - f_ddprintk("regbase_virt: %#lx\n", par->mmio_vbase); + f_ddprintk("regbase_virt: %p\n", par->mmio_vbase); f_ddprintk("membase_phys: %#lx\n", fix->smem_start); f_ddprintk("fbbase_virt: %p\n", info->screen_base); diff --git a/include/video/sstfb.h b/include/video/sstfb.h index 28384f354773..d4a5e41d1173 100644 --- a/include/video/sstfb.h +++ b/include/video/sstfb.h @@ -23,7 +23,7 @@ # define SST_DEBUG_FUNC 1 # define SST_DEBUG_VAR 1 #else -# define dprintk(X...) +# define dprintk(X...) no_printk(X) # define SST_DEBUG_REG 0 # define SST_DEBUG_FUNC 0 # define SST_DEBUG_VAR 0 @@ -48,7 +48,7 @@ #if (SST_DEBUG_FUNC > 1) # define f_ddprintk(X...) dprintk(" " X) #else -# define f_ddprintk(X...) +# define f_ddprintk(X...) no_printk(X) #endif #if (SST_DEBUG_FUNC > 2) # define f_dddprintk(X...) dprintk(" " X) From 4e4b1d92e24eafafb25e0008bc73bb2242f81a8b Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:01 +0100 Subject: [PATCH 0094/5577] video: fbdev: neofb: Fix set but not used warning for CursorMem Fix W=1 warnings by removing unused code v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Bartlomiej Zolnierkiewicz Cc: Sam Ravnborg Cc: Andrew Morton Cc: Evgeny Novikov Cc: Jani Nikula Cc: Mike Rapoport Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-16-sam@ravnborg.org --- drivers/video/fbdev/neofb.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c index 09a20d4ab35f..c0f4f402da3f 100644 --- a/drivers/video/fbdev/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -1843,7 +1843,6 @@ static int neo_init_hw(struct fb_info *info) struct neofb_par *par = info->par; int videoRam = 896; int maxClock = 65000; - int CursorMem = 1024; int CursorOff = 0x100; DBG("neo_init_hw"); @@ -1895,19 +1894,16 @@ static int neo_init_hw(struct fb_info *info) case FB_ACCEL_NEOMAGIC_NM2070: case FB_ACCEL_NEOMAGIC_NM2090: case FB_ACCEL_NEOMAGIC_NM2093: - CursorMem = 2048; CursorOff = 0x100; break; case FB_ACCEL_NEOMAGIC_NM2097: case FB_ACCEL_NEOMAGIC_NM2160: - CursorMem = 1024; CursorOff = 0x100; break; case FB_ACCEL_NEOMAGIC_NM2200: case FB_ACCEL_NEOMAGIC_NM2230: case FB_ACCEL_NEOMAGIC_NM2360: case FB_ACCEL_NEOMAGIC_NM2380: - CursorMem = 1024; CursorOff = 0x1000; par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase; From 025ae8255d3390e5d22c42f380e60080366272fc Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:06 +0100 Subject: [PATCH 0095/5577] video: fbdev: nvidia: Fix set but not used warnings Fix warnings by deleting unused code. The register reads are kept as it is unknown if there are any hidden side-effects. v2: - Update subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Antonino Daplas Cc: linux-fbdev@vger.kernel.org Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-21-sam@ravnborg.org --- drivers/video/fbdev/nvidia/nv_setup.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c index 2fa68669613a..5404017e6957 100644 --- a/drivers/video/fbdev/nvidia/nv_setup.c +++ b/drivers/video/fbdev/nvidia/nv_setup.c @@ -89,9 +89,8 @@ u8 NVReadSeq(struct nvidia_par *par, u8 index) } void NVWriteAttr(struct nvidia_par *par, u8 index, u8 value) { - volatile u8 tmp; - tmp = VGA_RD08(par->PCIO, par->IOBase + 0x0a); + VGA_RD08(par->PCIO, par->IOBase + 0x0a); if (par->paletteEnabled) index &= ~0x20; else @@ -101,9 +100,7 @@ void NVWriteAttr(struct nvidia_par *par, u8 index, u8 value) } u8 NVReadAttr(struct nvidia_par *par, u8 index) { - volatile u8 tmp; - - tmp = VGA_RD08(par->PCIO, par->IOBase + 0x0a); + VGA_RD08(par->PCIO, par->IOBase + 0x0a); if (par->paletteEnabled) index &= ~0x20; else From fa5d598b8cbab0af92bac48fd60e74a893550923 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 26 Nov 2020 12:51:55 +0200 Subject: [PATCH 0096/5577] drm/i915/perf: also include Gen11 in OATAILPTR workaround CI shows this workaround is also needed on Gen11. Signed-off-by: Lionel Landwerlin Fixes: 059a0beb486344 ("drm/i915/perf: workaround register corruption in OATAILPTR") Reviewed-by: Umesh Nerlige Ramappa Link: https://patchwork.freedesktop.org/patch/msgid/20201126105155.540350-1-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/i915/i915_perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 3640d0e229d2..acdfbe5344a4 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -913,7 +913,7 @@ static int gen8_oa_read(struct i915_perf_stream *stream, intel_uncore_rmw(uncore, oastatus_reg, GEN8_OASTATUS_COUNTER_OVERFLOW | GEN8_OASTATUS_REPORT_LOST, - IS_GEN_RANGE(uncore->i915, 8, 10) ? + IS_GEN_RANGE(uncore->i915, 8, 11) ? (GEN8_OASTATUS_HEAD_POINTER_WRAP | GEN8_OASTATUS_TAIL_POINTER_WRAP) : 0); } From 868b5626d0b9203a8f4e89b0ff91a0aa716b2e49 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:52 +0200 Subject: [PATCH 0097/5577] drm/i915/debugfs: remove RPS autotuning details from i915_rps_boost_info The information is no longer relevant, so remove it. This also removes the last users of I915_READ_FW() Cc: Chris Wilson Suggested-by: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 37 ----------------------------- 1 file changed, 37 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 200f6b86f864..cc8b9a28aa07 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1193,20 +1193,6 @@ static int i915_swizzle_info(struct seq_file *m, void *data) return 0; } -static const char *rps_power_to_str(unsigned int power) -{ - static const char * const strings[] = { - [LOW_POWER] = "low power", - [BETWEEN] = "mixed", - [HIGH_POWER] = "high power", - }; - - if (power >= ARRAY_SIZE(strings) || !strings[power]) - return "unknown"; - - return strings[power]; -} - static int i915_rps_boost_info(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -1233,29 +1219,6 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) seq_printf(m, "Wait boosts: %d\n", atomic_read(&rps->boosts)); - if (INTEL_GEN(dev_priv) >= 6 && intel_rps_is_active(rps)) { - u32 rpup, rpupei; - u32 rpdown, rpdownei; - - intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL); - rpup = I915_READ_FW(GEN6_RP_CUR_UP) & GEN6_RP_EI_MASK; - rpupei = I915_READ_FW(GEN6_RP_CUR_UP_EI) & GEN6_RP_EI_MASK; - rpdown = I915_READ_FW(GEN6_RP_CUR_DOWN) & GEN6_RP_EI_MASK; - rpdownei = I915_READ_FW(GEN6_RP_CUR_DOWN_EI) & GEN6_RP_EI_MASK; - intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); - - seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n", - rps_power_to_str(rps->power.mode)); - seq_printf(m, " Avg. up: %d%% [above threshold? %d%%]\n", - rpup && rpupei ? 100 * rpup / rpupei : 0, - rps->power.up_threshold); - seq_printf(m, " Avg. down: %d%% [below threshold? %d%%]\n", - rpdown && rpdownei ? 100 * rpdown / rpdownei : 0, - rps->power.down_threshold); - } else { - seq_puts(m, "\nRPS Autotuning inactive\n"); - } - return 0; } From 669f3f2bac1ca6ad887419f63ac5430e9ea85e6a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:53 +0200 Subject: [PATCH 0098/5577] drm/i915: remove last traces of I915_READ_FW() and I915_WRITE_FW() Good riddance! Remove the macros and their remaining references in comments. intel_uncore_read_fw() and intel_uncore_write_fw() should be used instead. Reviewed-by: Rodrigo Vivi Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 29 ----------------------------- drivers/gpu/drm/i915/intel_uncore.c | 2 +- drivers/gpu/drm/i915/intel_uncore.h | 2 +- 3 files changed, 2 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bfc8e4575e69..25af27e38764 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1979,35 +1979,6 @@ int i915_reg_read_ioctl(struct drm_device *dev, void *data, #define POSTING_READ(reg__) __I915_REG_OP(posting_read, dev_priv, (reg__)) -/* These are untraced mmio-accessors that are only valid to be used inside - * critical sections, such as inside IRQ handlers, where forcewake is explicitly - * controlled. - * - * Think twice, and think again, before using these. - * - * As an example, these accessors can possibly be used between: - * - * spin_lock_irq(&dev_priv->uncore.lock); - * intel_uncore_forcewake_get__locked(); - * - * and - * - * intel_uncore_forcewake_put__locked(); - * spin_unlock_irq(&dev_priv->uncore.lock); - * - * - * Note: some registers may not need forcewake held, so - * intel_uncore_forcewake_{get,put} can be omitted, see - * intel_uncore_forcewake_for_reg(). - * - * Certain architectures will die if the same cacheline is concurrently accessed - * by different clients (e.g. on Ivybridge). Access to registers should - * therefore generally be serialised, by either the dev_priv->uncore.lock or - * a more localised lock guarding all access to that bank of registers. - */ -#define I915_READ_FW(reg__) __I915_REG_OP(read_fw, dev_priv, (reg__)) -#define I915_WRITE_FW(reg__, val__) __I915_REG_OP(write_fw, dev_priv, (reg__), (val__)) - /* i915_mm.c */ int remap_io_mapping(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 1c14a07eba7d..ef40edfff412 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -2070,7 +2070,7 @@ int i915_reg_read_ioctl(struct drm_device *dev, * This routine waits until the target register @reg contains the expected * @value after applying the @mask, i.e. it waits until :: * - * (I915_READ_FW(reg) & mask) == value + * (intel_uncore_read_fw(uncore, reg) & mask) == value * * Otherwise, the wait will timeout after @slow_timeout_ms milliseconds. * For atomic context @slow_timeout_ms must be zero and @fast_timeout_us diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index bd2467284295..5dcb7f4183b2 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -216,7 +216,7 @@ void intel_uncore_forcewake_flush(struct intel_uncore *uncore, /* * Like above but the caller must manage the uncore.lock itself. - * Must be used with I915_READ_FW and friends. + * Must be used with intel_uncore_read_fw() and friends. */ void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore, enum forcewake_domains domains); From 507007fb591b23a0f9ad5ed62e2d60a004410ccb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:54 +0200 Subject: [PATCH 0099/5577] drm/i915/cdclk: prefer intel_de_write() over I915_WRITE() Let's try to not add new ones while we're phasing out I915_READ() and I915_WRITE(). Fixes: 27a6bc802bd9 ("drm/i915/dg1: Initialize RAWCLK properly") Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-3-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index c449d28d0560..088d5908176c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2710,8 +2710,8 @@ static int dg1_rawclk(struct drm_i915_private *dev_priv) * DG1 always uses a 38.4 MHz rawclk. The bspec tells us * "Program Numerator=2, Denominator=4, Divider=37 decimal." */ - I915_WRITE(PCH_RAWCLK_FREQ, - CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2)); + intel_de_write(dev_priv, PCH_RAWCLK_FREQ, + CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2)); return 38400; } From 88d570e030dddb6bd80b61bd6380fe106e11815b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:55 +0200 Subject: [PATCH 0100/5577] drm/i915/debugfs: remove the i915_cache_sharing debugfs file The i915_cache_sharing file is a debugfs interface for gen 6-7 with no validation or user. Remove it. This also removes the last I915_WRITE() use in i915_debugfs.c. Suggested-by: Chris Wilson Cc: Chris Wilson Cc: Rodrigo Vivi Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-4-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 50 ----------------------------- 1 file changed, 50 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index cc8b9a28aa07..81b9123affa4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1492,55 +1492,6 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops, i915_drop_caches_get, i915_drop_caches_set, "0x%08llx\n"); -static int -i915_cache_sharing_get(void *data, u64 *val) -{ - struct drm_i915_private *dev_priv = data; - intel_wakeref_t wakeref; - u32 snpcr = 0; - - if (!(IS_GEN_RANGE(dev_priv, 6, 7))) - return -ENODEV; - - with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) - snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); - - *val = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT; - - return 0; -} - -static int -i915_cache_sharing_set(void *data, u64 val) -{ - struct drm_i915_private *dev_priv = data; - intel_wakeref_t wakeref; - - if (!(IS_GEN_RANGE(dev_priv, 6, 7))) - return -ENODEV; - - if (val > 3) - return -EINVAL; - - drm_dbg(&dev_priv->drm, - "Manually setting uncore sharing to %llu\n", val); - with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) { - u32 snpcr; - - /* Update the cache sharing policy here as well */ - snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); - snpcr &= ~GEN6_MBC_SNPCR_MASK; - snpcr |= val << GEN6_MBC_SNPCR_SHIFT; - I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); - } - - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(i915_cache_sharing_fops, - i915_cache_sharing_get, i915_cache_sharing_set, - "%llu\n"); - static int i915_sseu_status(struct seq_file *m, void *unused) { struct drm_i915_private *i915 = node_to_i915(m->private); @@ -1606,7 +1557,6 @@ static const struct i915_debugfs_files { } i915_debugfs_files[] = { {"i915_perf_noa_delay", &i915_perf_noa_delay_fops}, {"i915_wedged", &i915_wedged_fops}, - {"i915_cache_sharing", &i915_cache_sharing_fops}, {"i915_gem_drop_caches", &i915_drop_caches_fops}, #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) {"i915_error_state", &i915_error_state_fops}, From 124a60f2131cc4bed249eea23fdc78a1cbd6b72e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:56 +0200 Subject: [PATCH 0101/5577] drm/i915/debugfs: replace I915_READ() with intel_uncore_read() Another straggler with I915_READ() uses gone. Arguably some of these should use intel_de_read(), however not all. Prioritize I915_READ() removal in general over migrating to the pedantically correct replacement right away. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-5-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 210 ++++++++++++++-------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 81b9123affa4..8b8b94dcde51 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -397,37 +397,37 @@ static void gen8_display_interrupt_info(struct seq_file *m) } seq_printf(m, "Pipe %c IMR:\t%08x\n", pipe_name(pipe), - I915_READ(GEN8_DE_PIPE_IMR(pipe))); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IMR(pipe))); seq_printf(m, "Pipe %c IIR:\t%08x\n", pipe_name(pipe), - I915_READ(GEN8_DE_PIPE_IIR(pipe))); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IIR(pipe))); seq_printf(m, "Pipe %c IER:\t%08x\n", pipe_name(pipe), - I915_READ(GEN8_DE_PIPE_IER(pipe))); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IER(pipe))); intel_display_power_put(dev_priv, power_domain, wakeref); } seq_printf(m, "Display Engine port interrupt mask:\t%08x\n", - I915_READ(GEN8_DE_PORT_IMR)); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IMR)); seq_printf(m, "Display Engine port interrupt identity:\t%08x\n", - I915_READ(GEN8_DE_PORT_IIR)); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IIR)); seq_printf(m, "Display Engine port interrupt enable:\t%08x\n", - I915_READ(GEN8_DE_PORT_IER)); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IER)); seq_printf(m, "Display Engine misc interrupt mask:\t%08x\n", - I915_READ(GEN8_DE_MISC_IMR)); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IMR)); seq_printf(m, "Display Engine misc interrupt identity:\t%08x\n", - I915_READ(GEN8_DE_MISC_IIR)); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IIR)); seq_printf(m, "Display Engine misc interrupt enable:\t%08x\n", - I915_READ(GEN8_DE_MISC_IER)); + intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IER)); seq_printf(m, "PCU interrupt mask:\t%08x\n", - I915_READ(GEN8_PCU_IMR)); + intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IMR)); seq_printf(m, "PCU interrupt identity:\t%08x\n", - I915_READ(GEN8_PCU_IIR)); + intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IIR)); seq_printf(m, "PCU interrupt enable:\t%08x\n", - I915_READ(GEN8_PCU_IER)); + intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IER)); } static int i915_interrupt_info(struct seq_file *m, void *data) @@ -443,16 +443,16 @@ static int i915_interrupt_info(struct seq_file *m, void *data) intel_wakeref_t pref; seq_printf(m, "Master Interrupt Control:\t%08x\n", - I915_READ(GEN8_MASTER_IRQ)); + intel_uncore_read(&dev_priv->uncore, GEN8_MASTER_IRQ)); seq_printf(m, "Display IER:\t%08x\n", - I915_READ(VLV_IER)); + intel_uncore_read(&dev_priv->uncore, VLV_IER)); seq_printf(m, "Display IIR:\t%08x\n", - I915_READ(VLV_IIR)); + intel_uncore_read(&dev_priv->uncore, VLV_IIR)); seq_printf(m, "Display IIR_RW:\t%08x\n", - I915_READ(VLV_IIR_RW)); + intel_uncore_read(&dev_priv->uncore, VLV_IIR_RW)); seq_printf(m, "Display IMR:\t%08x\n", - I915_READ(VLV_IMR)); + intel_uncore_read(&dev_priv->uncore, VLV_IMR)); for_each_pipe(dev_priv, pipe) { enum intel_display_power_domain power_domain; @@ -467,71 +467,71 @@ static int i915_interrupt_info(struct seq_file *m, void *data) seq_printf(m, "Pipe %c stat:\t%08x\n", pipe_name(pipe), - I915_READ(PIPESTAT(pipe))); + intel_uncore_read(&dev_priv->uncore, PIPESTAT(pipe))); intel_display_power_put(dev_priv, power_domain, pref); } pref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); seq_printf(m, "Port hotplug:\t%08x\n", - I915_READ(PORT_HOTPLUG_EN)); + intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_EN)); seq_printf(m, "DPFLIPSTAT:\t%08x\n", - I915_READ(VLV_DPFLIPSTAT)); + intel_uncore_read(&dev_priv->uncore, VLV_DPFLIPSTAT)); seq_printf(m, "DPINVGTT:\t%08x\n", - I915_READ(DPINVGTT)); + intel_uncore_read(&dev_priv->uncore, DPINVGTT)); intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, pref); for (i = 0; i < 4; i++) { seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", - i, I915_READ(GEN8_GT_IMR(i))); + i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IMR(i))); seq_printf(m, "GT Interrupt IIR %d:\t%08x\n", - i, I915_READ(GEN8_GT_IIR(i))); + i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IIR(i))); seq_printf(m, "GT Interrupt IER %d:\t%08x\n", - i, I915_READ(GEN8_GT_IER(i))); + i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IER(i))); } seq_printf(m, "PCU interrupt mask:\t%08x\n", - I915_READ(GEN8_PCU_IMR)); + intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IMR)); seq_printf(m, "PCU interrupt identity:\t%08x\n", - I915_READ(GEN8_PCU_IIR)); + intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IIR)); seq_printf(m, "PCU interrupt enable:\t%08x\n", - I915_READ(GEN8_PCU_IER)); + intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IER)); } else if (INTEL_GEN(dev_priv) >= 11) { if (HAS_MASTER_UNIT_IRQ(dev_priv)) seq_printf(m, "Master Unit Interrupt Control: %08x\n", - I915_READ(DG1_MSTR_UNIT_INTR)); + intel_uncore_read(&dev_priv->uncore, DG1_MSTR_UNIT_INTR)); seq_printf(m, "Master Interrupt Control: %08x\n", - I915_READ(GEN11_GFX_MSTR_IRQ)); + intel_uncore_read(&dev_priv->uncore, GEN11_GFX_MSTR_IRQ)); seq_printf(m, "Render/Copy Intr Enable: %08x\n", - I915_READ(GEN11_RENDER_COPY_INTR_ENABLE)); + intel_uncore_read(&dev_priv->uncore, GEN11_RENDER_COPY_INTR_ENABLE)); seq_printf(m, "VCS/VECS Intr Enable: %08x\n", - I915_READ(GEN11_VCS_VECS_INTR_ENABLE)); + intel_uncore_read(&dev_priv->uncore, GEN11_VCS_VECS_INTR_ENABLE)); seq_printf(m, "GUC/SG Intr Enable:\t %08x\n", - I915_READ(GEN11_GUC_SG_INTR_ENABLE)); + intel_uncore_read(&dev_priv->uncore, GEN11_GUC_SG_INTR_ENABLE)); seq_printf(m, "GPM/WGBOXPERF Intr Enable: %08x\n", - I915_READ(GEN11_GPM_WGBOXPERF_INTR_ENABLE)); + intel_uncore_read(&dev_priv->uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE)); seq_printf(m, "Crypto Intr Enable:\t %08x\n", - I915_READ(GEN11_CRYPTO_RSVD_INTR_ENABLE)); + intel_uncore_read(&dev_priv->uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE)); seq_printf(m, "GUnit/CSME Intr Enable:\t %08x\n", - I915_READ(GEN11_GUNIT_CSME_INTR_ENABLE)); + intel_uncore_read(&dev_priv->uncore, GEN11_GUNIT_CSME_INTR_ENABLE)); seq_printf(m, "Display Interrupt Control:\t%08x\n", - I915_READ(GEN11_DISPLAY_INT_CTL)); + intel_uncore_read(&dev_priv->uncore, GEN11_DISPLAY_INT_CTL)); gen8_display_interrupt_info(m); } else if (INTEL_GEN(dev_priv) >= 8) { seq_printf(m, "Master Interrupt Control:\t%08x\n", - I915_READ(GEN8_MASTER_IRQ)); + intel_uncore_read(&dev_priv->uncore, GEN8_MASTER_IRQ)); for (i = 0; i < 4; i++) { seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", - i, I915_READ(GEN8_GT_IMR(i))); + i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IMR(i))); seq_printf(m, "GT Interrupt IIR %d:\t%08x\n", - i, I915_READ(GEN8_GT_IIR(i))); + i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IIR(i))); seq_printf(m, "GT Interrupt IER %d:\t%08x\n", - i, I915_READ(GEN8_GT_IER(i))); + i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IER(i))); } gen8_display_interrupt_info(m); @@ -539,13 +539,13 @@ static int i915_interrupt_info(struct seq_file *m, void *data) intel_wakeref_t pref; seq_printf(m, "Display IER:\t%08x\n", - I915_READ(VLV_IER)); + intel_uncore_read(&dev_priv->uncore, VLV_IER)); seq_printf(m, "Display IIR:\t%08x\n", - I915_READ(VLV_IIR)); + intel_uncore_read(&dev_priv->uncore, VLV_IIR)); seq_printf(m, "Display IIR_RW:\t%08x\n", - I915_READ(VLV_IIR_RW)); + intel_uncore_read(&dev_priv->uncore, VLV_IIR_RW)); seq_printf(m, "Display IMR:\t%08x\n", - I915_READ(VLV_IMR)); + intel_uncore_read(&dev_priv->uncore, VLV_IMR)); for_each_pipe(dev_priv, pipe) { enum intel_display_power_domain power_domain; @@ -560,87 +560,87 @@ static int i915_interrupt_info(struct seq_file *m, void *data) seq_printf(m, "Pipe %c stat:\t%08x\n", pipe_name(pipe), - I915_READ(PIPESTAT(pipe))); + intel_uncore_read(&dev_priv->uncore, PIPESTAT(pipe))); intel_display_power_put(dev_priv, power_domain, pref); } seq_printf(m, "Master IER:\t%08x\n", - I915_READ(VLV_MASTER_IER)); + intel_uncore_read(&dev_priv->uncore, VLV_MASTER_IER)); seq_printf(m, "Render IER:\t%08x\n", - I915_READ(GTIER)); + intel_uncore_read(&dev_priv->uncore, GTIER)); seq_printf(m, "Render IIR:\t%08x\n", - I915_READ(GTIIR)); + intel_uncore_read(&dev_priv->uncore, GTIIR)); seq_printf(m, "Render IMR:\t%08x\n", - I915_READ(GTIMR)); + intel_uncore_read(&dev_priv->uncore, GTIMR)); seq_printf(m, "PM IER:\t\t%08x\n", - I915_READ(GEN6_PMIER)); + intel_uncore_read(&dev_priv->uncore, GEN6_PMIER)); seq_printf(m, "PM IIR:\t\t%08x\n", - I915_READ(GEN6_PMIIR)); + intel_uncore_read(&dev_priv->uncore, GEN6_PMIIR)); seq_printf(m, "PM IMR:\t\t%08x\n", - I915_READ(GEN6_PMIMR)); + intel_uncore_read(&dev_priv->uncore, GEN6_PMIMR)); pref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); seq_printf(m, "Port hotplug:\t%08x\n", - I915_READ(PORT_HOTPLUG_EN)); + intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_EN)); seq_printf(m, "DPFLIPSTAT:\t%08x\n", - I915_READ(VLV_DPFLIPSTAT)); + intel_uncore_read(&dev_priv->uncore, VLV_DPFLIPSTAT)); seq_printf(m, "DPINVGTT:\t%08x\n", - I915_READ(DPINVGTT)); + intel_uncore_read(&dev_priv->uncore, DPINVGTT)); intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, pref); } else if (!HAS_PCH_SPLIT(dev_priv)) { seq_printf(m, "Interrupt enable: %08x\n", - I915_READ(GEN2_IER)); + intel_uncore_read(&dev_priv->uncore, GEN2_IER)); seq_printf(m, "Interrupt identity: %08x\n", - I915_READ(GEN2_IIR)); + intel_uncore_read(&dev_priv->uncore, GEN2_IIR)); seq_printf(m, "Interrupt mask: %08x\n", - I915_READ(GEN2_IMR)); + intel_uncore_read(&dev_priv->uncore, GEN2_IMR)); for_each_pipe(dev_priv, pipe) seq_printf(m, "Pipe %c stat: %08x\n", pipe_name(pipe), - I915_READ(PIPESTAT(pipe))); + intel_uncore_read(&dev_priv->uncore, PIPESTAT(pipe))); } else { seq_printf(m, "North Display Interrupt enable: %08x\n", - I915_READ(DEIER)); + intel_uncore_read(&dev_priv->uncore, DEIER)); seq_printf(m, "North Display Interrupt identity: %08x\n", - I915_READ(DEIIR)); + intel_uncore_read(&dev_priv->uncore, DEIIR)); seq_printf(m, "North Display Interrupt mask: %08x\n", - I915_READ(DEIMR)); + intel_uncore_read(&dev_priv->uncore, DEIMR)); seq_printf(m, "South Display Interrupt enable: %08x\n", - I915_READ(SDEIER)); + intel_uncore_read(&dev_priv->uncore, SDEIER)); seq_printf(m, "South Display Interrupt identity: %08x\n", - I915_READ(SDEIIR)); + intel_uncore_read(&dev_priv->uncore, SDEIIR)); seq_printf(m, "South Display Interrupt mask: %08x\n", - I915_READ(SDEIMR)); + intel_uncore_read(&dev_priv->uncore, SDEIMR)); seq_printf(m, "Graphics Interrupt enable: %08x\n", - I915_READ(GTIER)); + intel_uncore_read(&dev_priv->uncore, GTIER)); seq_printf(m, "Graphics Interrupt identity: %08x\n", - I915_READ(GTIIR)); + intel_uncore_read(&dev_priv->uncore, GTIIR)); seq_printf(m, "Graphics Interrupt mask: %08x\n", - I915_READ(GTIMR)); + intel_uncore_read(&dev_priv->uncore, GTIMR)); } if (INTEL_GEN(dev_priv) >= 11) { seq_printf(m, "RCS Intr Mask:\t %08x\n", - I915_READ(GEN11_RCS0_RSVD_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_RCS0_RSVD_INTR_MASK)); seq_printf(m, "BCS Intr Mask:\t %08x\n", - I915_READ(GEN11_BCS_RSVD_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_BCS_RSVD_INTR_MASK)); seq_printf(m, "VCS0/VCS1 Intr Mask:\t %08x\n", - I915_READ(GEN11_VCS0_VCS1_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_VCS0_VCS1_INTR_MASK)); seq_printf(m, "VCS2/VCS3 Intr Mask:\t %08x\n", - I915_READ(GEN11_VCS2_VCS3_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_VCS2_VCS3_INTR_MASK)); seq_printf(m, "VECS0/VECS1 Intr Mask:\t %08x\n", - I915_READ(GEN11_VECS0_VECS1_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_VECS0_VECS1_INTR_MASK)); seq_printf(m, "GUC/SG Intr Mask:\t %08x\n", - I915_READ(GEN11_GUC_SG_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_GUC_SG_INTR_MASK)); seq_printf(m, "GPM/WGBOXPERF Intr Mask: %08x\n", - I915_READ(GEN11_GPM_WGBOXPERF_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_GPM_WGBOXPERF_INTR_MASK)); seq_printf(m, "Crypto Intr Mask:\t %08x\n", - I915_READ(GEN11_CRYPTO_RSVD_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_CRYPTO_RSVD_INTR_MASK)); seq_printf(m, "Gunit/CSME Intr Mask:\t %08x\n", - I915_READ(GEN11_GUNIT_CSME_INTR_MASK)); + intel_uncore_read(&dev_priv->uncore, GEN11_GUNIT_CSME_INTR_MASK)); } else if (INTEL_GEN(dev_priv) >= 6) { for_each_uabi_engine(engine, dev_priv) { @@ -802,7 +802,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { u32 rpmodectl, freq_sts; - rpmodectl = I915_READ(GEN6_RP_CONTROL); + rpmodectl = intel_uncore_read(&dev_priv->uncore, GEN6_RP_CONTROL); seq_printf(m, "Video Turbo Mode: %s\n", yesno(rpmodectl & GEN6_RP_MEDIA_TURBO)); seq_printf(m, "HW control enabled: %s\n", @@ -847,19 +847,19 @@ static int i915_frequency_info(struct seq_file *m, void *unused) u32 pm_ier, pm_imr, pm_isr, pm_iir, pm_mask; int max_freq; - rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); + rp_state_limits = intel_uncore_read(&dev_priv->uncore, GEN6_RP_STATE_LIMITS); if (IS_GEN9_LP(dev_priv)) { - rp_state_cap = I915_READ(BXT_RP_STATE_CAP); - gt_perf_status = I915_READ(BXT_GT_PERF_STATUS); + rp_state_cap = intel_uncore_read(&dev_priv->uncore, BXT_RP_STATE_CAP); + gt_perf_status = intel_uncore_read(&dev_priv->uncore, BXT_GT_PERF_STATUS); } else { - rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); - gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); + rp_state_cap = intel_uncore_read(&dev_priv->uncore, GEN6_RP_STATE_CAP); + gt_perf_status = intel_uncore_read(&dev_priv->uncore, GEN6_GT_PERF_STATUS); } /* RPSTAT1 is in the GT power well */ intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL); - reqf = I915_READ(GEN6_RPNSWREQ); + reqf = intel_uncore_read(&dev_priv->uncore, GEN6_RPNSWREQ); if (INTEL_GEN(dev_priv) >= 9) reqf >>= 23; else { @@ -871,24 +871,24 @@ static int i915_frequency_info(struct seq_file *m, void *unused) } reqf = intel_gpu_freq(rps, reqf); - rpmodectl = I915_READ(GEN6_RP_CONTROL); - rpinclimit = I915_READ(GEN6_RP_UP_THRESHOLD); - rpdeclimit = I915_READ(GEN6_RP_DOWN_THRESHOLD); + rpmodectl = intel_uncore_read(&dev_priv->uncore, GEN6_RP_CONTROL); + rpinclimit = intel_uncore_read(&dev_priv->uncore, GEN6_RP_UP_THRESHOLD); + rpdeclimit = intel_uncore_read(&dev_priv->uncore, GEN6_RP_DOWN_THRESHOLD); - rpstat = I915_READ(GEN6_RPSTAT1); - rpupei = I915_READ(GEN6_RP_CUR_UP_EI) & GEN6_CURICONT_MASK; - rpcurup = I915_READ(GEN6_RP_CUR_UP) & GEN6_CURBSYTAVG_MASK; - rpprevup = I915_READ(GEN6_RP_PREV_UP) & GEN6_CURBSYTAVG_MASK; - rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK; - rpcurdown = I915_READ(GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK; - rpprevdown = I915_READ(GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK; + rpstat = intel_uncore_read(&dev_priv->uncore, GEN6_RPSTAT1); + rpupei = intel_uncore_read(&dev_priv->uncore, GEN6_RP_CUR_UP_EI) & GEN6_CURICONT_MASK; + rpcurup = intel_uncore_read(&dev_priv->uncore, GEN6_RP_CUR_UP) & GEN6_CURBSYTAVG_MASK; + rpprevup = intel_uncore_read(&dev_priv->uncore, GEN6_RP_PREV_UP) & GEN6_CURBSYTAVG_MASK; + rpdownei = intel_uncore_read(&dev_priv->uncore, GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK; + rpcurdown = intel_uncore_read(&dev_priv->uncore, GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK; + rpprevdown = intel_uncore_read(&dev_priv->uncore, GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK; cagf = intel_rps_read_actual_frequency(rps); intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); if (INTEL_GEN(dev_priv) >= 11) { - pm_ier = I915_READ(GEN11_GPM_WGBOXPERF_INTR_ENABLE); - pm_imr = I915_READ(GEN11_GPM_WGBOXPERF_INTR_MASK); + pm_ier = intel_uncore_read(&dev_priv->uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE); + pm_imr = intel_uncore_read(&dev_priv->uncore, GEN11_GPM_WGBOXPERF_INTR_MASK); /* * The equivalent to the PM ISR & IIR cannot be read * without affecting the current state of the system @@ -896,17 +896,17 @@ static int i915_frequency_info(struct seq_file *m, void *unused) pm_isr = 0; pm_iir = 0; } else if (INTEL_GEN(dev_priv) >= 8) { - pm_ier = I915_READ(GEN8_GT_IER(2)); - pm_imr = I915_READ(GEN8_GT_IMR(2)); - pm_isr = I915_READ(GEN8_GT_ISR(2)); - pm_iir = I915_READ(GEN8_GT_IIR(2)); + pm_ier = intel_uncore_read(&dev_priv->uncore, GEN8_GT_IER(2)); + pm_imr = intel_uncore_read(&dev_priv->uncore, GEN8_GT_IMR(2)); + pm_isr = intel_uncore_read(&dev_priv->uncore, GEN8_GT_ISR(2)); + pm_iir = intel_uncore_read(&dev_priv->uncore, GEN8_GT_IIR(2)); } else { - pm_ier = I915_READ(GEN6_PMIER); - pm_imr = I915_READ(GEN6_PMIMR); - pm_isr = I915_READ(GEN6_PMISR); - pm_iir = I915_READ(GEN6_PMIIR); + pm_ier = intel_uncore_read(&dev_priv->uncore, GEN6_PMIER); + pm_imr = intel_uncore_read(&dev_priv->uncore, GEN6_PMIMR); + pm_isr = intel_uncore_read(&dev_priv->uncore, GEN6_PMISR); + pm_iir = intel_uncore_read(&dev_priv->uncore, GEN6_PMIIR); } - pm_mask = I915_READ(GEN6_PMINTRMSK); + pm_mask = intel_uncore_read(&dev_priv->uncore, GEN6_PMINTRMSK); seq_printf(m, "Video Turbo Mode: %s\n", yesno(rpmodectl & GEN6_RP_MEDIA_TURBO)); From 77895af24e2cbb71eb34227c4be07043203df158 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:57 +0200 Subject: [PATCH 0102/5577] drm/i915/suspend: replace I915_READ()/WRITE() with intel_de_read()/write() Another straggler with I915_READ() and I915_WRITE() uses gone. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-6-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_suspend.c | 33 +++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index db2111fc809e..63212df33c9e 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -24,6 +24,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "display/intel_de.h" #include "display/intel_fbc.h" #include "display/intel_gmbus.h" #include "display/intel_vga.h" @@ -39,21 +40,21 @@ static void intel_save_swf(struct drm_i915_private *dev_priv) /* Scratch space */ if (IS_GEN(dev_priv, 2) && IS_MOBILE(dev_priv)) { for (i = 0; i < 7; i++) { - dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i)); - dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i)); + dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv, SWF0(i)); + dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, SWF1(i)); } for (i = 0; i < 3; i++) - dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i)); + dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv, SWF3(i)); } else if (IS_GEN(dev_priv, 2)) { for (i = 0; i < 7; i++) - dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i)); + dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, SWF1(i)); } else if (HAS_GMCH(dev_priv)) { for (i = 0; i < 16; i++) { - dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i)); - dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i)); + dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv, SWF0(i)); + dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, SWF1(i)); } for (i = 0; i < 3; i++) - dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i)); + dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv, SWF3(i)); } } @@ -64,21 +65,21 @@ static void intel_restore_swf(struct drm_i915_private *dev_priv) /* Scratch space */ if (IS_GEN(dev_priv, 2) && IS_MOBILE(dev_priv)) { for (i = 0; i < 7; i++) { - I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]); - I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]); + intel_de_write(dev_priv, SWF0(i), dev_priv->regfile.saveSWF0[i]); + intel_de_write(dev_priv, SWF1(i), dev_priv->regfile.saveSWF1[i]); } for (i = 0; i < 3; i++) - I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]); + intel_de_write(dev_priv, SWF3(i), dev_priv->regfile.saveSWF3[i]); } else if (IS_GEN(dev_priv, 2)) { for (i = 0; i < 7; i++) - I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]); + intel_de_write(dev_priv, SWF1(i), dev_priv->regfile.saveSWF1[i]); } else if (HAS_GMCH(dev_priv)) { for (i = 0; i < 16; i++) { - I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]); - I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]); + intel_de_write(dev_priv, SWF0(i), dev_priv->regfile.saveSWF0[i]); + intel_de_write(dev_priv, SWF1(i), dev_priv->regfile.saveSWF1[i]); } for (i = 0; i < 3; i++) - I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]); + intel_de_write(dev_priv, SWF3(i), dev_priv->regfile.saveSWF3[i]); } } @@ -88,7 +89,7 @@ void i915_save_display(struct drm_i915_private *dev_priv) /* Display arbitration control */ if (INTEL_GEN(dev_priv) <= 4) - dev_priv->regfile.saveDSPARB = I915_READ(DSPARB); + dev_priv->regfile.saveDSPARB = intel_de_read(dev_priv, DSPARB); if (IS_GEN(dev_priv, 4)) pci_read_config_word(pdev, GCDGMBUS, @@ -109,7 +110,7 @@ void i915_restore_display(struct drm_i915_private *dev_priv) /* Display arbitration */ if (INTEL_GEN(dev_priv) <= 4) - I915_WRITE(DSPARB, dev_priv->regfile.saveDSPARB); + intel_de_write(dev_priv, DSPARB, dev_priv->regfile.saveDSPARB); /* only restore FBC info on the platform that supports FBC*/ intel_fbc_global_disable(dev_priv); From 5f461660db1792fa422b454317e11d8654f57e15 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:58 +0200 Subject: [PATCH 0103/5577] drm/i915/pm: replace I915_READ()/WRITE() with intel_uncore_read()/write() Arguably some of these should use intel_de_read() or intel_de_write(), however not all. Prioritize I915_READ() and I915_WRITE() removal in general over migrating to the pedantically correct replacements right away. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-7-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 552 ++++++++++++++++---------------- 1 file changed, 276 insertions(+), 276 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ad76e0a835d4..57db548673dd 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -82,24 +82,24 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) * Must match Sampler, Pixel Back End, and Media. See * WaCompressedResourceSamplerPbeMediaNewHashMode. */ - I915_WRITE(CHICKEN_PAR1_1, - I915_READ(CHICKEN_PAR1_1) | + intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1, + intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_DE_COMPRESSED_HASH_MODE); } /* 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); + intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1, + intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ - I915_WRITE(GEN8_CHICKEN_DCPR_1, - I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); + intel_uncore_write(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, + intel_uncore_read(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); /* * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl * Display WA #0859: skl,bxt,kbl,glk,cfl */ - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | DISP_FBC_MEMORY_WAKE); } @@ -108,21 +108,21 @@ static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) gen9_init_clock_gating(dev_priv); /* WaDisableSDEUnitClockGating:bxt */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + intel_uncore_write(&dev_priv->uncore, GEN8_UCGCTL6, intel_uncore_read(&dev_priv->uncore, GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* * FIXME: * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + intel_uncore_write(&dev_priv->uncore, GEN8_UCGCTL6, intel_uncore_read(&dev_priv->uncore, GEN8_UCGCTL6) | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); /* * Wa: Backlight PWM may stop in the asserted state, causing backlight * to stay fully on. */ - I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) | + intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | PWM1_GATING_DIS | PWM2_GATING_DIS); /* @@ -131,20 +131,20 @@ static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) * is off and a MMIO access is attempted by any privilege * application, using batch buffers or any other means. */ - I915_WRITE(RM_TIMEOUT, MMIO_TIMEOUT_US(950)); + intel_uncore_write(&dev_priv->uncore, RM_TIMEOUT, MMIO_TIMEOUT_US(950)); /* * WaFbcTurnOffFbcWatermark:bxt * Display WA #0562: bxt */ - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | DISP_FBC_WM_DIS); /* * WaFbcHighMemBwCorruptionAvoidance:bxt * Display WA #0883: bxt */ - I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | ILK_DPFC_DISABLE_DUMMY0); } @@ -157,7 +157,7 @@ static void glk_init_clock_gating(struct drm_i915_private *dev_priv) * Backlight PWM may stop in the asserted state, causing backlight * to stay fully on. */ - I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) | + intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | PWM1_GATING_DIS | PWM2_GATING_DIS); } @@ -165,7 +165,7 @@ static void pnv_get_mem_freq(struct drm_i915_private *dev_priv) { u32 tmp; - tmp = I915_READ(CLKCFG); + tmp = intel_uncore_read(&dev_priv->uncore, CLKCFG); switch (tmp & CLKCFG_FSB_MASK) { case CLKCFG_FSB_533: @@ -195,7 +195,7 @@ static void pnv_get_mem_freq(struct drm_i915_private *dev_priv) } /* detect pineview DDR3 setting */ - tmp = I915_READ(CSHRDDR3CTL); + tmp = intel_uncore_read(&dev_priv->uncore, CSHRDDR3CTL); dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; } @@ -366,39 +366,39 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl u32 val; if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - was_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; - I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); - POSTING_READ(FW_BLC_SELF_VLV); + was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; + intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); + intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF_VLV); } else if (IS_G4X(dev_priv) || IS_I965GM(dev_priv)) { - was_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; - I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); - POSTING_READ(FW_BLC_SELF); + was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; + intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); + intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF); } else if (IS_PINEVIEW(dev_priv)) { - val = I915_READ(DSPFW3); + val = intel_uncore_read(&dev_priv->uncore, DSPFW3); was_enabled = val & PINEVIEW_SELF_REFRESH_EN; if (enable) val |= PINEVIEW_SELF_REFRESH_EN; else val &= ~PINEVIEW_SELF_REFRESH_EN; - I915_WRITE(DSPFW3, val); - POSTING_READ(DSPFW3); + intel_uncore_write(&dev_priv->uncore, DSPFW3, val); + intel_uncore_posting_read(&dev_priv->uncore, DSPFW3); } else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) { - was_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; + was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) : _MASKED_BIT_DISABLE(FW_BLC_SELF_EN); - I915_WRITE(FW_BLC_SELF, val); - POSTING_READ(FW_BLC_SELF); + intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, val); + intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF); } else if (IS_I915GM(dev_priv)) { /* * FIXME can't find a bit like this for 915G, and * and yet it does have the related watermark in * FW_BLC_SELF. What's going on? */ - was_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; + was_enabled = intel_uncore_read(&dev_priv->uncore, INSTPM) & INSTPM_SELF_EN; val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) : _MASKED_BIT_DISABLE(INSTPM_SELF_EN); - I915_WRITE(INSTPM, val); - POSTING_READ(INSTPM); + intel_uncore_write(&dev_priv->uncore, INSTPM, val); + intel_uncore_posting_read(&dev_priv->uncore, INSTPM); } else { return false; } @@ -494,20 +494,20 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) switch (pipe) { case PIPE_A: - dsparb = I915_READ(DSPARB); - dsparb2 = I915_READ(DSPARB2); + dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB); + dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 0, 0); sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 8, 4); break; case PIPE_B: - dsparb = I915_READ(DSPARB); - dsparb2 = I915_READ(DSPARB2); + dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB); + dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 16, 8); sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 24, 12); break; case PIPE_C: - dsparb2 = I915_READ(DSPARB2); - dsparb3 = I915_READ(DSPARB3); + dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); + dsparb3 = intel_uncore_read(&dev_priv->uncore, DSPARB3); sprite0_start = VLV_FIFO_START(dsparb3, dsparb2, 0, 16); sprite1_start = VLV_FIFO_START(dsparb3, dsparb2, 8, 20); break; @@ -525,7 +525,7 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = I915_READ(DSPARB); + u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB); int size; size = dsparb & 0x7f; @@ -541,7 +541,7 @@ static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv, static int i830_get_fifo_size(struct drm_i915_private *dev_priv, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = I915_READ(DSPARB); + u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB); int size; size = dsparb & 0x1ff; @@ -558,7 +558,7 @@ static int i830_get_fifo_size(struct drm_i915_private *dev_priv, static int i845_get_fifo_size(struct drm_i915_private *dev_priv, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = I915_READ(DSPARB); + u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB); int size; size = dsparb & 0x7f; @@ -911,38 +911,38 @@ static void pnv_update_wm(struct intel_crtc *unused_crtc) wm = intel_calculate_wm(clock, &pnv_display_wm, pnv_display_wm.fifo_size, cpp, latency->display_sr); - reg = I915_READ(DSPFW1); + reg = intel_uncore_read(&dev_priv->uncore, DSPFW1); reg &= ~DSPFW_SR_MASK; reg |= FW_WM(wm, SR); - I915_WRITE(DSPFW1, reg); + intel_uncore_write(&dev_priv->uncore, DSPFW1, reg); drm_dbg_kms(&dev_priv->drm, "DSPFW1 register is %x\n", reg); /* cursor SR */ wm = intel_calculate_wm(clock, &pnv_cursor_wm, pnv_display_wm.fifo_size, 4, latency->cursor_sr); - reg = I915_READ(DSPFW3); + reg = intel_uncore_read(&dev_priv->uncore, DSPFW3); reg &= ~DSPFW_CURSOR_SR_MASK; reg |= FW_WM(wm, CURSOR_SR); - I915_WRITE(DSPFW3, reg); + intel_uncore_write(&dev_priv->uncore, DSPFW3, reg); /* Display HPLL off SR */ wm = intel_calculate_wm(clock, &pnv_display_hplloff_wm, pnv_display_hplloff_wm.fifo_size, cpp, latency->display_hpll_disable); - reg = I915_READ(DSPFW3); + reg = intel_uncore_read(&dev_priv->uncore, DSPFW3); reg &= ~DSPFW_HPLL_SR_MASK; reg |= FW_WM(wm, HPLL_SR); - I915_WRITE(DSPFW3, reg); + intel_uncore_write(&dev_priv->uncore, DSPFW3, reg); /* cursor HPLL off SR */ wm = intel_calculate_wm(clock, &pnv_cursor_hplloff_wm, pnv_display_hplloff_wm.fifo_size, 4, latency->cursor_hpll_disable); - reg = I915_READ(DSPFW3); + reg = intel_uncore_read(&dev_priv->uncore, DSPFW3); reg &= ~DSPFW_HPLL_CURSOR_MASK; reg |= FW_WM(wm, HPLL_CURSOR); - I915_WRITE(DSPFW3, reg); + intel_uncore_write(&dev_priv->uncore, DSPFW3, reg); drm_dbg_kms(&dev_priv->drm, "DSPFW3 register is %x\n", reg); intel_set_memory_cxsr(dev_priv, true); @@ -976,25 +976,25 @@ static void g4x_write_wm_values(struct drm_i915_private *dev_priv, for_each_pipe(dev_priv, pipe) trace_g4x_wm(intel_get_crtc_for_pipe(dev_priv, pipe), wm); - I915_WRITE(DSPFW1, + intel_uncore_write(&dev_priv->uncore, DSPFW1, FW_WM(wm->sr.plane, SR) | FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); - I915_WRITE(DSPFW2, + intel_uncore_write(&dev_priv->uncore, DSPFW2, (wm->fbc_en ? DSPFW_FBC_SR_EN : 0) | FW_WM(wm->sr.fbc, FBC_SR) | FW_WM(wm->hpll.fbc, FBC_HPLL_SR) | FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEB) | FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); - I915_WRITE(DSPFW3, + intel_uncore_write(&dev_priv->uncore, DSPFW3, (wm->hpll_en ? DSPFW_HPLL_SR_EN : 0) | FW_WM(wm->sr.cursor, CURSOR_SR) | FW_WM(wm->hpll.cursor, HPLL_CURSOR) | FW_WM(wm->hpll.plane, HPLL_SR)); - POSTING_READ(DSPFW1); + intel_uncore_posting_read(&dev_priv->uncore, DSPFW1); } #define FW_WM_VLV(value, plane) \ @@ -1008,7 +1008,7 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv, for_each_pipe(dev_priv, pipe) { trace_vlv_wm(intel_get_crtc_for_pipe(dev_priv, pipe), wm); - I915_WRITE(VLV_DDL(pipe), + intel_uncore_write(&dev_priv->uncore, VLV_DDL(pipe), (wm->ddl[pipe].plane[PLANE_CURSOR] << DDL_CURSOR_SHIFT) | (wm->ddl[pipe].plane[PLANE_SPRITE1] << DDL_SPRITE_SHIFT(1)) | (wm->ddl[pipe].plane[PLANE_SPRITE0] << DDL_SPRITE_SHIFT(0)) | @@ -1020,35 +1020,35 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv, * high order bits so that there are no out of bounds values * present in the registers during the reprogramming. */ - I915_WRITE(DSPHOWM, 0); - I915_WRITE(DSPHOWM1, 0); - I915_WRITE(DSPFW4, 0); - I915_WRITE(DSPFW5, 0); - I915_WRITE(DSPFW6, 0); + intel_uncore_write(&dev_priv->uncore, DSPHOWM, 0); + intel_uncore_write(&dev_priv->uncore, DSPHOWM1, 0); + intel_uncore_write(&dev_priv->uncore, DSPFW4, 0); + intel_uncore_write(&dev_priv->uncore, DSPFW5, 0); + intel_uncore_write(&dev_priv->uncore, DSPFW6, 0); - I915_WRITE(DSPFW1, + intel_uncore_write(&dev_priv->uncore, DSPFW1, FW_WM(wm->sr.plane, SR) | FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); - I915_WRITE(DSPFW2, + intel_uncore_write(&dev_priv->uncore, DSPFW2, FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE1], SPRITEB) | FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); - I915_WRITE(DSPFW3, + intel_uncore_write(&dev_priv->uncore, DSPFW3, FW_WM(wm->sr.cursor, CURSOR_SR)); if (IS_CHERRYVIEW(dev_priv)) { - I915_WRITE(DSPFW7_CHV, + intel_uncore_write(&dev_priv->uncore, DSPFW7_CHV, FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); - I915_WRITE(DSPFW8_CHV, + intel_uncore_write(&dev_priv->uncore, DSPFW8_CHV, FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE1], SPRITEF) | FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE0], SPRITEE)); - I915_WRITE(DSPFW9_CHV, + intel_uncore_write(&dev_priv->uncore, DSPFW9_CHV, FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_PRIMARY], PLANEC) | FW_WM(wm->pipe[PIPE_C].plane[PLANE_CURSOR], CURSORC)); - I915_WRITE(DSPHOWM, + intel_uncore_write(&dev_priv->uncore, DSPHOWM, FW_WM(wm->sr.plane >> 9, SR_HI) | FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE1] >> 8, SPRITEF_HI) | FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE0] >> 8, SPRITEE_HI) | @@ -1060,10 +1060,10 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv, FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); } else { - I915_WRITE(DSPFW7, + intel_uncore_write(&dev_priv->uncore, DSPFW7, FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); - I915_WRITE(DSPHOWM, + intel_uncore_write(&dev_priv->uncore, DSPHOWM, FW_WM(wm->sr.plane >> 9, SR_HI) | FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | @@ -1073,7 +1073,7 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv, FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); } - POSTING_READ(DSPFW1); + intel_uncore_posting_read(&dev_priv->uncore, DSPFW1); } #undef FW_WM_VLV @@ -2310,14 +2310,14 @@ static void i965_update_wm(struct intel_crtc *unused_crtc) srwm); /* 965 has limitations... */ - I915_WRITE(DSPFW1, FW_WM(srwm, SR) | + intel_uncore_write(&dev_priv->uncore, DSPFW1, FW_WM(srwm, SR) | FW_WM(8, CURSORB) | FW_WM(8, PLANEB) | FW_WM(8, PLANEA)); - I915_WRITE(DSPFW2, FW_WM(8, CURSORA) | + intel_uncore_write(&dev_priv->uncore, DSPFW2, FW_WM(8, CURSORA) | FW_WM(8, PLANEC_OLD)); /* update cursor SR watermark */ - I915_WRITE(DSPFW3, FW_WM(cursor_sr, CURSOR_SR)); + intel_uncore_write(&dev_priv->uncore, DSPFW3, FW_WM(cursor_sr, CURSOR_SR)); if (cxsr_enabled) intel_set_memory_cxsr(dev_priv, true); @@ -2447,10 +2447,10 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) srwm = 1; if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) - I915_WRITE(FW_BLC_SELF, + intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); else - I915_WRITE(FW_BLC_SELF, srwm & 0x3f); + intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, srwm & 0x3f); } drm_dbg_kms(&dev_priv->drm, @@ -2464,8 +2464,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) fwater_lo = fwater_lo | (1 << 24) | (1 << 8); fwater_hi = fwater_hi | (1 << 8); - I915_WRITE(FW_BLC, fwater_lo); - I915_WRITE(FW_BLC2, fwater_hi); + intel_uncore_write(&dev_priv->uncore, FW_BLC, fwater_lo); + intel_uncore_write(&dev_priv->uncore, FW_BLC2, fwater_hi); if (enabled) intel_set_memory_cxsr(dev_priv, true); @@ -2488,13 +2488,13 @@ static void i845_update_wm(struct intel_crtc *unused_crtc) &i845_wm_info, dev_priv->display.get_fifo_size(dev_priv, PLANE_A), 4, pessimal_latency_ns); - fwater_lo = I915_READ(FW_BLC) & ~0xfff; + fwater_lo = intel_uncore_read(&dev_priv->uncore, FW_BLC) & ~0xfff; fwater_lo |= (3<<8) | planea_wm; drm_dbg_kms(&dev_priv->drm, "Setting FIFO watermarks - A: %d\n", planea_wm); - I915_WRITE(FW_BLC, fwater_lo); + intel_uncore_write(&dev_priv->uncore, FW_BLC, fwater_lo); } /* latency must be in 0.1us units. */ @@ -3534,17 +3534,17 @@ static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv, if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] & WM1_LP_SR_EN) { previous->wm_lp[2] &= ~WM1_LP_SR_EN; - I915_WRITE(WM3_LP_ILK, previous->wm_lp[2]); + intel_uncore_write(&dev_priv->uncore, WM3_LP_ILK, previous->wm_lp[2]); changed = true; } if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] & WM1_LP_SR_EN) { previous->wm_lp[1] &= ~WM1_LP_SR_EN; - I915_WRITE(WM2_LP_ILK, previous->wm_lp[1]); + intel_uncore_write(&dev_priv->uncore, WM2_LP_ILK, previous->wm_lp[1]); changed = true; } if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] & WM1_LP_SR_EN) { previous->wm_lp[0] &= ~WM1_LP_SR_EN; - I915_WRITE(WM1_LP_ILK, previous->wm_lp[0]); + intel_uncore_write(&dev_priv->uncore, WM1_LP_ILK, previous->wm_lp[0]); changed = true; } @@ -3574,56 +3574,56 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, _ilk_disable_lp_wm(dev_priv, dirty); if (dirty & WM_DIRTY_PIPE(PIPE_A)) - I915_WRITE(WM0_PIPE_ILK(PIPE_A), results->wm_pipe[0]); + intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_A), results->wm_pipe[0]); if (dirty & WM_DIRTY_PIPE(PIPE_B)) - I915_WRITE(WM0_PIPE_ILK(PIPE_B), results->wm_pipe[1]); + intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_B), results->wm_pipe[1]); if (dirty & WM_DIRTY_PIPE(PIPE_C)) - I915_WRITE(WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]); + intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]); if (dirty & WM_DIRTY_DDB) { if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { - val = I915_READ(WM_MISC); + val = intel_uncore_read(&dev_priv->uncore, WM_MISC); if (results->partitioning == INTEL_DDB_PART_1_2) val &= ~WM_MISC_DATA_PARTITION_5_6; else val |= WM_MISC_DATA_PARTITION_5_6; - I915_WRITE(WM_MISC, val); + intel_uncore_write(&dev_priv->uncore, WM_MISC, val); } else { - val = I915_READ(DISP_ARB_CTL2); + val = intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL2); if (results->partitioning == INTEL_DDB_PART_1_2) val &= ~DISP_DATA_PARTITION_5_6; else val |= DISP_DATA_PARTITION_5_6; - I915_WRITE(DISP_ARB_CTL2, val); + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL2, val); } } if (dirty & WM_DIRTY_FBC) { - val = I915_READ(DISP_ARB_CTL); + val = intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL); if (results->enable_fbc_wm) val &= ~DISP_FBC_WM_DIS; else val |= DISP_FBC_WM_DIS; - I915_WRITE(DISP_ARB_CTL, val); + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, val); } if (dirty & WM_DIRTY_LP(1) && previous->wm_lp_spr[0] != results->wm_lp_spr[0]) - I915_WRITE(WM1S_LP_ILK, results->wm_lp_spr[0]); + intel_uncore_write(&dev_priv->uncore, WM1S_LP_ILK, results->wm_lp_spr[0]); if (INTEL_GEN(dev_priv) >= 7) { if (dirty & WM_DIRTY_LP(2) && previous->wm_lp_spr[1] != results->wm_lp_spr[1]) - I915_WRITE(WM2S_LP_IVB, results->wm_lp_spr[1]); + intel_uncore_write(&dev_priv->uncore, WM2S_LP_IVB, results->wm_lp_spr[1]); if (dirty & WM_DIRTY_LP(3) && previous->wm_lp_spr[2] != results->wm_lp_spr[2]) - I915_WRITE(WM3S_LP_IVB, results->wm_lp_spr[2]); + intel_uncore_write(&dev_priv->uncore, WM3S_LP_IVB, results->wm_lp_spr[2]); } if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] != results->wm_lp[0]) - I915_WRITE(WM1_LP_ILK, results->wm_lp[0]); + intel_uncore_write(&dev_priv->uncore, WM1_LP_ILK, results->wm_lp[0]); if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] != results->wm_lp[1]) - I915_WRITE(WM2_LP_ILK, results->wm_lp[1]); + intel_uncore_write(&dev_priv->uncore, WM2_LP_ILK, results->wm_lp[1]); if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] != results->wm_lp[2]) - I915_WRITE(WM3_LP_ILK, results->wm_lp[2]); + intel_uncore_write(&dev_priv->uncore, WM3_LP_ILK, results->wm_lp[2]); dev_priv->wm.hw = *results; } @@ -3640,7 +3640,7 @@ u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *dev_priv) u8 enabled_slices_mask = 0; for (i = 0; i < max_slices; i++) { - if (I915_READ(DBUF_CTL_S(i)) & DBUF_POWER_STATE) + if (intel_uncore_read(&dev_priv->uncore, DBUF_CTL_S(i)) & DBUF_POWER_STATE) enabled_slices_mask |= BIT(i); } @@ -4300,12 +4300,12 @@ skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv, /* Cursor doesn't support NV12/planar, so no extra calculation needed */ if (plane_id == PLANE_CURSOR) { - val = I915_READ(CUR_BUF_CFG(pipe)); + val = intel_uncore_read(&dev_priv->uncore, CUR_BUF_CFG(pipe)); skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); return; } - val = I915_READ(PLANE_CTL(pipe, plane_id)); + val = intel_uncore_read(&dev_priv->uncore, PLANE_CTL(pipe, plane_id)); /* No DDB allocated for disabled planes */ if (val & PLANE_CTL_ENABLE) @@ -4314,11 +4314,11 @@ skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv, val & PLANE_CTL_ALPHA_MASK); if (INTEL_GEN(dev_priv) >= 11) { - val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); + val = intel_uncore_read(&dev_priv->uncore, PLANE_BUF_CFG(pipe, plane_id)); skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); } else { - val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); - val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id)); + val = intel_uncore_read(&dev_priv->uncore, PLANE_BUF_CFG(pipe, plane_id)); + val2 = intel_uncore_read(&dev_priv->uncore, PLANE_NV12_BUF_CFG(pipe, plane_id)); if (fourcc && drm_format_info_is_yuv_semiplanar(drm_format_info(fourcc))) @@ -6231,9 +6231,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, for (level = 0; level <= max_level; level++) { if (plane_id != PLANE_CURSOR) - val = I915_READ(PLANE_WM(pipe, plane_id, level)); + val = intel_uncore_read(&dev_priv->uncore, PLANE_WM(pipe, plane_id, level)); else - val = I915_READ(CUR_WM(pipe, level)); + val = intel_uncore_read(&dev_priv->uncore, CUR_WM(pipe, level)); skl_wm_level_from_reg_val(val, &wm->wm[level]); } @@ -6242,9 +6242,9 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, wm->sagv_wm0 = wm->wm[0]; if (plane_id != PLANE_CURSOR) - val = I915_READ(PLANE_WM_TRANS(pipe, plane_id)); + val = intel_uncore_read(&dev_priv->uncore, PLANE_WM_TRANS(pipe, plane_id)); else - val = I915_READ(CUR_WM_TRANS(pipe)); + val = intel_uncore_read(&dev_priv->uncore, CUR_WM_TRANS(pipe)); skl_wm_level_from_reg_val(val, &wm->trans_wm); } @@ -6280,7 +6280,7 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) struct intel_pipe_wm *active = &crtc_state->wm.ilk.optimal; enum pipe pipe = crtc->pipe; - hw->wm_pipe[pipe] = I915_READ(WM0_PIPE_ILK(pipe)); + hw->wm_pipe[pipe] = intel_uncore_read(&dev_priv->uncore, WM0_PIPE_ILK(pipe)); memset(active, 0, sizeof(*active)); @@ -6324,13 +6324,13 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv, { u32 tmp; - tmp = I915_READ(DSPFW1); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1); wm->sr.plane = _FW_WM(tmp, SR); wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB); wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEB); wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEA); - tmp = I915_READ(DSPFW2); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2); wm->fbc_en = tmp & DSPFW_FBC_SR_EN; wm->sr.fbc = _FW_WM(tmp, FBC_SR); wm->hpll.fbc = _FW_WM(tmp, FBC_HPLL_SR); @@ -6338,7 +6338,7 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv, wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA); wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM(tmp, SPRITEA); - tmp = I915_READ(DSPFW3); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3); wm->hpll_en = tmp & DSPFW_HPLL_SR_EN; wm->sr.cursor = _FW_WM(tmp, CURSOR_SR); wm->hpll.cursor = _FW_WM(tmp, HPLL_CURSOR); @@ -6352,7 +6352,7 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, u32 tmp; for_each_pipe(dev_priv, pipe) { - tmp = I915_READ(VLV_DDL(pipe)); + tmp = intel_uncore_read(&dev_priv->uncore, VLV_DDL(pipe)); wm->ddl[pipe].plane[PLANE_PRIMARY] = (tmp >> DDL_PLANE_SHIFT) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); @@ -6364,34 +6364,34 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, (tmp >> DDL_SPRITE_SHIFT(1)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); } - tmp = I915_READ(DSPFW1); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1); wm->sr.plane = _FW_WM(tmp, SR); wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB); wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEB); wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEA); - tmp = I915_READ(DSPFW2); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2); wm->pipe[PIPE_A].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEB); wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA); wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEA); - tmp = I915_READ(DSPFW3); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3); wm->sr.cursor = _FW_WM(tmp, CURSOR_SR); if (IS_CHERRYVIEW(dev_priv)) { - tmp = I915_READ(DSPFW7_CHV); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW7_CHV); wm->pipe[PIPE_B].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITED); wm->pipe[PIPE_B].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEC); - tmp = I915_READ(DSPFW8_CHV); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW8_CHV); wm->pipe[PIPE_C].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEF); wm->pipe[PIPE_C].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEE); - tmp = I915_READ(DSPFW9_CHV); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW9_CHV); wm->pipe[PIPE_C].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEC); wm->pipe[PIPE_C].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORC); - tmp = I915_READ(DSPHOWM); + tmp = intel_uncore_read(&dev_priv->uncore, DSPHOWM); wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; wm->pipe[PIPE_C].plane[PLANE_SPRITE1] |= _FW_WM(tmp, SPRITEF_HI) << 8; wm->pipe[PIPE_C].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEE_HI) << 8; @@ -6403,11 +6403,11 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, wm->pipe[PIPE_A].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEA_HI) << 8; wm->pipe[PIPE_A].plane[PLANE_PRIMARY] |= _FW_WM(tmp, PLANEA_HI) << 8; } else { - tmp = I915_READ(DSPFW7); + tmp = intel_uncore_read(&dev_priv->uncore, DSPFW7); wm->pipe[PIPE_B].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITED); wm->pipe[PIPE_B].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEC); - tmp = I915_READ(DSPHOWM); + tmp = intel_uncore_read(&dev_priv->uncore, DSPHOWM); wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; wm->pipe[PIPE_B].plane[PLANE_SPRITE1] |= _FW_WM(tmp, SPRITED_HI) << 8; wm->pipe[PIPE_B].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEC_HI) << 8; @@ -6428,7 +6428,7 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) g4x_read_wm_values(dev_priv, wm); - wm->cxsr = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; + wm->cxsr = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; for_each_intel_crtc(&dev_priv->drm, crtc) { struct intel_crtc_state *crtc_state = @@ -6572,7 +6572,7 @@ void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) vlv_read_wm_values(dev_priv, wm); - wm->cxsr = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; + wm->cxsr = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; wm->level = VLV_WM_LEVEL_PM2; if (IS_CHERRYVIEW(dev_priv)) { @@ -6719,9 +6719,9 @@ void vlv_wm_sanitize(struct drm_i915_private *dev_priv) */ static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) { - I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN); - I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN); - I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); + intel_uncore_write(&dev_priv->uncore, WM3_LP_ILK, intel_uncore_read(&dev_priv->uncore, WM3_LP_ILK) & ~WM1_LP_SR_EN); + intel_uncore_write(&dev_priv->uncore, WM2_LP_ILK, intel_uncore_read(&dev_priv->uncore, WM2_LP_ILK) & ~WM1_LP_SR_EN); + intel_uncore_write(&dev_priv->uncore, WM1_LP_ILK, intel_uncore_read(&dev_priv->uncore, WM1_LP_ILK) & ~WM1_LP_SR_EN); /* * Don't touch WM1S_LP_EN here. @@ -6739,25 +6739,25 @@ void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) for_each_intel_crtc(&dev_priv->drm, crtc) ilk_pipe_wm_get_hw_state(crtc); - hw->wm_lp[0] = I915_READ(WM1_LP_ILK); - hw->wm_lp[1] = I915_READ(WM2_LP_ILK); - hw->wm_lp[2] = I915_READ(WM3_LP_ILK); + hw->wm_lp[0] = intel_uncore_read(&dev_priv->uncore, WM1_LP_ILK); + hw->wm_lp[1] = intel_uncore_read(&dev_priv->uncore, WM2_LP_ILK); + hw->wm_lp[2] = intel_uncore_read(&dev_priv->uncore, WM3_LP_ILK); - hw->wm_lp_spr[0] = I915_READ(WM1S_LP_ILK); + hw->wm_lp_spr[0] = intel_uncore_read(&dev_priv->uncore, WM1S_LP_ILK); if (INTEL_GEN(dev_priv) >= 7) { - hw->wm_lp_spr[1] = I915_READ(WM2S_LP_IVB); - hw->wm_lp_spr[2] = I915_READ(WM3S_LP_IVB); + hw->wm_lp_spr[1] = intel_uncore_read(&dev_priv->uncore, WM2S_LP_IVB); + hw->wm_lp_spr[2] = intel_uncore_read(&dev_priv->uncore, WM3S_LP_IVB); } if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - hw->partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ? + hw->partitioning = (intel_uncore_read(&dev_priv->uncore, WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ? INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; else if (IS_IVYBRIDGE(dev_priv)) - hw->partitioning = (I915_READ(DISP_ARB_CTL2) & DISP_DATA_PARTITION_5_6) ? + hw->partitioning = (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL2) & DISP_DATA_PARTITION_5_6) ? INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; hw->enable_fbc_wm = - !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS); + !(intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) & DISP_FBC_WM_DIS); } /** @@ -6808,14 +6808,14 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv) if (!HAS_IPC(dev_priv)) return; - val = I915_READ(DISP_ARB_CTL2); + val = intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL2); if (dev_priv->ipc_enabled) val |= DISP_IPC_ENABLE; else val &= ~DISP_IPC_ENABLE; - I915_WRITE(DISP_ARB_CTL2, val); + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL2, val); } static bool intel_can_enable_ipc(struct drm_i915_private *dev_priv) @@ -6850,7 +6850,7 @@ static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) * gating for the panel power sequencer or it will fail to * start up when no ports are active. */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); } static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) @@ -6858,12 +6858,12 @@ static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) enum pipe pipe; for_each_pipe(dev_priv, pipe) { - I915_WRITE(DSPCNTR(pipe), - I915_READ(DSPCNTR(pipe)) | + intel_uncore_write(&dev_priv->uncore, DSPCNTR(pipe), + intel_uncore_read(&dev_priv->uncore, DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); - I915_WRITE(DSPSURF(pipe), I915_READ(DSPSURF(pipe))); - POSTING_READ(DSPSURF(pipe)); + intel_uncore_write(&dev_priv->uncore, DSPSURF(pipe), intel_uncore_read(&dev_priv->uncore, DSPSURF(pipe))); + intel_uncore_posting_read(&dev_priv->uncore, DSPSURF(pipe)); } } @@ -6879,10 +6879,10 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) ILK_DPFCUNIT_CLOCK_GATE_DISABLE | ILK_DPFDUNIT_CLOCK_GATE_ENABLE; - I915_WRITE(PCH_3DCGDIS0, + intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS0, MARIUNIT_CLOCK_GATE_DISABLE | SVSMUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(PCH_3DCGDIS1, + intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS1, VFMUNIT_CLOCK_GATE_DISABLE); /* @@ -6892,12 +6892,12 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) * The bit 5 of 0x42020 * The bit 15 of 0x45000 */ - I915_WRITE(ILK_DISPLAY_CHICKEN2, - (I915_READ(ILK_DISPLAY_CHICKEN2) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, + (intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | ILK_DPARB_GATE | ILK_VSDPFD_FULL)); dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE; - I915_WRITE(DISP_ARB_CTL, - (I915_READ(DISP_ARB_CTL) | + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, + (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | DISP_FBC_WM_DIS)); /* @@ -6909,18 +6909,18 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) */ if (IS_IRONLAKE_M(dev_priv)) { /* WaFbcAsynchFlipDisableFbcQueue:ilk */ - I915_WRITE(ILK_DISPLAY_CHICKEN1, - I915_READ(ILK_DISPLAY_CHICKEN1) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1) | ILK_FBCQ_DIS); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | ILK_DPARB_GATE); } - I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate); + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | ILK_ELPIN_409_SELECT); g4x_disable_trickle_feed(dev_priv); @@ -6938,27 +6938,27 @@ static void cpt_init_clock_gating(struct drm_i915_private *dev_priv) * gating for the panel power sequencer or it will fail to * start up when no ports are active. */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | + intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | PCH_DPLUNIT_CLOCK_GATE_DISABLE | PCH_CPUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | + intel_uncore_write(&dev_priv->uncore, SOUTH_CHICKEN2, intel_uncore_read(&dev_priv->uncore, SOUTH_CHICKEN2) | DPLS_EDP_PPS_FIX_DIS); /* The below fixes the weird display corruption, a few pixels shifted * downward, on (only) LVDS of some HP laptops with IVY. */ for_each_pipe(dev_priv, pipe) { - val = I915_READ(TRANS_CHICKEN2(pipe)); + val = intel_uncore_read(&dev_priv->uncore, TRANS_CHICKEN2(pipe)); val |= TRANS_CHICKEN2_TIMING_OVERRIDE; val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; if (dev_priv->vbt.fdi_rx_polarity_inverted) val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER; val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH; - I915_WRITE(TRANS_CHICKEN2(pipe), val); + intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN2(pipe), val); } /* WADP0ClockGatingDisable */ for_each_pipe(dev_priv, pipe) { - I915_WRITE(TRANS_CHICKEN1(pipe), + intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN1(pipe), TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); } } @@ -6967,7 +6967,7 @@ static void gen6_check_mch_setup(struct drm_i915_private *dev_priv) { u32 tmp; - tmp = I915_READ(MCH_SSKPD); + tmp = intel_uncore_read(&dev_priv->uncore, MCH_SSKPD); if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL) drm_dbg_kms(&dev_priv->drm, "Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n", @@ -6978,14 +6978,14 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) { u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; - I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate); + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | ILK_ELPIN_409_SELECT); - I915_WRITE(GEN6_UCGCTL1, - I915_READ(GEN6_UCGCTL1) | + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1, + intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) | GEN6_BLBUNIT_CLOCK_GATE_DISABLE | GEN6_CSUNIT_CLOCK_GATE_DISABLE); @@ -7002,7 +7002,7 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) * WaDisableRCCUnitClockGating:snb * WaDisableRCPBUnitClockGating:snb */ - I915_WRITE(GEN6_UCGCTL2, + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); @@ -7017,14 +7017,14 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) * * WaFbcAsynchFlipDisableFbcQueue:snb */ - I915_WRITE(ILK_DISPLAY_CHICKEN1, - I915_READ(ILK_DISPLAY_CHICKEN1) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1) | ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | ILK_DPARB_GATE | ILK_VSDPFD_FULL); - I915_WRITE(ILK_DSPCLK_GATE_D, - I915_READ(ILK_DSPCLK_GATE_D) | + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, + intel_uncore_read(&dev_priv->uncore, ILK_DSPCLK_GATE_D) | ILK_DPARBUNIT_CLOCK_GATE_ENABLE | ILK_DPFDUNIT_CLOCK_GATE_ENABLE); @@ -7042,23 +7042,23 @@ static void lpt_init_clock_gating(struct drm_i915_private *dev_priv) * disabled when not needed anymore in order to save power. */ if (HAS_PCH_LPT_LP(dev_priv)) - I915_WRITE(SOUTH_DSPCLK_GATE_D, - I915_READ(SOUTH_DSPCLK_GATE_D) | + intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, + intel_uncore_read(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D) | PCH_LP_PARTITION_LEVEL_DISABLE); /* WADPOClockGatingDisable:hsw */ - I915_WRITE(TRANS_CHICKEN1(PIPE_A), - I915_READ(TRANS_CHICKEN1(PIPE_A)) | + intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN1(PIPE_A), + intel_uncore_read(&dev_priv->uncore, TRANS_CHICKEN1(PIPE_A)) | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); } static void lpt_suspend_hw(struct drm_i915_private *dev_priv) { if (HAS_PCH_LPT_LP(dev_priv)) { - u32 val = I915_READ(SOUTH_DSPCLK_GATE_D); + u32 val = intel_uncore_read(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D); val &= ~PCH_LP_PARTITION_LEVEL_DISABLE; - I915_WRITE(SOUTH_DSPCLK_GATE_D, val); + intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, val); } } @@ -7070,33 +7070,33 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, u32 val; /* WaTempDisableDOPClkGating:bdw */ - misccpctl = I915_READ(GEN7_MISCCPCTL); - I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); + misccpctl = intel_uncore_read(&dev_priv->uncore, GEN7_MISCCPCTL); + intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); - val = I915_READ(GEN8_L3SQCREG1); + val = intel_uncore_read(&dev_priv->uncore, GEN8_L3SQCREG1); val &= ~L3_PRIO_CREDITS_MASK; val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits); val |= L3_HIGH_PRIO_CREDITS(high_prio_credits); - I915_WRITE(GEN8_L3SQCREG1, val); + intel_uncore_write(&dev_priv->uncore, GEN8_L3SQCREG1, val); /* * Wait at least 100 clocks before re-enabling clock gating. * See the definition of L3SQCREG1 in BSpec. */ - POSTING_READ(GEN8_L3SQCREG1); + intel_uncore_posting_read(&dev_priv->uncore, GEN8_L3SQCREG1); udelay(1); - I915_WRITE(GEN7_MISCCPCTL, misccpctl); + intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl); } static void icl_init_clock_gating(struct drm_i915_private *dev_priv) { /* Wa_1409120013:icl,ehl */ - I915_WRITE(ILK_DPFC_CHICKEN, + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL); /* This is not an Wa. Enable to reduce Sampler power */ - I915_WRITE(GEN10_DFR_RATIO_EN_AND_CHICKEN, - I915_READ(GEN10_DFR_RATIO_EN_AND_CHICKEN) & ~DFR_DISABLE); + intel_uncore_write(&dev_priv->uncore, GEN10_DFR_RATIO_EN_AND_CHICKEN, + intel_uncore_read(&dev_priv->uncore, GEN10_DFR_RATIO_EN_AND_CHICKEN) & ~DFR_DISABLE); /*Wa_14010594013:icl, ehl */ intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, @@ -7120,12 +7120,12 @@ static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) gen12_init_clock_gating(dev_priv); /* Wa_1409120013:tgl */ - I915_WRITE(ILK_DPFC_CHICKEN, + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL); /* Wa_1409825376:tgl (pre-prod)*/ if (IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_B1)) - I915_WRITE(GEN9_CLKGATE_DIS_3, I915_READ(GEN9_CLKGATE_DIS_3) | + intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_3, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_3) | TGL_VRH_GATING_DIS); /* Wa_14011059788:tgl */ @@ -7139,7 +7139,7 @@ static void dg1_init_clock_gating(struct drm_i915_private *dev_priv) /* Wa_1409836686:dg1[a0] */ if (IS_DG1_REVID(dev_priv, DG1_REVID_A0, DG1_REVID_A0)) - I915_WRITE(GEN9_CLKGATE_DIS_3, I915_READ(GEN9_CLKGATE_DIS_3) | + intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_3, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_3) | DPT_GATING_DIS); } @@ -7149,7 +7149,7 @@ static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) return; /* Display WA #1181 WaSouthDisplayDisablePWMCGEGating: cnp */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, I915_READ(SOUTH_DSPCLK_GATE_D) | + intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, intel_uncore_read(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D) | CNP_PWM_CGE_GATING_DISABLE); } @@ -7159,35 +7159,35 @@ static void cnl_init_clock_gating(struct drm_i915_private *dev_priv) cnp_init_clock_gating(dev_priv); /* This is not an Wa. Enable for better image quality */ - I915_WRITE(_3D_CHICKEN3, + intel_uncore_write(&dev_priv->uncore, _3D_CHICKEN3, _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE)); /* WaEnableChickenDCPR:cnl */ - I915_WRITE(GEN8_CHICKEN_DCPR_1, - I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); + intel_uncore_write(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, + intel_uncore_read(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); /* * WaFbcWakeMemOn:cnl * Display WA #0859: cnl */ - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | DISP_FBC_MEMORY_WAKE); - val = I915_READ(SLICE_UNIT_LEVEL_CLKGATE); + val = intel_uncore_read(&dev_priv->uncore, SLICE_UNIT_LEVEL_CLKGATE); /* ReadHitWriteOnlyDisable:cnl */ val |= RCCUNIT_CLKGATE_DIS; - I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, val); + intel_uncore_write(&dev_priv->uncore, SLICE_UNIT_LEVEL_CLKGATE, val); /* Wa_2201832410:cnl */ - val = I915_READ(SUBSLICE_UNIT_LEVEL_CLKGATE); + val = intel_uncore_read(&dev_priv->uncore, SUBSLICE_UNIT_LEVEL_CLKGATE); val |= GWUNIT_CLKGATE_DIS; - I915_WRITE(SUBSLICE_UNIT_LEVEL_CLKGATE, val); + intel_uncore_write(&dev_priv->uncore, SUBSLICE_UNIT_LEVEL_CLKGATE, val); /* WaDisableVFclkgate:cnl */ /* WaVFUnitClockGatingDisable:cnl */ - val = I915_READ(UNSLICE_UNIT_LEVEL_CLKGATE); + val = intel_uncore_read(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE); val |= VFUNIT_CLKGATE_DIS; - I915_WRITE(UNSLICE_UNIT_LEVEL_CLKGATE, val); + intel_uncore_write(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE, val); } static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) @@ -7196,21 +7196,21 @@ static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) gen9_init_clock_gating(dev_priv); /* WAC6entrylatency:cfl */ - I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) | + intel_uncore_write(&dev_priv->uncore, FBC_LLC_READ_CTRL, intel_uncore_read(&dev_priv->uncore, FBC_LLC_READ_CTRL) | FBC_LLC_FULLY_OPEN); /* * WaFbcTurnOffFbcWatermark:cfl * Display WA #0562: cfl */ - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | DISP_FBC_WM_DIS); /* * WaFbcNukeOnHostModify:cfl * Display WA #0873: cfl */ - I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); } @@ -7219,31 +7219,31 @@ static void kbl_init_clock_gating(struct drm_i915_private *dev_priv) gen9_init_clock_gating(dev_priv); /* WAC6entrylatency:kbl */ - I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) | + intel_uncore_write(&dev_priv->uncore, FBC_LLC_READ_CTRL, intel_uncore_read(&dev_priv->uncore, FBC_LLC_READ_CTRL) | FBC_LLC_FULLY_OPEN); /* WaDisableSDEUnitClockGating:kbl */ if (IS_KBL_GT_REVID(dev_priv, 0, KBL_REVID_B0)) - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + intel_uncore_write(&dev_priv->uncore, GEN8_UCGCTL6, intel_uncore_read(&dev_priv->uncore, GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaDisableGamClockGating:kbl */ if (IS_KBL_GT_REVID(dev_priv, 0, KBL_REVID_B0)) - I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1, intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) | GEN6_GAMUNIT_CLOCK_GATE_DISABLE); /* * WaFbcTurnOffFbcWatermark:kbl * Display WA #0562: kbl */ - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | DISP_FBC_WM_DIS); /* * WaFbcNukeOnHostModify:kbl * Display WA #0873: kbl */ - I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); } @@ -7252,32 +7252,32 @@ static void skl_init_clock_gating(struct drm_i915_private *dev_priv) gen9_init_clock_gating(dev_priv); /* WaDisableDopClockGating:skl */ - I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL) & + intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, intel_uncore_read(&dev_priv->uncore, GEN7_MISCCPCTL) & ~GEN7_DOP_CLOCK_GATE_ENABLE); /* WAC6entrylatency:skl */ - I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) | + intel_uncore_write(&dev_priv->uncore, FBC_LLC_READ_CTRL, intel_uncore_read(&dev_priv->uncore, FBC_LLC_READ_CTRL) | FBC_LLC_FULLY_OPEN); /* * WaFbcTurnOffFbcWatermark:skl * Display WA #0562: skl */ - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | DISP_FBC_WM_DIS); /* * WaFbcNukeOnHostModify:skl * Display WA #0873: skl */ - I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); /* * WaFbcHighMemBwCorruptionAvoidance:skl * Display WA #0883: skl */ - I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN, intel_uncore_read(&dev_priv->uncore, ILK_DPFC_CHICKEN) | ILK_DPFC_DISABLE_DUMMY0); } @@ -7286,42 +7286,42 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) enum pipe pipe; /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - I915_WRITE(CHICKEN_PIPESL_1(PIPE_A), - I915_READ(CHICKEN_PIPESL_1(PIPE_A)) | + intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), + intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A)) | HSW_FBCQ_DIS); /* WaSwitchSolVfFArbitrationPriority:bdw */ - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); + intel_uncore_write(&dev_priv->uncore, GAM_ECOCHK, intel_uncore_read(&dev_priv->uncore, GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); /* WaPsrDPAMaskVBlankInSRD:bdw */ - I915_WRITE(CHICKEN_PAR1_1, - I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); + intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1, + intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ for_each_pipe(dev_priv, pipe) { - I915_WRITE(CHICKEN_PIPESL_1(pipe), - I915_READ(CHICKEN_PIPESL_1(pipe)) | + intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), + intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe)) | BDW_DPRS_MASK_VBLANK_SRD); } /* WaVSRefCountFullforceMissDisable:bdw */ /* WaDSRefCountFullforceMissDisable:bdw */ - I915_WRITE(GEN7_FF_THREAD_MODE, - I915_READ(GEN7_FF_THREAD_MODE) & + intel_uncore_write(&dev_priv->uncore, GEN7_FF_THREAD_MODE, + intel_uncore_read(&dev_priv->uncore, GEN7_FF_THREAD_MODE) & ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME)); - I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL, + intel_uncore_write(&dev_priv->uncore, GEN6_RC_SLEEP_PSMI_CONTROL, _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); /* WaDisableSDEUnitClockGating:bdw */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + intel_uncore_write(&dev_priv->uncore, GEN8_UCGCTL6, intel_uncore_read(&dev_priv->uncore, GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaProgramL3SqcReg1Default:bdw */ gen8_set_l3sqc_credits(dev_priv, 30, 2); /* WaKVMNotificationOnConfigChange:bdw */ - I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1) + intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR2_1, intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR2_1) | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); lpt_init_clock_gating(dev_priv); @@ -7331,24 +7331,24 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP * clock gating. */ - I915_WRITE(GEN6_UCGCTL1, - I915_READ(GEN6_UCGCTL1) | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1, + intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) | GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); } static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) { /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - I915_WRITE(CHICKEN_PIPESL_1(PIPE_A), - I915_READ(CHICKEN_PIPESL_1(PIPE_A)) | + intel_uncore_write(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), + intel_uncore_read(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A)) | HSW_FBCQ_DIS); /* This is required by WaCatErrorRejectionIssue:hsw */ - I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + intel_uncore_write(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + intel_uncore_read(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); /* WaSwitchSolVfFArbitrationPriority:hsw */ - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); + intel_uncore_write(&dev_priv->uncore, GAM_ECOCHK, intel_uncore_read(&dev_priv->uncore, GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); lpt_init_clock_gating(dev_priv); } @@ -7357,26 +7357,26 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) { u32 snpcr; - I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); /* WaFbcAsynchFlipDisableFbcQueue:ivb */ - I915_WRITE(ILK_DISPLAY_CHICKEN1, - I915_READ(ILK_DISPLAY_CHICKEN1) | + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1) | ILK_FBCQ_DIS); /* WaDisableBackToBackFlipFix:ivb */ - I915_WRITE(IVB_CHICKEN3, + intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | CHICKEN3_DGMG_DONE_FIX_DISABLE); if (IS_IVB_GT1(dev_priv)) - I915_WRITE(GEN7_ROW_CHICKEN2, + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); else { /* must write both registers */ - I915_WRITE(GEN7_ROW_CHICKEN2, + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); - I915_WRITE(GEN7_ROW_CHICKEN2_GT2, + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2_GT2, _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); } @@ -7384,20 +7384,20 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) * According to the spec, bit 13 (RCZUNIT) must be set on IVB. * This implements the WaDisableRCZUnitClockGating:ivb workaround. */ - I915_WRITE(GEN6_UCGCTL2, + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); /* This is required by WaCatErrorRejectionIssue:ivb */ - I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + intel_uncore_write(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + intel_uncore_read(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); g4x_disable_trickle_feed(dev_priv); - snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); + snpcr = intel_uncore_read(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR); snpcr &= ~GEN6_MBC_SNPCR_MASK; snpcr |= GEN6_MBC_SNPCR_MED; - I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); + intel_uncore_write(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, snpcr); if (!HAS_PCH_NOP(dev_priv)) cpt_init_clock_gating(dev_priv); @@ -7408,58 +7408,58 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) { /* WaDisableBackToBackFlipFix:vlv */ - I915_WRITE(IVB_CHICKEN3, + intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | CHICKEN3_DGMG_DONE_FIX_DISABLE); /* WaDisableDopClockGating:vlv */ - I915_WRITE(GEN7_ROW_CHICKEN2, + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); /* This is required by WaCatErrorRejectionIssue:vlv */ - I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + intel_uncore_write(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + intel_uncore_read(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); /* * According to the spec, bit 13 (RCZUNIT) must be set on IVB. * This implements the WaDisableRCZUnitClockGating:vlv workaround. */ - I915_WRITE(GEN6_UCGCTL2, + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); /* WaDisableL3Bank2xClockGate:vlv * Disabling L3 clock gating- MMIO 940c[25] = 1 * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ - I915_WRITE(GEN7_UCGCTL4, - I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, GEN7_UCGCTL4, + intel_uncore_read(&dev_priv->uncore, GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE); /* * WaDisableVLVClockGating_VBIIssue:vlv * Disable clock gating on th GCFG unit to prevent a delay * in the reporting of vblank events. */ - I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS); + intel_uncore_write(&dev_priv->uncore, VLV_GUNIT_CLOCK_GATE, GCFG_DIS); } static void chv_init_clock_gating(struct drm_i915_private *dev_priv) { /* WaVSRefCountFullforceMissDisable:chv */ /* WaDSRefCountFullforceMissDisable:chv */ - I915_WRITE(GEN7_FF_THREAD_MODE, - I915_READ(GEN7_FF_THREAD_MODE) & + intel_uncore_write(&dev_priv->uncore, GEN7_FF_THREAD_MODE, + intel_uncore_read(&dev_priv->uncore, GEN7_FF_THREAD_MODE) & ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME)); /* WaDisableSemaphoreAndSyncFlipWait:chv */ - I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL, + intel_uncore_write(&dev_priv->uncore, GEN6_RC_SLEEP_PSMI_CONTROL, _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); /* WaDisableCSUnitClockGating:chv */ - I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1, intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) | GEN6_CSUNIT_CLOCK_GATE_DISABLE); /* WaDisableSDEUnitClockGating:chv */ - I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + intel_uncore_write(&dev_priv->uncore, GEN8_UCGCTL6, intel_uncore_read(&dev_priv->uncore, GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* @@ -7474,17 +7474,17 @@ static void g4x_init_clock_gating(struct drm_i915_private *dev_priv) { u32 dspclk_gate; - I915_WRITE(RENCLK_GATE_D1, 0); - I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, 0); + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | GS_UNIT_CLOCK_GATE_DISABLE | CL_UNIT_CLOCK_GATE_DISABLE); - I915_WRITE(RAMCLK_GATE_D, 0); + intel_uncore_write(&dev_priv->uncore, RAMCLK_GATE_D, 0); dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | OVRUNIT_CLOCK_GATE_DISABLE | OVCUNIT_CLOCK_GATE_DISABLE; if (IS_GM45(dev_priv)) dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; - I915_WRITE(DSPCLK_GATE_D, dspclk_gate); + intel_uncore_write(&dev_priv->uncore, DSPCLK_GATE_D, dspclk_gate); g4x_disable_trickle_feed(dev_priv); } @@ -7505,49 +7505,49 @@ static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv) static void i965g_init_clock_gating(struct drm_i915_private *dev_priv) { - I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | I965_RCC_CLOCK_GATE_DISABLE | I965_RCPB_CLOCK_GATE_DISABLE | I965_ISC_CLOCK_GATE_DISABLE | I965_FBC_CLOCK_GATE_DISABLE); - I915_WRITE(RENCLK_GATE_D2, 0); - I915_WRITE(MI_ARB_STATE, + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, 0); + intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); } static void gen3_init_clock_gating(struct drm_i915_private *dev_priv) { - u32 dstate = I915_READ(D_STATE); + u32 dstate = intel_uncore_read(&dev_priv->uncore, D_STATE); dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | DSTATE_DOT_CLOCK_GATING; - I915_WRITE(D_STATE, dstate); + intel_uncore_write(&dev_priv->uncore, D_STATE, dstate); if (IS_PINEVIEW(dev_priv)) - I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); + intel_uncore_write(&dev_priv->uncore, ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); /* IIR "flip pending" means done if this bit is set */ - I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); + intel_uncore_write(&dev_priv->uncore, ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); /* interrupts should cause a wake up from C3 */ - I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); + intel_uncore_write(&dev_priv->uncore, INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ - I915_WRITE(MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); + intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); - I915_WRITE(MI_ARB_STATE, + intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); } static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) { - I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); /* interrupts should cause a wake up from C3 */ - I915_WRITE(MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | + intel_uncore_write(&dev_priv->uncore, MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); - I915_WRITE(MEM_MODE, + intel_uncore_write(&dev_priv->uncore, MEM_MODE, _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); /* @@ -7557,13 +7557,13 @@ static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) * abosultely nothing) would not allow FBC to recompress * until a 2D blit occurs. */ - I915_WRITE(SCPD0, + intel_uncore_write(&dev_priv->uncore, SCPD0, _MASKED_BIT_ENABLE(SCPD_FBC_IGNORE_3D)); } static void i830_init_clock_gating(struct drm_i915_private *dev_priv) { - I915_WRITE(MEM_MODE, + intel_uncore_write(&dev_priv->uncore, MEM_MODE, _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); } From 2939eb068289be2d14802deb4db6143bc84cc689 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:15:59 +0200 Subject: [PATCH 0104/5577] drm/i915/irq: replace I915_READ()/WRITE() with intel_uncore_read()/write() Arguably some of these should use intel_de_read() or intel_de_write(), however not all. Prioritize I915_READ() and I915_WRITE() removal in general over migrating to the pedantically correct replacements right away. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-8-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 336 ++++++++++++++++---------------- 1 file changed, 168 insertions(+), 168 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c80eeac53952..b245109f73e3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -309,10 +309,10 @@ i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv, lockdep_assert_held(&dev_priv->irq_lock); drm_WARN_ON(&dev_priv->drm, bits & ~mask); - val = I915_READ(PORT_HOTPLUG_EN); + val = intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_EN); val &= ~mask; val |= bits; - I915_WRITE(PORT_HOTPLUG_EN, val); + intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_EN, val); } /** @@ -358,8 +358,8 @@ void ilk_update_display_irq(struct drm_i915_private *dev_priv, if (new_val != dev_priv->irq_mask && !drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) { dev_priv->irq_mask = new_val; - I915_WRITE(DEIMR, dev_priv->irq_mask); - POSTING_READ(DEIMR); + intel_uncore_write(&dev_priv->uncore, DEIMR, dev_priv->irq_mask); + intel_uncore_posting_read(&dev_priv->uncore, DEIMR); } } @@ -383,15 +383,15 @@ static void bdw_update_port_irq(struct drm_i915_private *dev_priv, if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) return; - old_val = I915_READ(GEN8_DE_PORT_IMR); + old_val = intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IMR); new_val = old_val; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != old_val) { - I915_WRITE(GEN8_DE_PORT_IMR, new_val); - POSTING_READ(GEN8_DE_PORT_IMR); + intel_uncore_write(&dev_priv->uncore, GEN8_DE_PORT_IMR, new_val); + intel_uncore_posting_read(&dev_priv->uncore, GEN8_DE_PORT_IMR); } } @@ -422,8 +422,8 @@ void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, if (new_val != dev_priv->de_irq_mask[pipe]) { dev_priv->de_irq_mask[pipe] = new_val; - I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); - POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); + intel_uncore_write(&dev_priv->uncore, GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); + intel_uncore_posting_read(&dev_priv->uncore, GEN8_DE_PIPE_IMR(pipe)); } } @@ -437,7 +437,7 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, u32 interrupt_mask, u32 enabled_irq_mask) { - u32 sdeimr = I915_READ(SDEIMR); + u32 sdeimr = intel_uncore_read(&dev_priv->uncore, SDEIMR); sdeimr &= ~interrupt_mask; sdeimr |= (~enabled_irq_mask & interrupt_mask); @@ -448,8 +448,8 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) return; - I915_WRITE(SDEIMR, sdeimr); - POSTING_READ(SDEIMR); + intel_uncore_write(&dev_priv->uncore, SDEIMR, sdeimr); + intel_uncore_posting_read(&dev_priv->uncore, SDEIMR); } u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, @@ -515,8 +515,8 @@ void i915_enable_pipestat(struct drm_i915_private *dev_priv, dev_priv->pipestat_irq_mask[pipe] |= status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); - I915_WRITE(reg, enable_mask | status_mask); - POSTING_READ(reg); + intel_uncore_write(&dev_priv->uncore, reg, enable_mask | status_mask); + intel_uncore_posting_read(&dev_priv->uncore, reg); } void i915_disable_pipestat(struct drm_i915_private *dev_priv, @@ -538,8 +538,8 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv, dev_priv->pipestat_irq_mask[pipe] &= ~status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); - I915_WRITE(reg, enable_mask | status_mask); - POSTING_READ(reg); + intel_uncore_write(&dev_priv->uncore, reg, enable_mask | status_mask); + intel_uncore_posting_read(&dev_priv->uncore, reg); } static bool i915_has_asle(struct drm_i915_private *dev_priv) @@ -697,7 +697,7 @@ u32 g4x_get_vblank_counter(struct drm_crtc *crtc) if (!vblank->max_vblank_count) return 0; - return I915_READ(PIPE_FRMCOUNT_G4X(pipe)); + return intel_uncore_read(&dev_priv->uncore, PIPE_FRMCOUNT_G4X(pipe)); } /* @@ -986,9 +986,9 @@ static void ivb_parity_work(struct work_struct *work) if (drm_WARN_ON(&dev_priv->drm, !dev_priv->l3_parity.which_slice)) goto out; - misccpctl = I915_READ(GEN7_MISCCPCTL); - I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); - POSTING_READ(GEN7_MISCCPCTL); + misccpctl = intel_uncore_read(&dev_priv->uncore, GEN7_MISCCPCTL); + intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); + intel_uncore_posting_read(&dev_priv->uncore, GEN7_MISCCPCTL); while ((slice = ffs(dev_priv->l3_parity.which_slice)) != 0) { i915_reg_t reg; @@ -1002,13 +1002,13 @@ static void ivb_parity_work(struct work_struct *work) reg = GEN7_L3CDERRST1(slice); - error_status = I915_READ(reg); + error_status = intel_uncore_read(&dev_priv->uncore, reg); row = GEN7_PARITY_ERROR_ROW(error_status); bank = GEN7_PARITY_ERROR_BANK(error_status); subbank = GEN7_PARITY_ERROR_SUBBANK(error_status); - I915_WRITE(reg, GEN7_PARITY_ERROR_VALID | GEN7_L3CDERRST1_ENABLE); - POSTING_READ(reg); + intel_uncore_write(&dev_priv->uncore, reg, GEN7_PARITY_ERROR_VALID | GEN7_L3CDERRST1_ENABLE); + intel_uncore_posting_read(&dev_priv->uncore, reg); parity_event[0] = I915_L3_PARITY_UEVENT "=1"; parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row); @@ -1029,7 +1029,7 @@ static void ivb_parity_work(struct work_struct *work) kfree(parity_event[1]); } - I915_WRITE(GEN7_MISCCPCTL, misccpctl); + intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl); out: drm_WARN_ON(&dev_priv->drm, dev_priv->l3_parity.which_slice); @@ -1319,7 +1319,7 @@ static void hsw_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { display_pipe_crc_irq_handler(dev_priv, pipe, - I915_READ(PIPE_CRC_RES_1_IVB(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_1_IVB(pipe)), 0, 0, 0, 0); } @@ -1327,11 +1327,11 @@ static void ivb_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { display_pipe_crc_irq_handler(dev_priv, pipe, - I915_READ(PIPE_CRC_RES_1_IVB(pipe)), - I915_READ(PIPE_CRC_RES_2_IVB(pipe)), - I915_READ(PIPE_CRC_RES_3_IVB(pipe)), - I915_READ(PIPE_CRC_RES_4_IVB(pipe)), - I915_READ(PIPE_CRC_RES_5_IVB(pipe))); + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_1_IVB(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_2_IVB(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_3_IVB(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_4_IVB(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_5_IVB(pipe))); } static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, @@ -1340,19 +1340,19 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, u32 res1, res2; if (INTEL_GEN(dev_priv) >= 3) - res1 = I915_READ(PIPE_CRC_RES_RES1_I915(pipe)); + res1 = intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RES1_I915(pipe)); else res1 = 0; if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) - res2 = I915_READ(PIPE_CRC_RES_RES2_G4X(pipe)); + res2 = intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RES2_G4X(pipe)); else res2 = 0; display_pipe_crc_irq_handler(dev_priv, pipe, - I915_READ(PIPE_CRC_RES_RED(pipe)), - I915_READ(PIPE_CRC_RES_GREEN(pipe)), - I915_READ(PIPE_CRC_RES_BLUE(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RED(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_GREEN(pipe)), + intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_BLUE(pipe)), res1, res2); } @@ -1361,7 +1361,7 @@ static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) enum pipe pipe; for_each_pipe(dev_priv, pipe) { - I915_WRITE(PIPESTAT(pipe), + intel_uncore_write(&dev_priv->uncore, PIPESTAT(pipe), PIPESTAT_INT_STATUS_MASK | PIPE_FIFO_UNDERRUN_STATUS); @@ -1415,7 +1415,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, continue; reg = PIPESTAT(pipe); - pipe_stats[pipe] = I915_READ(reg) & status_mask; + pipe_stats[pipe] = intel_uncore_read(&dev_priv->uncore, reg) & status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); /* @@ -1428,8 +1428,8 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, * an interrupt is still pending. */ if (pipe_stats[pipe]) { - I915_WRITE(reg, pipe_stats[pipe]); - I915_WRITE(reg, enable_mask); + intel_uncore_write(&dev_priv->uncore, reg, pipe_stats[pipe]); + intel_uncore_write(&dev_priv->uncore, reg, enable_mask); } } spin_unlock(&dev_priv->irq_lock); @@ -1545,18 +1545,18 @@ static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv) * bits can itself generate a new hotplug interrupt :( */ for (i = 0; i < 10; i++) { - u32 tmp = I915_READ(PORT_HOTPLUG_STAT) & hotplug_status_mask; + u32 tmp = intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT) & hotplug_status_mask; if (tmp == 0) return hotplug_status; hotplug_status |= tmp; - I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); + intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, hotplug_status); } drm_WARN_ONCE(&dev_priv->drm, 1, "PORT_HOTPLUG_STAT did not clear (0x%08x)\n", - I915_READ(PORT_HOTPLUG_STAT)); + intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT)); return hotplug_status; } @@ -1605,9 +1605,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) u32 hotplug_status = 0; u32 ier = 0; - gt_iir = I915_READ(GTIIR); - pm_iir = I915_READ(GEN6_PMIIR); - iir = I915_READ(VLV_IIR); + gt_iir = intel_uncore_read(&dev_priv->uncore, GTIIR); + pm_iir = intel_uncore_read(&dev_priv->uncore, GEN6_PMIIR); + iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR); if (gt_iir == 0 && pm_iir == 0 && iir == 0) break; @@ -1627,14 +1627,14 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) * don't end up clearing all the VLV_IIR, GT_IIR, GEN6_PMIIR * bits this time around. */ - I915_WRITE(VLV_MASTER_IER, 0); - ier = I915_READ(VLV_IER); - I915_WRITE(VLV_IER, 0); + intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, 0); + ier = intel_uncore_read(&dev_priv->uncore, VLV_IER); + intel_uncore_write(&dev_priv->uncore, VLV_IER, 0); if (gt_iir) - I915_WRITE(GTIIR, gt_iir); + intel_uncore_write(&dev_priv->uncore, GTIIR, gt_iir); if (pm_iir) - I915_WRITE(GEN6_PMIIR, pm_iir); + intel_uncore_write(&dev_priv->uncore, GEN6_PMIIR, pm_iir); if (iir & I915_DISPLAY_PORT_INTERRUPT) hotplug_status = i9xx_hpd_irq_ack(dev_priv); @@ -1652,10 +1652,10 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. */ if (iir) - I915_WRITE(VLV_IIR, iir); + intel_uncore_write(&dev_priv->uncore, VLV_IIR, iir); - I915_WRITE(VLV_IER, ier); - I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); + intel_uncore_write(&dev_priv->uncore, VLV_IER, ier); + intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); if (gt_iir) gen6_gt_irq_handler(&dev_priv->gt, gt_iir); @@ -1690,8 +1690,8 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) u32 hotplug_status = 0; u32 ier = 0; - master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; - iir = I915_READ(VLV_IIR); + master_ctl = intel_uncore_read(&dev_priv->uncore, GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; + iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR); if (master_ctl == 0 && iir == 0) break; @@ -1711,9 +1711,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) * don't end up clearing all the VLV_IIR and GEN8_MASTER_IRQ_CONTROL * bits this time around. */ - I915_WRITE(GEN8_MASTER_IRQ, 0); - ier = I915_READ(VLV_IER); - I915_WRITE(VLV_IER, 0); + intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, 0); + ier = intel_uncore_read(&dev_priv->uncore, VLV_IER); + intel_uncore_write(&dev_priv->uncore, VLV_IER, 0); gen8_gt_irq_handler(&dev_priv->gt, master_ctl); @@ -1734,10 +1734,10 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. */ if (iir) - I915_WRITE(VLV_IIR, iir); + intel_uncore_write(&dev_priv->uncore, VLV_IIR, iir); - I915_WRITE(VLV_IER, ier); - I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); + intel_uncore_write(&dev_priv->uncore, VLV_IER, ier); + intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); if (hotplug_status) i9xx_hpd_irq_handler(dev_priv, hotplug_status); @@ -1761,7 +1761,7 @@ static void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv, * zero. Not acking leads to "The master control interrupt lied (SDE)!" * errors. */ - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG); if (!hotplug_trigger) { u32 mask = PORTA_HOTPLUG_STATUS_MASK | PORTD_HOTPLUG_STATUS_MASK | @@ -1770,7 +1770,7 @@ static void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv, dig_hotplug_reg &= ~mask; } - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg); if (!hotplug_trigger) return; @@ -1815,7 +1815,7 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) for_each_pipe(dev_priv, pipe) drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), - I915_READ(FDI_RX_IIR(pipe))); + intel_uncore_read(&dev_priv->uncore, FDI_RX_IIR(pipe))); } if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) @@ -1834,7 +1834,7 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) static void ivb_err_int_handler(struct drm_i915_private *dev_priv) { - u32 err_int = I915_READ(GEN7_ERR_INT); + u32 err_int = intel_uncore_read(&dev_priv->uncore, GEN7_ERR_INT); enum pipe pipe; if (err_int & ERR_INT_POISON) @@ -1852,12 +1852,12 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) } } - I915_WRITE(GEN7_ERR_INT, err_int); + intel_uncore_write(&dev_priv->uncore, GEN7_ERR_INT, err_int); } static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) { - u32 serr_int = I915_READ(SERR_INT); + u32 serr_int = intel_uncore_read(&dev_priv->uncore, SERR_INT); enum pipe pipe; if (serr_int & SERR_INT_POISON) @@ -1867,7 +1867,7 @@ static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) if (serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pipe)) intel_pch_fifo_underrun_irq_handler(dev_priv, pipe); - I915_WRITE(SERR_INT, serr_int); + intel_uncore_write(&dev_priv->uncore, SERR_INT, serr_int); } static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) @@ -1900,7 +1900,7 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) for_each_pipe(dev_priv, pipe) drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), - I915_READ(FDI_RX_IIR(pipe))); + intel_uncore_read(&dev_priv->uncore, FDI_RX_IIR(pipe))); } if (pch_iir & SDE_ERROR_CPT) @@ -1916,8 +1916,8 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) if (ddi_hotplug_trigger) { u32 dig_hotplug_reg; - dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_DDI); - I915_WRITE(SHOTPLUG_CTL_DDI, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_DDI); + intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_DDI, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, ddi_hotplug_trigger, dig_hotplug_reg, @@ -1928,8 +1928,8 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) if (tc_hotplug_trigger) { u32 dig_hotplug_reg; - dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_TC); - I915_WRITE(SHOTPLUG_CTL_TC, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_TC); + intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_TC, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, tc_hotplug_trigger, dig_hotplug_reg, @@ -1954,8 +1954,8 @@ static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) if (hotplug_trigger) { u32 dig_hotplug_reg; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, @@ -1966,8 +1966,8 @@ static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) if (hotplug2_trigger) { u32 dig_hotplug_reg; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2); - I915_WRITE(PCH_PORT_HOTPLUG2, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG2); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG2, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug2_trigger, dig_hotplug_reg, @@ -1987,8 +1987,8 @@ static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv, { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; - dig_hotplug_reg = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL); - I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL); + intel_uncore_write(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, @@ -2029,7 +2029,7 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv, /* check event from PCH */ if (de_iir & DE_PCH_EVENT) { - u32 pch_iir = I915_READ(SDEIIR); + u32 pch_iir = intel_uncore_read(&dev_priv->uncore, SDEIIR); if (HAS_PCH_CPT(dev_priv)) cpt_irq_handler(dev_priv, pch_iir); @@ -2037,7 +2037,7 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv, ibx_irq_handler(dev_priv, pch_iir); /* should clear PCH hotplug event before clear CPU irq */ - I915_WRITE(SDEIIR, pch_iir); + intel_uncore_write(&dev_priv->uncore, SDEIIR, pch_iir); } if (IS_GEN(dev_priv, 5) && de_iir & DE_PCU_EVENT) @@ -2057,10 +2057,10 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv, ivb_err_int_handler(dev_priv); if (de_iir & DE_EDP_PSR_INT_HSW) { - u32 psr_iir = I915_READ(EDP_PSR_IIR); + u32 psr_iir = intel_uncore_read(&dev_priv->uncore, EDP_PSR_IIR); intel_psr_irq_handler(dev_priv, psr_iir); - I915_WRITE(EDP_PSR_IIR, psr_iir); + intel_uncore_write(&dev_priv->uncore, EDP_PSR_IIR, psr_iir); } if (de_iir & DE_AUX_CHANNEL_A_IVB) @@ -2076,12 +2076,12 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv, /* check event from PCH */ if (!HAS_PCH_NOP(dev_priv) && (de_iir & DE_PCH_EVENT_IVB)) { - u32 pch_iir = I915_READ(SDEIIR); + u32 pch_iir = intel_uncore_read(&dev_priv->uncore, SDEIIR); cpt_irq_handler(dev_priv, pch_iir); /* clear PCH hotplug event before clear CPU irq */ - I915_WRITE(SDEIIR, pch_iir); + intel_uncore_write(&dev_priv->uncore, SDEIIR, pch_iir); } } @@ -2166,8 +2166,8 @@ static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv, { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, @@ -2186,8 +2186,8 @@ static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir) if (trigger_tc) { u32 dig_hotplug_reg; - dig_hotplug_reg = I915_READ(GEN11_TC_HOTPLUG_CTL); - I915_WRITE(GEN11_TC_HOTPLUG_CTL, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL); + intel_uncore_write(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, trigger_tc, dig_hotplug_reg, @@ -2198,8 +2198,8 @@ static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir) if (trigger_tbt) { u32 dig_hotplug_reg; - dig_hotplug_reg = I915_READ(GEN11_TBT_HOTPLUG_CTL); - I915_WRITE(GEN11_TBT_HOTPLUG_CTL, dig_hotplug_reg); + dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL); + intel_uncore_write(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, trigger_tbt, dig_hotplug_reg, @@ -2276,8 +2276,8 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) else iir_reg = EDP_PSR_IIR; - psr_iir = I915_READ(iir_reg); - I915_WRITE(iir_reg, psr_iir); + psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg); + intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir); if (psr_iir) found = true; @@ -2301,7 +2301,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, * Incase of dual link, TE comes from DSI_1 * this is to check if dual link is enabled */ - val = I915_READ(TRANS_DDI_FUNC_CTL2(TRANSCODER_DSI_0)); + val = intel_uncore_read(&dev_priv->uncore, TRANS_DDI_FUNC_CTL2(TRANSCODER_DSI_0)); val &= PORT_SYNC_MODE_ENABLE; /* @@ -2313,7 +2313,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, dsi_trans = (port == PORT_A) ? TRANSCODER_DSI_0 : TRANSCODER_DSI_1; /* Check if DSI configured in command mode */ - val = I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)); + val = intel_uncore_read(&dev_priv->uncore, DSI_TRANS_FUNC_CONF(dsi_trans)); val = val & OP_MODE_MASK; if (val != CMD_MODE_NO_GATE && val != CMD_MODE_TE_GATE) { @@ -2322,7 +2322,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, } /* Get PIPE for handling VBLANK event */ - val = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans)); + val = intel_uncore_read(&dev_priv->uncore, TRANS_DDI_FUNC_CTL(dsi_trans)); switch (val & TRANS_DDI_EDP_INPUT_MASK) { case TRANS_DDI_EDP_INPUT_A_ON: pipe = PIPE_A; @@ -2342,8 +2342,8 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, /* clear TE in dsi IIR */ port = (te_trigger & DSI1_TE) ? PORT_B : PORT_A; - tmp = I915_READ(DSI_INTR_IDENT_REG(port)); - I915_WRITE(DSI_INTR_IDENT_REG(port), tmp); + tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_IDENT_REG(port)); + intel_uncore_write(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), tmp); } static irqreturn_t @@ -2354,9 +2354,9 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) enum pipe pipe; if (master_ctl & GEN8_DE_MISC_IRQ) { - iir = I915_READ(GEN8_DE_MISC_IIR); + iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IIR); if (iir) { - I915_WRITE(GEN8_DE_MISC_IIR, iir); + intel_uncore_write(&dev_priv->uncore, GEN8_DE_MISC_IIR, iir); ret = IRQ_HANDLED; gen8_de_misc_irq_handler(dev_priv, iir); } else { @@ -2366,9 +2366,9 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) } if (INTEL_GEN(dev_priv) >= 11 && (master_ctl & GEN11_DE_HPD_IRQ)) { - iir = I915_READ(GEN11_DE_HPD_IIR); + iir = intel_uncore_read(&dev_priv->uncore, GEN11_DE_HPD_IIR); if (iir) { - I915_WRITE(GEN11_DE_HPD_IIR, iir); + intel_uncore_write(&dev_priv->uncore, GEN11_DE_HPD_IIR, iir); ret = IRQ_HANDLED; gen11_hpd_irq_handler(dev_priv, iir); } else { @@ -2378,11 +2378,11 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) } if (master_ctl & GEN8_DE_PORT_IRQ) { - iir = I915_READ(GEN8_DE_PORT_IIR); + iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IIR); if (iir) { bool found = false; - I915_WRITE(GEN8_DE_PORT_IIR, iir); + intel_uncore_write(&dev_priv->uncore, GEN8_DE_PORT_IIR, iir); ret = IRQ_HANDLED; if (iir & gen8_de_port_aux_mask(dev_priv)) { @@ -2435,7 +2435,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) continue; - iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); + iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IIR(pipe)); if (!iir) { drm_err(&dev_priv->drm, "The master control interrupt lied (DE PIPE)!\n"); @@ -2443,7 +2443,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) } ret = IRQ_HANDLED; - I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir); + intel_uncore_write(&dev_priv->uncore, GEN8_DE_PIPE_IIR(pipe), iir); if (iir & GEN8_PIPE_VBLANK) intel_handle_vblank(dev_priv, pipe); @@ -2472,9 +2472,9 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) * scheme also closed the SDE interrupt handling race we've seen * on older pch-split platforms. But this needs testing. */ - iir = I915_READ(SDEIIR); + iir = intel_uncore_read(&dev_priv->uncore, SDEIIR); if (iir) { - I915_WRITE(SDEIIR, iir); + intel_uncore_write(&dev_priv->uncore, SDEIIR, iir); ret = IRQ_HANDLED; if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) @@ -2713,7 +2713,7 @@ int i915gm_enable_vblank(struct drm_crtc *crtc) * only when vblank interrupts are actually enabled. */ if (dev_priv->vblank_enabled++ == 0) - I915_WRITE(SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + intel_uncore_write(&dev_priv->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); return i8xx_enable_vblank(crtc); } @@ -2770,16 +2770,16 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, else port = PORT_A; - tmp = I915_READ(DSI_INTR_MASK_REG(port)); + tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_MASK_REG(port)); if (enable) tmp &= ~DSI_TE_EVENT; else tmp |= DSI_TE_EVENT; - I915_WRITE(DSI_INTR_MASK_REG(port), tmp); + intel_uncore_write(&dev_priv->uncore, DSI_INTR_MASK_REG(port), tmp); - tmp = I915_READ(DSI_INTR_IDENT_REG(port)); - I915_WRITE(DSI_INTR_IDENT_REG(port), tmp); + tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_IDENT_REG(port)); + intel_uncore_write(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), tmp); return true; } @@ -2841,7 +2841,7 @@ void i915gm_disable_vblank(struct drm_crtc *crtc) i8xx_disable_vblank(crtc); if (--dev_priv->vblank_enabled == 0) - I915_WRITE(SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + intel_uncore_write(&dev_priv->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } void i965_disable_vblank(struct drm_crtc *crtc) @@ -2907,7 +2907,7 @@ static void ibx_irq_reset(struct drm_i915_private *dev_priv) GEN3_IRQ_RESET(uncore, SDE); if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) - I915_WRITE(SERR_INT, 0xffffffff); + intel_uncore_write(&dev_priv->uncore, SERR_INT, 0xffffffff); } static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) @@ -2920,7 +2920,7 @@ static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) intel_uncore_write(uncore, DPINVGTT, DPINVGTT_STATUS_MASK); i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0); - intel_uncore_write(uncore, PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + intel_uncore_write(uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT)); i9xx_pipestat_irq_reset(dev_priv); @@ -2983,8 +2983,8 @@ static void ilk_irq_reset(struct drm_i915_private *dev_priv) static void valleyview_irq_reset(struct drm_i915_private *dev_priv) { - I915_WRITE(VLV_MASTER_IER, 0); - POSTING_READ(VLV_MASTER_IER); + intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, 0); + intel_uncore_posting_read(&dev_priv->uncore, VLV_MASTER_IER); gen5_gt_irq_reset(&dev_priv->gt); @@ -3137,8 +3137,8 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; - I915_WRITE(GEN8_MASTER_IRQ, 0); - POSTING_READ(GEN8_MASTER_IRQ); + intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, 0); + intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ); gen8_gt_irq_reset(&dev_priv->gt); @@ -3184,7 +3184,7 @@ static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv) * duration to 2ms (which is the minimum in the Display Port spec). * The pulse duration bits are reserved on LPT+. */ - hotplug = I915_READ(PCH_PORT_HOTPLUG); + hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG); hotplug &= ~(PORTA_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE | @@ -3193,7 +3193,7 @@ static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv) PORTC_PULSE_DURATION_MASK | PORTD_PULSE_DURATION_MASK); hotplug |= intel_hpd_hotplug_enables(dev_priv, ibx_hotplug_enables); - I915_WRITE(PCH_PORT_HOTPLUG, hotplug); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug); } static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) @@ -3242,20 +3242,20 @@ static void icp_ddi_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 hotplug; - hotplug = I915_READ(SHOTPLUG_CTL_DDI); + hotplug = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_DDI); hotplug &= ~(SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_A) | SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_B) | SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_C) | SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_D)); hotplug |= intel_hpd_hotplug_enables(dev_priv, icp_ddi_hotplug_enables); - I915_WRITE(SHOTPLUG_CTL_DDI, hotplug); + intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_DDI, hotplug); } static void icp_tc_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 hotplug; - hotplug = I915_READ(SHOTPLUG_CTL_TC); + hotplug = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_TC); hotplug &= ~(ICP_TC_HPD_ENABLE(HPD_PORT_TC1) | ICP_TC_HPD_ENABLE(HPD_PORT_TC2) | ICP_TC_HPD_ENABLE(HPD_PORT_TC3) | @@ -3263,7 +3263,7 @@ static void icp_tc_hpd_detection_setup(struct drm_i915_private *dev_priv) ICP_TC_HPD_ENABLE(HPD_PORT_TC5) | ICP_TC_HPD_ENABLE(HPD_PORT_TC6)); hotplug |= intel_hpd_hotplug_enables(dev_priv, icp_tc_hotplug_enables); - I915_WRITE(SHOTPLUG_CTL_TC, hotplug); + intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_TC, hotplug); } static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv) @@ -3274,7 +3274,7 @@ static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv) hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->hotplug.pch_hpd); if (INTEL_PCH_TYPE(dev_priv) <= PCH_TGP) - I915_WRITE(SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ); + intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ); ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); @@ -3302,12 +3302,12 @@ static void dg1_hpd_irq_setup(struct drm_i915_private *dev_priv) { u32 val; - val = I915_READ(SOUTH_CHICKEN1); + val = intel_uncore_read(&dev_priv->uncore, SOUTH_CHICKEN1); val |= (INVERT_DDIA_HPD | INVERT_DDIB_HPD | INVERT_DDIC_HPD | INVERT_DDID_HPD); - I915_WRITE(SOUTH_CHICKEN1, val); + intel_uncore_write(&dev_priv->uncore, SOUTH_CHICKEN1, val); icp_hpd_irq_setup(dev_priv); } @@ -3316,7 +3316,7 @@ static void gen11_tc_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 hotplug; - hotplug = I915_READ(GEN11_TC_HOTPLUG_CTL); + hotplug = intel_uncore_read(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL); hotplug &= ~(GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) | GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) | GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) | @@ -3324,14 +3324,14 @@ static void gen11_tc_hpd_detection_setup(struct drm_i915_private *dev_priv) GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) | GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6)); hotplug |= intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables); - I915_WRITE(GEN11_TC_HOTPLUG_CTL, hotplug); + intel_uncore_write(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, hotplug); } static void gen11_tbt_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 hotplug; - hotplug = I915_READ(GEN11_TBT_HOTPLUG_CTL); + hotplug = intel_uncore_read(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL); hotplug &= ~(GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) | GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) | GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) | @@ -3339,7 +3339,7 @@ static void gen11_tbt_hpd_detection_setup(struct drm_i915_private *dev_priv) GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) | GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6)); hotplug |= intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables); - I915_WRITE(GEN11_TBT_HOTPLUG_CTL, hotplug); + intel_uncore_write(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, hotplug); } static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv) @@ -3350,11 +3350,11 @@ static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv) enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->hotplug.hpd); hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->hotplug.hpd); - val = I915_READ(GEN11_DE_HPD_IMR); + val = intel_uncore_read(&dev_priv->uncore, GEN11_DE_HPD_IMR); val &= ~hotplug_irqs; val |= ~enabled_irqs & hotplug_irqs; - I915_WRITE(GEN11_DE_HPD_IMR, val); - POSTING_READ(GEN11_DE_HPD_IMR); + intel_uncore_write(&dev_priv->uncore, GEN11_DE_HPD_IMR, val); + intel_uncore_posting_read(&dev_priv->uncore, GEN11_DE_HPD_IMR); gen11_tc_hpd_detection_setup(dev_priv); gen11_tbt_hpd_detection_setup(dev_priv); @@ -3397,25 +3397,25 @@ static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) /* Display WA #1179 WaHardHangonHotPlug: cnp */ if (HAS_PCH_CNP(dev_priv)) { - val = I915_READ(SOUTH_CHICKEN1); + val = intel_uncore_read(&dev_priv->uncore, SOUTH_CHICKEN1); val &= ~CHASSIS_CLK_REQ_DURATION_MASK; val |= CHASSIS_CLK_REQ_DURATION(0xf); - I915_WRITE(SOUTH_CHICKEN1, val); + intel_uncore_write(&dev_priv->uncore, SOUTH_CHICKEN1, val); } /* Enable digital hotplug on the PCH */ - hotplug = I915_READ(PCH_PORT_HOTPLUG); + hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG); hotplug &= ~(PORTA_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE | PORTD_HOTPLUG_ENABLE); hotplug |= intel_hpd_hotplug_enables(dev_priv, spt_hotplug_enables); - I915_WRITE(PCH_PORT_HOTPLUG, hotplug); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug); - hotplug = I915_READ(PCH_PORT_HOTPLUG2); + hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG2); hotplug &= ~PORTE_HOTPLUG_ENABLE; hotplug |= intel_hpd_hotplug_enables(dev_priv, spt_hotplug2_enables); - I915_WRITE(PCH_PORT_HOTPLUG2, hotplug); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG2, hotplug); } static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) @@ -3423,7 +3423,7 @@ static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) u32 hotplug_irqs, enabled_irqs; if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) - I915_WRITE(SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ); + intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ); enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->hotplug.pch_hpd); hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->hotplug.pch_hpd); @@ -3454,11 +3454,11 @@ static void ilk_hpd_detection_setup(struct drm_i915_private *dev_priv) * duration to 2ms (which is the minimum in the Display Port spec) * The pulse duration bits are reserved on HSW+. */ - hotplug = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL); + hotplug = intel_uncore_read(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL); hotplug &= ~(DIGITAL_PORTA_HOTPLUG_ENABLE | DIGITAL_PORTA_PULSE_DURATION_MASK); hotplug |= intel_hpd_hotplug_enables(dev_priv, ilk_hotplug_enables); - I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hotplug); + intel_uncore_write(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, hotplug); } static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv) @@ -3508,7 +3508,7 @@ static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 hotplug; - hotplug = I915_READ(PCH_PORT_HOTPLUG); + hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG); hotplug &= ~(PORTA_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE | @@ -3516,7 +3516,7 @@ static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv) BXT_DDIB_HPD_INVERT | BXT_DDIC_HPD_INVERT); hotplug |= intel_hpd_hotplug_enables(dev_priv, bxt_hotplug_enables); - I915_WRITE(PCH_PORT_HOTPLUG, hotplug); + intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug); } static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) @@ -3636,8 +3636,8 @@ static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv) vlv_display_irq_postinstall(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); - I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); - POSTING_READ(VLV_MASTER_IER); + intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); + intel_uncore_posting_read(&dev_priv->uncore, VLV_MASTER_IER); } static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) @@ -3750,14 +3750,14 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv) GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked); - I915_WRITE(GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); + intel_uncore_write(&dev_priv->uncore, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); if (HAS_MASTER_UNIT_IRQ(dev_priv)) { dg1_master_intr_enable(uncore->regs); - POSTING_READ(DG1_MSTR_UNIT_INTR); + intel_uncore_posting_read(&dev_priv->uncore, DG1_MSTR_UNIT_INTR); } else { gen11_master_intr_enable(uncore->regs); - POSTING_READ(GEN11_GFX_MSTR_IRQ); + intel_uncore_posting_read(&dev_priv->uncore, GEN11_GFX_MSTR_IRQ); } } @@ -3770,8 +3770,8 @@ static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv) vlv_display_irq_postinstall(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); - I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); - POSTING_READ(GEN8_MASTER_IRQ); + intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); + intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ); } static void i8xx_irq_reset(struct drm_i915_private *dev_priv) @@ -3861,11 +3861,11 @@ static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv, { u32 emr; - *eir = I915_READ(EIR); + *eir = intel_uncore_read(&dev_priv->uncore, EIR); - I915_WRITE(EIR, *eir); + intel_uncore_write(&dev_priv->uncore, EIR, *eir); - *eir_stuck = I915_READ(EIR); + *eir_stuck = intel_uncore_read(&dev_priv->uncore, EIR); if (*eir_stuck == 0) return; @@ -3879,9 +3879,9 @@ static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv, * (or by a GPU reset) so we mask any bit that * remains set. */ - emr = I915_READ(EMR); - I915_WRITE(EMR, 0xffffffff); - I915_WRITE(EMR, emr | *eir_stuck); + emr = intel_uncore_read(&dev_priv->uncore, EMR); + intel_uncore_write(&dev_priv->uncore, EMR, 0xffffffff); + intel_uncore_write(&dev_priv->uncore, EMR, emr | *eir_stuck); } static void i9xx_error_irq_handler(struct drm_i915_private *dev_priv, @@ -3945,7 +3945,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv) if (I915_HAS_HOTPLUG(dev_priv)) { i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT)); } i9xx_pipestat_irq_reset(dev_priv); @@ -3959,7 +3959,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; - I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | + intel_uncore_write(&dev_priv->uncore, EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); /* Unmask the interrupts that we always want on. */ @@ -4012,7 +4012,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) u32 hotplug_status = 0; u32 iir; - iir = I915_READ(GEN2_IIR); + iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR); if (iir == 0) break; @@ -4029,7 +4029,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) if (iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - I915_WRITE(GEN2_IIR, iir); + intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir); if (iir & I915_USER_INTERRUPT) intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]); @@ -4053,7 +4053,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv) struct intel_uncore *uncore = &dev_priv->uncore; i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT)); i9xx_pipestat_irq_reset(dev_priv); @@ -4080,7 +4080,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv) error_mask = ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH); } - I915_WRITE(EMR, error_mask); + intel_uncore_write(&dev_priv->uncore, EMR, error_mask); /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = @@ -4156,7 +4156,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) u32 hotplug_status = 0; u32 iir; - iir = I915_READ(GEN2_IIR); + iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR); if (iir == 0) break; @@ -4172,7 +4172,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) if (iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - I915_WRITE(GEN2_IIR, iir); + intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir); if (iir & I915_USER_INTERRUPT) intel_engine_signal_breadcrumbs(dev_priv->gt.engine[RCS0]); From 5cf82904264190cd6c0edf65ce144ebb2b8be7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 17 Nov 2020 15:44:07 +0100 Subject: [PATCH 0105/5577] drm/ttm/drivers: remove unecessary ttm_module.h include v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ttm_module.h deals with internals of TTM and should never be include outside of it. v2: also move the file around Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/404885/ --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 1 - drivers/gpu/drm/nouveau/nouveau_drv.h | 1 - drivers/gpu/drm/qxl/qxl_drv.h | 1 - drivers/gpu/drm/qxl/qxl_ttm.c | 1 - drivers/gpu/drm/radeon/radeon.h | 1 - drivers/gpu/drm/radeon/radeon_ttm.c | 1 - drivers/gpu/drm/ttm/ttm_agp_backend.c | 1 - drivers/gpu/drm/ttm/ttm_bo.c | 3 ++- drivers/gpu/drm/ttm/ttm_bo_vm.c | 1 - drivers/gpu/drm/ttm/ttm_memory.c | 3 ++- drivers/gpu/drm/ttm/ttm_module.c | 3 ++- {include => drivers/gpu}/drm/ttm/ttm_module.h | 0 drivers/gpu/drm/ttm/ttm_range_manager.c | 1 - drivers/gpu/drm/vmwgfx/ttm_object.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_thp.c | 1 - include/drm/ttm/ttm_bo_driver.h | 1 - 20 files changed, 6 insertions(+), 19 deletions(-) rename {include => drivers/gpu}/drm/ttm/ttm_module.h (100%) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6eceef23d838..b2ccf944a318 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -55,7 +55,6 @@ #include #include #include -#include #include #include diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index a34fedcc8b61..ec93d4fdabbd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9d04d1b36434..c802d3d1ba39 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -55,7 +55,6 @@ #include #include #include -#include #include diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 8bd0f916dfbc..83b54f0dad61 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -46,7 +46,6 @@ #include #include #include -#include #include #include "qxl_dev.h" diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index d42e750cbdd3..38e2b117a085 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "qxl_drv.h" diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 28cb8ced91b9..428c561a4e2c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -75,7 +75,6 @@ #include #include #include -#include #include #include diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index f1f7adb67c8e..a3432c6343ba 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include "radeon_reg.h" diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index 03c86628e4ac..8f9fa4188897 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c @@ -32,7 +32,6 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index fc6b619c0329..02cc5d247c0d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -31,7 +31,6 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include #include #include #include @@ -43,6 +42,8 @@ #include #include +#include "ttm_module.h" + static void ttm_bo_global_kobj_release(struct kobject *kobj); /* diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 2944fa0af493..144a4940b6b6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -31,7 +31,6 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include #include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index 5ed1fc8f2ace..a3bfbd9cea68 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -29,7 +29,6 @@ #define pr_fmt(fmt) "[TTM] " fmt #include -#include #include #include #include @@ -39,6 +38,8 @@ #include #include +#include "ttm_module.h" + #define TTM_MEMORY_ALLOC_RETRIES 4 struct ttm_mem_global ttm_mem_glob; diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c index 6ff40c041d79..c0906437cb1c 100644 --- a/drivers/gpu/drm/ttm/ttm_module.c +++ b/drivers/gpu/drm/ttm/ttm_module.c @@ -32,9 +32,10 @@ #include #include #include -#include #include +#include "ttm_module.h" + static DECLARE_WAIT_QUEUE_HEAD(exit_q); static atomic_t device_released; diff --git a/include/drm/ttm/ttm_module.h b/drivers/gpu/drm/ttm/ttm_module.h similarity index 100% rename from include/drm/ttm/ttm_module.h rename to drivers/gpu/drm/ttm/ttm_module.h diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index e0952444cea9..a39305f742da 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -29,7 +29,6 @@ * Authors: Thomas Hellstrom */ -#include #include #include #include diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c index 16077785ad47..0fe869d0fad1 100644 --- a/drivers/gpu/drm/vmwgfx/ttm_object.c +++ b/drivers/gpu/drm/vmwgfx/ttm_object.c @@ -59,7 +59,6 @@ #define pr_fmt(fmt) "[TTM] " fmt -#include #include #include #include diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 216daf93022c..0008be02d31c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "ttm_object.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index b45becbb00f8..5b9a28157dd3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -39,7 +39,6 @@ #include #include -#include #include "ttm_lock.h" #include "ttm_object.h" diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c index be325a62c178..8fe26e32f920 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c @@ -29,7 +29,6 @@ */ #include "vmwgfx_drv.h" -#include #include #include #include diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c b/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c index 155ca3a5c7e5..e8e79de255cf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c @@ -5,7 +5,6 @@ * Copyright (C) 2007-2019 Vmware, Inc. All rights reservedd. */ #include "vmwgfx_drv.h" -#include #include #include diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index f02f7cf9ae90..b1d1ce9740c4 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -39,7 +39,6 @@ #include "ttm_bo_api.h" #include "ttm_memory.h" -#include "ttm_module.h" #include "ttm_placement.h" #include "ttm_tt.h" #include "ttm_pool.h" From efab47658a6c0fee7add0e5263e1fbc9a62cfa55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Mon, 30 Nov 2020 04:57:50 -0800 Subject: [PATCH 0106/5577] drm/i915/display/psr: Calculate selective fetch plane registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the calculations to set plane selective fetch registers depending in the value of the area damaged. It is still using the whole plane area as damaged but that will change in next patches. v2: - fixed new_plane_state->uapi.dst.y2 typo in intel_psr2_sel_fetch_update() - do not shifthing new_plane_state->uapi.dst only src is in 16.16 format BSpec: 55229 Cc: Gwan-gyeong Mun Cc: Ville Syrjälä Signed-off-by: José Roberto de Souza Reviewed-by: Gwan-gyeong Mun Tested-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20201130125750.17820-1-jose.souza@intel.com --- .../drm/i915/display/intel_display_types.h | 2 ++ drivers/gpu/drm/i915/display/intel_psr.c | 22 ++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ce82d654d0f2..3a18aaf907cc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -604,6 +604,8 @@ struct intel_plane_state { u32 planar_slave; struct drm_intel_sprite_colorkey ckey; + + struct drm_rect psr2_sel_fetch_area; }; struct intel_initial_plane_config { diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index b3631b722de3..d9a395c486d3 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1185,6 +1185,7 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; + const struct drm_rect *clip; u32 val; if (!crtc_state->enable_psr2_sel_fetch) @@ -1196,16 +1197,20 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, if (!val || plane->id == PLANE_CURSOR) return; - val = plane_state->uapi.dst.y1 << 16 | plane_state->uapi.dst.x1; + clip = &plane_state->psr2_sel_fetch_area; + + val = (clip->y1 + plane_state->uapi.dst.y1) << 16; + val |= plane_state->uapi.dst.x1; intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_POS(pipe, plane->id), val); - val = plane_state->color_plane[color_plane].y << 16; + /* TODO: consider tiling and auxiliary surfaces */ + val = (clip->y1 + plane_state->color_plane[color_plane].y) << 16; val |= plane_state->color_plane[color_plane].x; intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_OFFSET(pipe, plane->id), val); /* Sizes are 0 based */ - val = ((drm_rect_height(&plane_state->uapi.src) >> 16) - 1) << 16; + val = (drm_rect_height(clip) - 1) << 16; val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1; intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe, plane->id), val); } @@ -1279,7 +1284,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { - struct drm_rect temp; + struct drm_rect *sel_fetch_area, temp; if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc) continue; @@ -1302,8 +1307,13 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, * For now doing a selective fetch in the whole plane area, * optimizations will come in the future. */ - temp.y1 = new_plane_state->uapi.dst.y1; - temp.y2 = new_plane_state->uapi.dst.y2; + sel_fetch_area = &new_plane_state->psr2_sel_fetch_area; + sel_fetch_area->y1 = new_plane_state->uapi.src.y1 >> 16; + sel_fetch_area->y2 = new_plane_state->uapi.src.y2 >> 16; + + temp = *sel_fetch_area; + temp.y1 += new_plane_state->uapi.dst.y1; + temp.y2 += new_plane_state->uapi.dst.y2; clip_area_update(&pipe_clip, &temp); } From 6926872ae24452d4f2176a3ba2dee659497de2c4 Mon Sep 17 00:00:00 2001 From: Jialin Zhang Date: Mon, 30 Nov 2020 10:02:16 +0800 Subject: [PATCH 0107/5577] drm/gma500: Fix error return code in psb_driver_load() Fix to return a negative error code from the error handling case instead of 0, as done elsewhere in this function. Fixes: 5c49fd3aa0ab ("gma500: Add the core DRM files and headers") Reported-by: Hulk Robot Signed-off-by: Jialin Zhang Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201130020216.1906141-1-zhangjialin11@huawei.com --- drivers/gpu/drm/gma500/psb_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index cc2d59e8471d..134068f9328d 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -312,6 +312,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) if (ret) goto out_err; + ret = -ENOMEM; + dev_priv->mmu = psb_mmu_driver_init(dev, 1, 0, 0); if (!dev_priv->mmu) goto out_err; From 551620f2a3816397266dfd812cd8b3be89f14be4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 27 Nov 2020 17:35:28 +0100 Subject: [PATCH 0108/5577] drm/nouveau: Drop mutex_lock_nested for atomic Purely conjecture, but I think the original locking inversion with the legacy page flip code between flipping and ttm's bo move function shoudn't exist anymore with atomic: With atomic the bo pinning and actual modeset commit is completely separated in the code patsh. This annotation was originally added in commit 060810d7abaabcab282e062c595871d661561400 Author: Ben Skeggs Date: Mon Jul 8 14:15:51 2013 +1000 drm/nouveau: fix locking issues in page flipping paths due to commit b580c9e2b7ba5030a795aa2fb73b796523d65a78 Author: Maarten Lankhorst Date: Thu Jun 27 13:48:18 2013 +0200 drm/nouveau: make flipping lockdep safe Acked-by: Ben Skeggs Reviewed-by: Maarten Lankhorst Signed-off-by: Daniel Vetter Cc: Maarten Lankhorst Cc: Ben Skeggs Cc: Dave Airlie Cc: nouveau@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20201127163528.2221671-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/nouveau/nouveau_bo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 645e7091dffc..bc542ac4c4b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -774,7 +774,10 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, return ret; } - mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); + if (drm_drv_uses_atomic_modeset(drm->dev)) + mutex_lock(&cli->mutex); + else + mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, ctx->interruptible); if (ret == 0) { ret = drm->ttm.move(chan, bo, &bo->mem, new_reg); From b73cd1e2ebfc8c22741eb4439bc5d347555f3e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 1 Dec 2020 14:27:34 +0100 Subject: [PATCH 0109/5577] drm/ttm: stop destroying pinned ghost object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Daniel added a warning for this, but we were abusing that behavior here. Signed-off-by: Christian König Fixes: 57fcd550eb15 ("drm/ttm: Warn on pinning without holding a reference") Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/series/84456/ --- drivers/gpu/drm/ttm/ttm_bo_util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 7ccb2295cac1..5bbc1339d28e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -310,7 +310,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, kref_init(&fbo->base.kref); fbo->base.destroy = &ttm_transfered_destroy; fbo->base.acc_size = 0; - fbo->base.pin_count = 1; + fbo->base.pin_count = 0; if (bo->type != ttm_bo_type_sg) fbo->base.base.resv = &fbo->base.base._resv; @@ -319,6 +319,8 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, ret = dma_resv_trylock(&fbo->base.base._resv); WARN_ON(!ret); + ttm_bo_move_to_lru_tail_unlocked(&fbo->base); + *new_obj = &fbo->base; return 0; } From 81cc320aa3592ee257d1a4a5d72124546f981dad Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:24 +0530 Subject: [PATCH 0110/5577] drm/i915/display: Add HDR Capability detection for LSPCON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LSPCON firmware exposes HDR capability through LPCON_CAPABILITIES DPCD register. LSPCON implementations capable of supporting HDR set HDR_CAPABILITY bit in LSPCON_CAPABILITIES to 1. This patch reads the same, detects the HDR capability and adds this to intel_lspcon struct. v2: Addressed Jani Nikula's review comment and fixed the HDR capability detection logic v3: Deferred HDR detection from lspcon_init (Ville) v4: Addressed Ville's minor review comments, added his RB. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-2-uma.shankar@intel.com --- .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_lspcon.c | 27 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_lspcon.h | 1 + 3 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3a18aaf907cc..491e3550174f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1452,6 +1452,7 @@ enum lspcon_vendor { struct intel_lspcon { bool active; + bool hdr_supported; enum drm_lspcon_mode mode; enum lspcon_vendor vendor; }; diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index e37d45e531df..3065727015a7 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -35,6 +35,8 @@ #define LSPCON_VENDOR_PARADE_OUI 0x001CF8 #define LSPCON_VENDOR_MCA_OUI 0x0060AD +#define DPCD_MCA_LSPCON_HDR_STATUS 0x70003 + /* AUX addresses to write MCA AVI IF */ #define LSPCON_MCA_AVI_IF_WRITE_OFFSET 0x5C0 #define LSPCON_MCA_AVI_IF_CTRL 0x5DF @@ -104,6 +106,31 @@ static bool lspcon_detect_vendor(struct intel_lspcon *lspcon) return true; } +void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon) +{ + struct intel_digital_port *dig_port = + container_of(lspcon, struct intel_digital_port, lspcon); + struct drm_device *dev = dig_port->base.base.dev; + struct intel_dp *dp = lspcon_to_intel_dp(lspcon); + u8 hdr_caps; + int ret; + + /* Enable HDR for MCA based LSPCON devices */ + if (lspcon->vendor == LSPCON_VENDOR_MCA) + ret = drm_dp_dpcd_read(&dp->aux, DPCD_MCA_LSPCON_HDR_STATUS, + &hdr_caps, 1); + else + return; + + if (ret < 0) { + drm_dbg_kms(dev, "HDR capability detection failed\n"); + lspcon->hdr_supported = false; + } else if (hdr_caps & 0x1) { + drm_dbg_kms(dev, "LSPCON capable of HDR\n"); + lspcon->hdr_supported = true; + } +} + static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) { enum drm_lspcon_mode current_mode; diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index b03dcb7076d8..a19b3564c635 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -15,6 +15,7 @@ struct intel_digital_port; struct intel_encoder; struct intel_lspcon; +void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon); void lspcon_resume(struct intel_digital_port *dig_port); void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); void lspcon_write_infoframe(struct intel_encoder *encoder, From 1a911350dd6c777b4a08ca60fe6e2249fd3c254a Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:25 +0530 Subject: [PATCH 0111/5577] drm/i915/display: Enable HDR on gen9 devices with MCA Lspcon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gen9 hardware supports HDMI2.0 through LSPCON chips. Extending HDR support for MCA LSPCON based GEN9 devices. SOC will drive LSPCON as DP and send HDR metadata as standard DP SDP packets. LSPCON will be set to operate in PCON mode, will receive the metadata and create Dynamic Range and Mastering Infoframe (DRM packets) and send it to HDR capable HDMI sink devices. v2: Re-used hsw infoframe write implementation for HDR metadata for LSPCON as per Ville's suggestion. v3: Addressed Jani Nikula's review comments. v4: Addressed Ville's review comments, removed redundant wrapper and checks, passed arguments instead of hardcodings. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-3-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 8 ++--- drivers/gpu/drm/i915/display/intel_lspcon.c | 35 ++++++++++++--------- drivers/gpu/drm/i915/display/intel_lspcon.h | 4 +++ 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 82674a8853c6..0f2cc40cc792 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -518,10 +518,10 @@ static u32 vlv_infoframes_enabled(struct intel_encoder *encoder, VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP); } -static void hsw_write_infoframe(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - unsigned int type, - const void *frame, ssize_t len) +void hsw_write_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + const void *frame, ssize_t len) { const u32 *data = frame; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 3065727015a7..641025f00286 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -445,27 +445,32 @@ void lspcon_write_infoframe(struct intel_encoder *encoder, unsigned int type, const void *frame, ssize_t len) { - bool ret; + bool ret = true; struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder); - /* LSPCON only needs AVI IF */ - if (type != HDMI_INFOFRAME_TYPE_AVI) - return; - - if (lspcon->vendor == LSPCON_VENDOR_MCA) - ret = _lspcon_write_avi_infoframe_mca(&intel_dp->aux, - frame, len); - else - ret = _lspcon_write_avi_infoframe_parade(&intel_dp->aux, - frame, len); - - if (!ret) { - DRM_ERROR("Failed to write AVI infoframes\n"); + switch (type) { + case HDMI_INFOFRAME_TYPE_AVI: + if (lspcon->vendor == LSPCON_VENDOR_MCA) + ret = _lspcon_write_avi_infoframe_mca(&intel_dp->aux, + frame, len); + else + ret = _lspcon_write_avi_infoframe_parade(&intel_dp->aux, + frame, len); + break; + case HDMI_PACKET_TYPE_GAMUT_METADATA: + drm_dbg_kms(encoder->base.dev, "Update HDR metadata for lspcon\n"); + /* It uses the legacy hsw implementation for the same */ + hsw_write_infoframe(encoder, crtc_state, type, frame, len); + break; + default: return; } - DRM_DEBUG_DRIVER("AVI infoframes updated successfully\n"); + if (!ret) { + DRM_ERROR("Failed to write infoframes\n"); + return; + } } void lspcon_read_infoframe(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index a19b3564c635..98043ba50dd4 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -32,5 +32,9 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, const struct drm_connector_state *conn_state); u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config); +void hsw_write_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + const void *frame, ssize_t len); #endif /* __INTEL_LSPCON_H__ */ From 2e666613b24e3c7d2ae5cf5c1e264751bb5b2a8f Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:26 +0530 Subject: [PATCH 0112/5577] drm/i915/display: Attach HDR property for capable Gen9 devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attach HDR property for Gen9 devices with MCA LSPCON chips. v2: Cleaned HDR property attachment logic based on capability as per Jani Nikula's suggestion. v3: Fixed the HDR property attachment logic as per the new changes by Kai-Feng to align with lspcon detection failure on some devices. v4: Add HDR proprty in late_register to handle lspcon detection, as suggested by Ville. v5: Init Lspcon only if advertized from BIOS. v6: Added a Todo to plan a cleanup later, added Ville's RB. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-4-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/display/intel_lspcon.c | 2 +- drivers/gpu/drm/i915/display/intel_lspcon.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3896d08c4177..5aaa06d73609 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6774,6 +6774,8 @@ intel_dp_connector_register(struct drm_connector *connector) { struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct intel_lspcon *lspcon = &dig_port->lspcon; int ret; ret = intel_connector_register(connector); @@ -6787,6 +6789,22 @@ intel_dp_connector_register(struct drm_connector *connector) ret = drm_dp_aux_register(&intel_dp->aux); if (!ret) drm_dp_cec_register_connector(&intel_dp->aux, connector); + + if (!intel_bios_is_lspcon_present(i915, dig_port->base.port)) + return ret; + + /* + * ToDo: Clean this up to handle lspcon init and resume more + * efficiently and streamlined. + */ + if (lspcon_init(dig_port)) { + lspcon_detect_hdr_capability(lspcon); + if (lspcon->hdr_supported) + drm_object_attach_property(&connector->base, + connector->dev->mode_config.hdr_output_metadata_property, + 0); + } + return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 641025f00286..f98891f058da 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -552,7 +552,7 @@ void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon) lspcon_wait_mode(lspcon, DRM_LSPCON_MODE_PCON); } -static bool lspcon_init(struct intel_digital_port *dig_port) +bool lspcon_init(struct intel_digital_port *dig_port) { struct intel_dp *dp = &dig_port->dp; struct intel_lspcon *lspcon = &dig_port->lspcon; diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 98043ba50dd4..42ccb21c908f 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -15,6 +15,7 @@ struct intel_digital_port; struct intel_encoder; struct intel_lspcon; +bool lspcon_init(struct intel_digital_port *dig_port); void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon); void lspcon_resume(struct intel_digital_port *dig_port); void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); From 9559c0d13b6b35abc2659bdd3024849d552e3c4e Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:27 +0530 Subject: [PATCH 0113/5577] drm/i915/display: Fixes quantization range for YCbCr output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the quantization range for YCbCr output on Lspcon based devices. v2: Re-phrased the description and added Ville's Rb. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-5-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_lspcon.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index f98891f058da..7cb65e0f241e 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -523,12 +523,17 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, else frame.avi.colorspace = HDMI_COLORSPACE_RGB; - drm_hdmi_avi_infoframe_quant_range(&frame.avi, - conn_state->connector, - adjusted_mode, - crtc_state->limited_color_range ? - HDMI_QUANTIZATION_RANGE_LIMITED : - HDMI_QUANTIZATION_RANGE_FULL); + if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) { + drm_hdmi_avi_infoframe_quant_range(&frame.avi, + conn_state->connector, + adjusted_mode, + crtc_state->limited_color_range ? + HDMI_QUANTIZATION_RANGE_LIMITED : + HDMI_QUANTIZATION_RANGE_FULL); + } else { + frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT; + frame.avi.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED; + } ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf)); if (ret < 0) { From 55b1f9ddf41d369f2d480596822c6d17817a8d78 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:28 +0530 Subject: [PATCH 0114/5577] drm/i915/display: Add a WARN for invalid output range and format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a WARN to rule out an invalid output range and format combination. This is to align the lspcon code with compute_avi_infoframes. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-6-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_lspcon.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 7cb65e0f241e..9552dfc55e20 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -523,6 +523,10 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, else frame.avi.colorspace = HDMI_COLORSPACE_RGB; + /* nonsense combination */ + drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range && + crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); + if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) { drm_hdmi_avi_infoframe_quant_range(&frame.avi, conn_state->connector, From b983675709e07523c5e8bacfcfa153a49f7eca7f Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:29 +0530 Subject: [PATCH 0115/5577] drm/i915/display: Attach content type property for LSPCON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Content type is supported on HDMI sink devices. Attached the property for the same for LSPCON based devices. v2: Added the content type programming when we are attaching the property to connector, as suggested by Ville. v3: Need to attach content type on intel_dp_add_properties as creating of new properties is not possible at late_register. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-7-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 3 +++ drivers/gpu/drm/i915/display/intel_lspcon.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 5aaa06d73609..69de163be776 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7195,6 +7195,9 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect intel_attach_colorspace_property(connector); + if (intel_bios_is_lspcon_present(dev_priv, port)) + drm_connector_attach_content_type_property(connector); + if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 11) drm_object_attach_property(&connector->base, connector->dev->mode_config.hdr_output_metadata_property, diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 9552dfc55e20..0a4c05d67108 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -539,6 +539,8 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, frame.avi.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED; } + drm_hdmi_avi_infoframe_content_type(&frame.avi, conn_state); + ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf)); if (ret < 0) { DRM_ERROR("Failed to pack AVI IF\n"); From 174da987bc8da65327c230ba404a98bcd1b16cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 1 Dec 2020 02:17:30 +0530 Subject: [PATCH 0116/5577] drm/i915: Split intel_attach_colorspace_property() into HDMI vs. DP variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With LSPCON we use the AVI infoframe to convey the colorimetry information (as opposed to DP MSA/SDP), so the property we expose should match the values we can stuff into the infoframe. Ie. we must use the HDMI variant of the property, even though we drive LSPCON in PCON mode. To that end just split intel_attach_colorspace_property() into HDMI and DP variants and let the caller worry about which one it wants to use. Cc: Uma Shankar Signed-off-by: Ville Syrjälä Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-8-uma.shankar@intel.com --- .../gpu/drm/i915/display/intel_connector.c | 31 +++++++------------ .../gpu/drm/i915/display/intel_connector.h | 3 +- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index 406e96785c76..d5ceb7bdc14b 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -279,24 +279,17 @@ intel_attach_aspect_ratio_property(struct drm_connector *connector) } void -intel_attach_colorspace_property(struct drm_connector *connector) +intel_attach_hdmi_colorspace_property(struct drm_connector *connector) { - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_HDMIB: - if (drm_mode_create_hdmi_colorspace_property(connector)) - return; - break; - case DRM_MODE_CONNECTOR_DisplayPort: - case DRM_MODE_CONNECTOR_eDP: - if (drm_mode_create_dp_colorspace_property(connector)) - return; - break; - default: - MISSING_CASE(connector->connector_type); - return; - } - - drm_object_attach_property(&connector->base, - connector->colorspace_property, 0); + if (!drm_mode_create_hdmi_colorspace_property(connector)) + drm_object_attach_property(&connector->base, + connector->colorspace_property, 0); +} + +void +intel_attach_dp_colorspace_property(struct drm_connector *connector) +{ + if (!drm_mode_create_dp_colorspace_property(connector)) + drm_object_attach_property(&connector->base, + connector->colorspace_property, 0); } diff --git a/drivers/gpu/drm/i915/display/intel_connector.h b/drivers/gpu/drm/i915/display/intel_connector.h index 93a7375c8196..661a37a3c6d8 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.h +++ b/drivers/gpu/drm/i915/display/intel_connector.h @@ -30,6 +30,7 @@ int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); void intel_attach_force_audio_property(struct drm_connector *connector); void intel_attach_broadcast_rgb_property(struct drm_connector *connector); void intel_attach_aspect_ratio_property(struct drm_connector *connector); -void intel_attach_colorspace_property(struct drm_connector *connector); +void intel_attach_hdmi_colorspace_property(struct drm_connector *connector); +void intel_attach_dp_colorspace_property(struct drm_connector *connector); #endif /* __INTEL_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 69de163be776..f066031af162 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7193,7 +7193,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect else if (INTEL_GEN(dev_priv) >= 5) drm_connector_attach_max_bpc_property(connector, 6, 12); - intel_attach_colorspace_property(connector); + intel_attach_dp_colorspace_property(connector); if (intel_bios_is_lspcon_present(dev_priv, port)) drm_connector_attach_content_type_property(connector); diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 0f2cc40cc792..0dcf6cd5a253 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2963,7 +2963,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c * as well. Will be implemented separately. */ if (!dig_port->lspcon.active) - intel_attach_colorspace_property(connector); + intel_attach_hdmi_colorspace_property(connector); drm_connector_attach_content_type_property(connector); From 5d36f2b2dd4d973880ee0450f1c287d1c368ebb2 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:31 +0530 Subject: [PATCH 0117/5577] drm/i915/display: Enable colorspace programming for LSPCON devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable HDMI Colorspace for LSPCON based devices. Sending Colorimetry data for HDR using AVI infoframe. LSPCON firmware expects this and though SOC drives DP, for HDMI panel AVI infoframe is sent to the LSPCON device which transfers the same to HDMI sink. v2: Dropped state managed in drm core as per Jani Nikula's suggestion. v3: Aligned colorimetry handling for lspcon as per compute_avi_infoframes, as suggested by Ville. v4: Finally fixed this with Ville's help, re-phrased the commit header and description. v5: Register HDMI colorspace for lspcon and move this to intel_dp_add_properties as we can't create property at late_register. Credits-to: Ville Syrjälä Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-9-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 9 ++++++--- drivers/gpu/drm/i915/display/intel_lspcon.c | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f066031af162..21a0ca6ae2a6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7193,10 +7193,13 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect else if (INTEL_GEN(dev_priv) >= 5) drm_connector_attach_max_bpc_property(connector, 6, 12); - intel_attach_dp_colorspace_property(connector); - - if (intel_bios_is_lspcon_present(dev_priv, port)) + /* Register HDMI colorspace for case of lspcon */ + if (intel_bios_is_lspcon_present(dev_priv, port)) { drm_connector_attach_content_type_property(connector); + intel_attach_hdmi_colorspace_property(connector); + } else { + intel_attach_dp_colorspace_property(connector); + } if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 11) drm_object_attach_property(&connector->base, diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 0a4c05d67108..cb768a1ae4c9 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -523,6 +523,9 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, else frame.avi.colorspace = HDMI_COLORSPACE_RGB; + /* Set the Colorspace as per the HDMI spec */ + drm_hdmi_avi_infoframe_colorspace(&frame.avi, conn_state); + /* nonsense combination */ drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); From 84ab44b757d59e50584c0ca86890dd139f9daed0 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:32 +0530 Subject: [PATCH 0118/5577] drm/i915/display: Nuke bogus lspcon check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dropped a irrelevant lspcon check from intel_hdmi_add_properties function. Suggested-by: Ville Syrjälä Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-10-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 0dcf6cd5a253..88c153407a7d 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2950,21 +2950,12 @@ static void intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) { struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_digital_port *dig_port = - hdmi_to_dig_port(intel_hdmi); intel_attach_force_audio_property(connector); intel_attach_broadcast_rgb_property(connector); intel_attach_aspect_ratio_property(connector); - /* - * Attach Colorspace property for Non LSPCON based device - * ToDo: This needs to be extended for LSPCON implementation - * as well. Will be implemented separately. - */ - if (!dig_port->lspcon.active) - intel_attach_hdmi_colorspace_property(connector); - + intel_attach_hdmi_colorspace_property(connector); drm_connector_attach_content_type_property(connector); if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) From c5044aee4039671d72ddcfdb38ea0a3b32effab4 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:33 +0530 Subject: [PATCH 0119/5577] drm/i915/display: Enable HDR for Parade based lspcon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable HDR for LSPCON based on Parade along with MCA. v2: Added a helper for status reg as suggested by Ville. v3: Removed a redundant variable, added Ville's RB. Signed-off-by: Uma Shankar Signed-off-by: Vipin Anand Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-11-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_lspcon.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index cb768a1ae4c9..592c19deba00 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -36,6 +36,7 @@ #define LSPCON_VENDOR_MCA_OUI 0x0060AD #define DPCD_MCA_LSPCON_HDR_STATUS 0x70003 +#define DPCD_PARADE_LSPCON_HDR_STATUS 0x00511 /* AUX addresses to write MCA AVI IF */ #define LSPCON_MCA_AVI_IF_WRITE_OFFSET 0x5C0 @@ -106,6 +107,14 @@ static bool lspcon_detect_vendor(struct intel_lspcon *lspcon) return true; } +static u32 get_hdr_status_reg(struct intel_lspcon *lspcon) +{ + if (lspcon->vendor == LSPCON_VENDOR_MCA) + return DPCD_MCA_LSPCON_HDR_STATUS; + else + return DPCD_PARADE_LSPCON_HDR_STATUS; +} + void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon) { struct intel_digital_port *dig_port = @@ -115,12 +124,8 @@ void lspcon_detect_hdr_capability(struct intel_lspcon *lspcon) u8 hdr_caps; int ret; - /* Enable HDR for MCA based LSPCON devices */ - if (lspcon->vendor == LSPCON_VENDOR_MCA) - ret = drm_dp_dpcd_read(&dp->aux, DPCD_MCA_LSPCON_HDR_STATUS, - &hdr_caps, 1); - else - return; + ret = drm_dp_dpcd_read(&dp->aux, get_hdr_status_reg(lspcon), + &hdr_caps, 1); if (ret < 0) { drm_dbg_kms(dev, "HDR capability detection failed\n"); From a44289b923f6092e3103e8e1b83a5d0b86d34769 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:34 +0530 Subject: [PATCH 0120/5577] drm/i915/lspcon: Create separate infoframe_enabled helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lspcon has Infoframes as well as DIP for HDR metadata(DRM Infoframe). Create a separate mechanism for lspcon compared to HDMI in order to address the same and ensure future scalability. v2: Streamlined this as per Ville's suggestions, making sure that HDMI infoframe versions are directly returned instead of a redundant and confusing DIP overhead. Suggested-by: Ville Syrjälä Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-12-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 10 +++++++--- drivers/gpu/drm/i915/display/intel_lspcon.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_lspcon.h | 2 ++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 92940a0c5ef8..48da5dc59939 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4583,6 +4583,7 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); u32 temp, flags = 0; temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); @@ -4657,9 +4658,12 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->fec_enable); } - pipe_config->infoframes.enable |= - intel_hdmi_infoframes_enabled(encoder, pipe_config); - + if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink) + pipe_config->infoframes.enable |= + intel_lspcon_infoframes_enabled(encoder, pipe_config); + else + pipe_config->infoframes.enable |= + intel_hdmi_infoframes_enabled(encoder, pipe_config); break; case TRANS_DDI_MODE_SELECT_DP_MST: pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 592c19deba00..303f23d35020 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -30,6 +30,7 @@ #include "intel_display_types.h" #include "intel_dp.h" #include "intel_lspcon.h" +#include "intel_hdmi.h" /* LSPCON OUI Vendor ID(signatures) */ #define LSPCON_VENDOR_PARADE_OUI 0x001CF8 @@ -601,6 +602,14 @@ bool lspcon_init(struct intel_digital_port *dig_port) return true; } +u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config) +{ + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + + return dig_port->infoframes_enabled(encoder, pipe_config); +} + void lspcon_resume(struct intel_digital_port *dig_port) { struct intel_lspcon *lspcon = &dig_port->lspcon; diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 42ccb21c908f..44aa6bc38512 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -33,6 +33,8 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, const struct drm_connector_state *conn_state); u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config); +u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config); void hsw_write_infoframe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, unsigned int type, From 34108a03e430ea0e7a1d9005e3caa0d6a746fa95 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:35 +0530 Subject: [PATCH 0121/5577] drm/i915/display: Implement infoframes readback for LSPCON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented Infoframes enabled readback for LSPCON devices. This will help align the implementation with state readback infrastructure. v2: Added proper bitmask of enabled infoframes as per Ville's recommendation. v3: Added pcon specific infoframe types instead of using the HSW one's, as recommended by Ville. v4: Addressed Ville's review comment by adding HDMI infoframe versions directly instead of DIP wrappers. v5: Re-ordered the patches to avoid potential break in usage, as suggested by Ville. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-13-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_lspcon.c | 57 ++++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 303f23d35020..7768cf34f4e9 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -560,11 +560,64 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, buf, ret); } +static bool _lspcon_read_avi_infoframe_enabled_mca(struct drm_dp_aux *aux) +{ + int ret; + u32 val = 0; + u16 reg = LSPCON_MCA_AVI_IF_CTRL; + + ret = drm_dp_dpcd_read(aux, reg, &val, 1); + if (ret < 0) { + DRM_ERROR("DPCD read failed, address 0x%x\n", reg); + return false; + } + + return val & LSPCON_MCA_AVI_IF_KICKOFF; +} + +static bool _lspcon_read_avi_infoframe_enabled_parade(struct drm_dp_aux *aux) +{ + int ret; + u32 val = 0; + u16 reg = LSPCON_PARADE_AVI_IF_CTRL; + + ret = drm_dp_dpcd_read(aux, reg, &val, 1); + if (ret < 0) { + DRM_ERROR("DPCD read failed, address 0x%x\n", reg); + return false; + } + + return val & LSPCON_PARADE_AVI_IF_KICKOFF; +} + u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) { - /* FIXME actually read this from the hw */ - return 0; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder); + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + bool infoframes_enabled; + u32 val = 0; + u32 mask, tmp; + + if (lspcon->vendor == LSPCON_VENDOR_MCA) + infoframes_enabled = _lspcon_read_avi_infoframe_enabled_mca(&intel_dp->aux); + else + infoframes_enabled = _lspcon_read_avi_infoframe_enabled_parade(&intel_dp->aux); + + if (infoframes_enabled) + val |= intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI); + + if (lspcon->hdr_supported) { + tmp = intel_de_read(dev_priv, + HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder)); + mask = VIDEO_DIP_ENABLE_GMP_HSW; + + if (tmp & mask) + val |= intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA); + } + + return val; } void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon) From b759415020b335aea8329f210ee162cb0c3c86a0 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:36 +0530 Subject: [PATCH 0122/5577] drm/i915/display: Implement DRM infoframe read for LSPCON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement Read back of HDR metadata infoframes i.e Dynamic Range and Mastering Infoframe for LSPCON devices. v2: Added proper bitmask of enabled infoframes as per Ville's recommendation. v3: Dropped a redundant wrapper as per Ville's comment. v4: Dropped a redundant print, added Ville's RB. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-14-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 7 +++---- drivers/gpu/drm/i915/display/intel_lspcon.c | 5 ++++- drivers/gpu/drm/i915/display/intel_lspcon.h | 4 ++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 88c153407a7d..e10fdb369daa 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -555,10 +555,9 @@ void hsw_write_infoframe(struct intel_encoder *encoder, intel_de_posting_read(dev_priv, ctl_reg); } -static void hsw_read_infoframe(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - unsigned int type, - void *frame, ssize_t len) +void hsw_read_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, void *frame, ssize_t len) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 7768cf34f4e9..e4ff533e3a69 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -484,7 +484,10 @@ void lspcon_read_infoframe(struct intel_encoder *encoder, unsigned int type, void *frame, ssize_t len) { - /* FIXME implement this */ + /* FIXME implement for AVI Infoframe as well */ + if (type == HDMI_PACKET_TYPE_GAMUT_METADATA) + hsw_read_infoframe(encoder, crtc_state, type, + frame, len); } void lspcon_set_infoframes(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 44aa6bc38512..e19e10492b05 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -39,5 +39,9 @@ void hsw_write_infoframe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, unsigned int type, const void *frame, ssize_t len); +void hsw_read_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + void *frame, ssize_t len); #endif /* __INTEL_LSPCON_H__ */ From 998cc864955d9ec0a0675e7e2ea4e069ba640214 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Tue, 1 Dec 2020 02:17:37 +0530 Subject: [PATCH 0123/5577] drm/i915/lspcon: Do not send DRM infoframes to non-HDMI sinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Non-HDMI sinks shouldn't be sent Dynamic Range and Mastering infoframes. Check for that when using LSPCON. v2: Addressed Ville's review comment. Signed-off-by: Uma Shankar Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201130204738.2443-15-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 48da5dc59939..76e975b4765b 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4118,6 +4118,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); enum port port = encoder->port; if (port == PORT_A && INTEL_GEN(dev_priv) < 9) @@ -4125,7 +4126,10 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state, intel_edp_backlight_on(crtc_state, conn_state); intel_psr_enable(intel_dp, crtc_state, conn_state); - intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); + + if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink) + intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); + intel_edp_drrs_enable(intel_dp, crtc_state); if (crtc_state->has_audio) From 5ac84806f5e9b1960c0751633767b239bd314d0a Mon Sep 17 00:00:00 2001 From: Swathi Dhanavanthri Date: Mon, 2 Nov 2020 17:59:35 -0800 Subject: [PATCH 0124/5577] drm/i915/tgl, rkl, dg1: Apply WA_1406941453 to TGL, RKL and DG1 This workaround is applicable only for tgl,rkl and dg1. Bspec: 52890, 53273, 53508. Signed-off-by: Swathi Dhanavanthri Reviewed-by: Clint Taylor Signed-off-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20201201175735.1377372-1-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index a82554baa6ac..7c6b21ced56f 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1778,6 +1778,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) wa_masked_en(wal, GEN9_CS_DEBUG_MODE1, FF_DOP_CLOCK_GATE_DISABLE); + + /* Wa_1406941453:tgl,rkl,dg1 */ + wa_masked_en(wal, + GEN10_SAMPLER_MODE, + ENABLE_SMALLPL); } if (IS_DG1_REVID(i915, DG1_REVID_A0, DG1_REVID_A0) || @@ -1808,13 +1813,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) GEN8_RC_SEMA_IDLE_MSG_DISABLE); } - if (IS_GEN(i915, 12)) { - /* Wa_1406941453:gen12 */ - wa_masked_en(wal, - GEN10_SAMPLER_MODE, - ENABLE_SMALLPL); - } - if (IS_GEN(i915, 11)) { /* This is not an Wa. Enable for better image quality */ wa_masked_en(wal, From 37df0edf7048f4128953e18ffc9a6b84cf15f4cd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 1 Dec 2020 21:54:41 +0000 Subject: [PATCH 0125/5577] drm/i915/gem: Report error for vmap() failure Convert the NULL pointer from a failed vmap() to ERR_PTR(-ENOMEM) for propagation. <1> [269.830447] BUG: kernel NULL pointer dereference, address: 0000000000000000 <1> [269.830455] #PF: supervisor write access in kernel mode <1> [269.830457] #PF: error_code(0x0002) - not-present page <6> [269.830459] PGD 0 P4D 0 <4> [269.830465] Oops: 0002 [#1] PREEMPT SMP PTI <4> [269.830469] CPU: 3 PID: 5789 Comm: i915_selftest Tainted: G U 5.10.0-rc6-CI-CI_DRM_9412+ #1 <4> [269.830472] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017 <4> [269.830636] RIP: 0010:igt_client_fill+0x1b9/0x5f0 [i915] <4> [269.830640] Code: e8 0c 32 02 00 48 89 c5 48 3d 00 f0 ff ff 0f 87 e9 02 00 00 48 8b 8b 78 06 00 00 44 89 f0 48 89 ef 35 af be ad de 48 c1 e9 02 ab 0f b6 83 80 03 00 00 89 c2 c0 ea 03 83 e2 02 75 09 83 c8 20 <4> [269.830642] RSP: 0018:ffffc900007a79e8 EFLAGS: 00010206 <4> [269.830645] RAX: 00000000df0bf37b RBX: ffff88811d8af3c0 RCX: 00000000010afc00 <4> [269.830647] RDX: 0000000000000000 RSI: ffffffff822f2b17 RDI: 0000000000000000 <4> [269.830648] RBP: 0000000000000000 R08: ffff888111c80930 R09: 00000000fffffffe <4> [269.830650] R10: 0000000000000000 R11: 00000000ffbc70e4 R12: ffff88811090f700 <4> [269.830652] R13: ffff88810df60180 R14: 0000000001a64dd4 R15: 0000000000000000 <4> [269.830655] FS: 00007f137b07de40(0000) GS:ffff88817b980000(0000) knlGS:0000000000000000 <4> [269.830657] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4> [269.830659] CR2: 0000000000000000 CR3: 0000000115984000 CR4: 0000000000350ee0 <4> [269.830661] Call Trace: <4> [269.830780] __i915_subtests.cold.7+0x42/0x92 [i915] <4> [269.830886] ? __i915_nop_teardown+0x10/0x10 [i915] <4> [269.830989] ? __i915_live_setup+0x30/0x30 [i915] <4> [269.831104] __run_selftests.part.3+0xf7/0x14c [i915] <4> [269.831939] i915_live_selftests.cold.5+0x1f/0x47 [i915] <4> [269.832027] i915_pci_probe+0x93/0x1d0 [i915] <4> [269.832037] ? _raw_spin_unlock_irqrestore+0x2f/0x50 <4> [269.832043] pci_device_probe+0x9e/0x110 <4> [269.832049] really_probe+0x1c4/0x430 <4> [269.832053] driver_probe_device+0xd9/0x140 <4> [269.832056] device_driver_attach+0x4a/0x50 <4> [269.832059] __driver_attach+0x83/0x140 <4> [269.832062] ? device_driver_attach+0x50/0x50 <4> [269.832064] ? device_driver_attach+0x50/0x50 <4> [269.832067] bus_for_each_dev+0x75/0xc0 <4> [269.832070] bus_add_driver+0x14b/0x1f0 <4> [269.832073] driver_register+0x66/0xb0 <4> [269.832160] i915_init+0x70/0x87 [i915] <4> [269.832164] ? 0xffffffffa05e3000 <4> [269.832168] do_one_initcall+0x56/0x2e0 <4> [269.832174] ? kmem_cache_alloc_trace+0x6a4/0x770 <4> [269.832180] do_init_module+0x55/0x200 <4> [269.832184] load_module+0x22a2/0x2480 <4> [269.832191] ? __do_sys_finit_module+0xad/0x110 <4> [269.832194] __do_sys_finit_module+0xad/0x110 <4> [269.832199] do_syscall_64+0x33/0x80 <4> [269.832202] entry_SYSCALL_64_after_hwframe+0x44/0xa9 <4> [269.832204] RIP: 0033:0x7f137a718839 <4> [269.832208] Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 1f f6 2c 00 f7 d8 64 89 01 48 <4> [269.832210] RSP: 002b:00007ffc4267d308 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 <4> [269.832214] RAX: ffffffffffffffda RBX: 000056288b88f0d0 RCX: 00007f137a718839 <4> [269.832216] RDX: 0000000000000000 RSI: 000056288b895850 RDI: 0000000000000007 <4> [269.832218] RBP: 000056288b895850 R08: 312d3d7374736574 R09: 000056288b88c020 <4> [269.832220] R10: 00007ffc4267d450 R11: 0000000000000246 R12: 0000000000000000 <4> [269.832222] R13: 000056288b8877a0 R14: 0000000000000020 R15: 0000000000000045 <4> [269.832226] Modules linked in: i915(+) vgem mei_hdcp snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio x86_pkg_temp_thermal coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel cdc_ether usbnet snd_intel_dspcfg mii snd_hda_codec snd_hwdep snd_hda_core r8169 snd_pcm realtek mei_me mei prime_numbers intel_lpss_pci i2c_hid pinctrl_geminilake [last unloaded: i915] <4> [269.832264] CR2: 0000000000000000 Fixes: cb2ce93e5b05 ("drm/i915/gem: Differentiate oom failures from invalid map types") Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Tvrtko Ursulin Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20201201215441.31900-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 6dad9ea8eaa3..3db3c667c486 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -290,7 +290,8 @@ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, vaddr = vmap(pages, n_pages, 0, pgprot); if (pages != stack) kvfree(pages); - return vaddr; + + return vaddr ?: ERR_PTR(-ENOMEM); } static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, @@ -320,7 +321,8 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO)); if (pfns != stack) kvfree(pfns); - return vaddr; + + return vaddr ?: ERR_PTR(-ENOMEM); } /* get, pin, and map the pages of the object into kernel space */ From ca3fb8821fbc016c8baa3acbe6e8bf9cab684061 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:16:00 +0200 Subject: [PATCH 0126/5577] drm/i915/gvt: replace I915_WRITE with intel_uncore_write Let's avoid adding new I915_WRITE uses while we try to get rid of them. Fixes: 5f60b12edcd0 ("drm/i915/gvt: Save/restore HW status to support GVT suspend/resume") Cc: Zhenyu Wang Cc: Hang Yuan Cc: Colin Xu Cc: Zhi Wang Cc: intel-gvt-dev@lists.freedesktop.org Reviewed-by: Zhenyu Wang Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-9-jani.nikula@intel.com --- drivers/gpu/drm/i915/gvt/handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 62b49c72a7d0..91245d297950 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -3652,7 +3652,7 @@ static inline int mmio_pm_restore_handler(struct intel_gvt *gvt, struct drm_i915_private *dev_priv = gvt->gt->i915; if (gvt->mmio.mmio_attribute[offset >> 2] & F_PM_SAVE) - I915_WRITE(_MMIO(offset), vgpu_vreg(vgpu, offset)); + intel_uncore_write(&dev_priv->uncore, _MMIO(offset), vgpu_vreg(vgpu, offset)); return 0; } From 41a90202cd150a2f1318582a985e27b4a3bd9a8d Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 30 Nov 2020 18:16:21 -0800 Subject: [PATCH 0127/5577] drm/virtio: virtio_{blah} --> virtio_gpu_{blah} virtio_gpu typically uses the prefix virtio_gpu, but there are a few places where the virtio prefix is used. Modify this for consistency. v3: add r-b tags Signed-off-by: Gurchetan Singh Reviewed-by: Anthoine Bourgeois Link: http://patchwork.freedesktop.org/patch/msgid/20201201021623.619-1-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 24 ++++++++++-------- drivers/gpu/drm/virtio/virtgpu_fence.c | 32 +++++++++++++----------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index 5fefc88d47e4..c2b20e0ee030 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -28,14 +28,13 @@ #include "virtgpu_drv.h" -static void virtio_add_bool(struct seq_file *m, const char *name, - bool value) +static void virtio_gpu_add_bool(struct seq_file *m, const char *name, + bool value) { seq_printf(m, "%-16s : %s\n", name, value ? "yes" : "no"); } -static void virtio_add_int(struct seq_file *m, const char *name, - int value) +static void virtio_gpu_add_int(struct seq_file *m, const char *name, int value) { seq_printf(m, "%-16s : %d\n", name, value); } @@ -45,13 +44,16 @@ static int virtio_gpu_features(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct virtio_gpu_device *vgdev = node->minor->dev->dev_private; - virtio_add_bool(m, "virgl", vgdev->has_virgl_3d); - virtio_add_bool(m, "edid", vgdev->has_edid); - virtio_add_bool(m, "indirect", vgdev->has_indirect); - virtio_add_bool(m, "resource uuid", vgdev->has_resource_assign_uuid); - virtio_add_bool(m, "blob resources", vgdev->has_resource_blob); - virtio_add_int(m, "cap sets", vgdev->num_capsets); - virtio_add_int(m, "scanouts", vgdev->num_scanouts); + virtio_gpu_add_bool(m, "virgl", vgdev->has_virgl_3d); + virtio_gpu_add_bool(m, "edid", vgdev->has_edid); + virtio_gpu_add_bool(m, "indirect", vgdev->has_indirect); + + virtio_gpu_add_bool(m, "resource uuid", + vgdev->has_resource_assign_uuid); + + virtio_gpu_add_bool(m, "blob resources", vgdev->has_resource_blob); + virtio_gpu_add_int(m, "cap sets", vgdev->num_capsets); + virtio_gpu_add_int(m, "scanouts", vgdev->num_scanouts); if (vgdev->host_visible_region.len) { seq_printf(m, "%-16s : 0x%lx +0x%lx\n", "host visible region", (unsigned long)vgdev->host_visible_region.addr, diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 728ca36f6327..586034c90587 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -27,22 +27,22 @@ #include "virtgpu_drv.h" -#define to_virtio_fence(x) \ +#define to_virtio_gpu_fence(x) \ container_of(x, struct virtio_gpu_fence, f) -static const char *virtio_get_driver_name(struct dma_fence *f) +static const char *virtio_gpu_get_driver_name(struct dma_fence *f) { return "virtio_gpu"; } -static const char *virtio_get_timeline_name(struct dma_fence *f) +static const char *virtio_gpu_get_timeline_name(struct dma_fence *f) { return "controlq"; } -static bool virtio_fence_signaled(struct dma_fence *f) +static bool virtio_gpu_fence_signaled(struct dma_fence *f) { - struct virtio_gpu_fence *fence = to_virtio_fence(f); + struct virtio_gpu_fence *fence = to_virtio_gpu_fence(f); if (WARN_ON_ONCE(fence->f.seqno == 0)) /* leaked fence outside driver before completing @@ -53,25 +53,26 @@ static bool virtio_fence_signaled(struct dma_fence *f) return false; } -static void virtio_fence_value_str(struct dma_fence *f, char *str, int size) +static void virtio_gpu_fence_value_str(struct dma_fence *f, char *str, int size) { snprintf(str, size, "%llu", f->seqno); } -static void virtio_timeline_value_str(struct dma_fence *f, char *str, int size) +static void virtio_gpu_timeline_value_str(struct dma_fence *f, char *str, + int size) { - struct virtio_gpu_fence *fence = to_virtio_fence(f); + struct virtio_gpu_fence *fence = to_virtio_gpu_fence(f); snprintf(str, size, "%llu", (u64)atomic64_read(&fence->drv->last_fence_id)); } -static const struct dma_fence_ops virtio_fence_ops = { - .get_driver_name = virtio_get_driver_name, - .get_timeline_name = virtio_get_timeline_name, - .signaled = virtio_fence_signaled, - .fence_value_str = virtio_fence_value_str, - .timeline_value_str = virtio_timeline_value_str, +static const struct dma_fence_ops virtio_gpu_fence_ops = { + .get_driver_name = virtio_gpu_get_driver_name, + .get_timeline_name = virtio_gpu_get_timeline_name, + .signaled = virtio_gpu_fence_signaled, + .fence_value_str = virtio_gpu_fence_value_str, + .timeline_value_str = virtio_gpu_timeline_value_str, }; struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) @@ -88,7 +89,8 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) * unknown yet. The fence must not be used outside of the driver * until virtio_gpu_fence_emit is called. */ - dma_fence_init(&fence->f, &virtio_fence_ops, &drv->lock, drv->context, 0); + dma_fence_init(&fence->f, &virtio_gpu_fence_ops, &drv->lock, drv->context, + 0); return fence; } From b9662c3a54eba1a06e2c14744dd78b065df120c5 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 30 Nov 2020 18:16:22 -0800 Subject: [PATCH 0128/5577] drm/virtio: rework virtio_fence_signaled virtio_gpu_fence_event_process sets the last_fence_id and subsequently calls dma_fence_signal_locked(..). dma_fence_signal_locked(..) sets DMA_FENCE_FLAG_SIGNALED_BIT, which is actually checked before &dma_fence_ops.(*signaled) is called. The check for last_fence_id is therefore a bit redundant, and it will not be sufficient to check the last_fence_id for multiple synchronization timelines. Remove it. v3: add r-b tags Signed-off-by: Gurchetan Singh Reviewed-by: Anthoine Bourgeois Link: http://patchwork.freedesktop.org/patch/msgid/20201201021623.619-2-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_fence.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 586034c90587..b35fcd1d02d7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -42,14 +42,10 @@ static const char *virtio_gpu_get_timeline_name(struct dma_fence *f) static bool virtio_gpu_fence_signaled(struct dma_fence *f) { - struct virtio_gpu_fence *fence = to_virtio_gpu_fence(f); - - if (WARN_ON_ONCE(fence->f.seqno == 0)) - /* leaked fence outside driver before completing - * initialization with virtio_gpu_fence_emit */ - return false; - if (atomic64_read(&fence->drv->last_fence_id) >= fence->f.seqno) - return true; + /* leaked fence outside driver before completing + * initialization with virtio_gpu_fence_emit. + */ + WARN_ON_ONCE(f->seqno == 0); return false; } From 36549848ed27c22bb2ffd5d1468efc6505b05f97 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 30 Nov 2020 18:16:23 -0800 Subject: [PATCH 0129/5577] drm/virtio: consider dma-fence context when signaling This an incremental refactor towards multiple dma-fence contexts in virtio-gpu. Since all fences are still allocated using &virtio_gpu_fence_driver.context, nothing should break and every processed fence will be signaled. The overall idea is every 3D context can allocate a number of dma-fence contexts. Each dma-fence context refers to it's own timeline. For example, consider the following case where virgl submits commands to the GPU (fence ids 1, 3) and does a metadata query with the CPU (fence id 5). In a different process, gfxstream submits commands to the GPU (fence ids 2, 4). fence_id (&dma_fence.seqno) | 1 2 3 4 5 ----------------------------------|----------- fence_ctx 0 (virgl gpu) | 1 3 fence_ctx 1 (virgl metadata query)| 5 fence_ctx 2 (gfxstream gpu) | 2 4 With multiple fence contexts, we can wait for the metadata query to finish without waiting for the virgl gpu to finish. virgl gpu does not have to wait for gfxstream gpu. The fence id still is the monotonically increasing sequence number, but it's only revelant to the specific dma-fence context. To fully enable this feature, we'll need to: - have each 3d context allocate a number of fence contexts. Not too hard with explicit context initialization on the horizon. - have guest userspace specify fence context when performing ioctls. - tag each fence emitted to the host with the fence context information. virtio_gpu_ctrl_hdr has padding + flags available, so that should be easy. This change goes in the direction specified above, by: - looking up the virtgpu_fence given a fence_id - signalling all prior fences in a given context - signalling current fence v2: fix grammar in comment v3: add r-b tags Reviewed-by: Anthoine Bourgeois Signed-off-by: Gurchetan Singh Link: http://patchwork.freedesktop.org/patch/msgid/20201201021623.619-3-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_fence.c | 39 ++++++++++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 6a232553c99b..d9dbc4f258f3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -136,6 +136,7 @@ struct virtio_gpu_fence_driver { struct virtio_gpu_fence { struct dma_fence f; + uint64_t fence_id; struct virtio_gpu_fence_driver *drv; struct list_head node; }; diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index b35fcd1d02d7..d28e25e8409b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -51,7 +51,7 @@ static bool virtio_gpu_fence_signaled(struct dma_fence *f) static void virtio_gpu_fence_value_str(struct dma_fence *f, char *str, int size) { - snprintf(str, size, "%llu", f->seqno); + snprintf(str, size, "[%llu, %llu]", f->context, f->seqno); } static void virtio_gpu_timeline_value_str(struct dma_fence *f, char *str, @@ -99,7 +99,7 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, unsigned long irq_flags; spin_lock_irqsave(&drv->lock, irq_flags); - fence->f.seqno = ++drv->current_fence_id; + fence->fence_id = fence->f.seqno = ++drv->current_fence_id; dma_fence_get(&fence->f); list_add_tail(&fence->node, &drv->fences); spin_unlock_irqrestore(&drv->lock, irq_flags); @@ -107,24 +107,45 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, trace_dma_fence_emit(&fence->f); cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE); - cmd_hdr->fence_id = cpu_to_le64(fence->f.seqno); + cmd_hdr->fence_id = cpu_to_le64(fence->fence_id); } void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev, u64 fence_id) { struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; - struct virtio_gpu_fence *fence, *tmp; + struct virtio_gpu_fence *signaled, *curr, *tmp; unsigned long irq_flags; spin_lock_irqsave(&drv->lock, irq_flags); atomic64_set(&vgdev->fence_drv.last_fence_id, fence_id); - list_for_each_entry_safe(fence, tmp, &drv->fences, node) { - if (fence_id < fence->f.seqno) + list_for_each_entry_safe(curr, tmp, &drv->fences, node) { + if (fence_id != curr->fence_id) continue; - dma_fence_signal_locked(&fence->f); - list_del(&fence->node); - dma_fence_put(&fence->f); + + signaled = curr; + + /* + * Signal any fences with a strictly smaller sequence number + * than the current signaled fence. + */ + list_for_each_entry_safe(curr, tmp, &drv->fences, node) { + /* dma-fence contexts must match */ + if (signaled->f.context != curr->f.context) + continue; + + if (!dma_fence_is_later(&signaled->f, &curr->f)) + continue; + + dma_fence_signal_locked(&curr->f); + list_del(&curr->node); + dma_fence_put(&curr->f); + } + + dma_fence_signal_locked(&signaled->f); + list_del(&signaled->node); + dma_fence_put(&signaled->f); + break; } spin_unlock_irqrestore(&drv->lock, irq_flags); } From 348fb0cb0a79bce03f402d689bbe0bf666577531 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 1 Dec 2020 13:17:57 +0000 Subject: [PATCH 0130/5577] drm/i915/pmu: Deprecate I915_PMU_LAST and optimize state tracking Adding any kinds of "last" abi markers is usually a mistake which I repeated when implementing the PMU because it felt convenient at the time. This patch marks I915_PMU_LAST as deprecated and stops the internal implementation using it for sizing the event status bitmask and array. New way of sizing the fields is a bit less elegant, but it omits reserving slots for tracking events we are not interested in, and as such saves some runtime space. Adding sampling events is likely to be a special event and the new plumbing needed will be easily detected in testing. Existing asserts against the bitfield and array sizes are keeping the code safe. First event which gets the new treatment in this new scheme are the interrupts - which neither needs any tracking in i915 pmu nor needs waking up the GPU to read it. v2: * Streamline helper names. (Chris) v3: * Comment which events need tracking. (Chris) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201201131757.206367-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_pmu.c | 84 ++++++++++++++++++++++++--------- drivers/gpu/drm/i915/i915_pmu.h | 35 +++++++++----- include/uapi/drm/i915_drm.h | 2 +- 3 files changed, 87 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index cd786ad12be7..97bb4aaa5236 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -27,8 +27,6 @@ BIT(I915_SAMPLE_WAIT) | \ BIT(I915_SAMPLE_SEMA)) -#define ENGINE_SAMPLE_BITS (1 << I915_PMU_SAMPLE_BITS) - static cpumask_t i915_pmu_cpumask; static unsigned int i915_pmu_target_cpu = -1; @@ -57,17 +55,42 @@ static bool is_engine_config(u64 config) return config < __I915_PMU_OTHER(0); } -static unsigned int config_enabled_bit(u64 config) +static unsigned int other_bit(const u64 config) +{ + unsigned int val; + + switch (config) { + case I915_PMU_ACTUAL_FREQUENCY: + val = __I915_PMU_ACTUAL_FREQUENCY_ENABLED; + break; + case I915_PMU_REQUESTED_FREQUENCY: + val = __I915_PMU_REQUESTED_FREQUENCY_ENABLED; + break; + case I915_PMU_RC6_RESIDENCY: + val = __I915_PMU_RC6_RESIDENCY_ENABLED; + break; + default: + /* + * Events that do not require sampling, or tracking state + * transitions between enabled and disabled can be ignored. + */ + return -1; + } + + return I915_ENGINE_SAMPLE_COUNT + val; +} + +static unsigned int config_bit(const u64 config) { if (is_engine_config(config)) return engine_config_sample(config); else - return ENGINE_SAMPLE_BITS + (config - __I915_PMU_OTHER(0)); + return other_bit(config); } -static u64 config_enabled_mask(u64 config) +static u64 config_mask(u64 config) { - return BIT_ULL(config_enabled_bit(config)); + return BIT_ULL(config_bit(config)); } static bool is_engine_event(struct perf_event *event) @@ -75,15 +98,20 @@ static bool is_engine_event(struct perf_event *event) return is_engine_config(event->attr.config); } -static unsigned int event_enabled_bit(struct perf_event *event) +static unsigned int event_bit(struct perf_event *event) { - return config_enabled_bit(event->attr.config); + return config_bit(event->attr.config); +} + +static bool event_read_needs_wakeref(const struct perf_event *event) +{ + return event->attr.config == I915_PMU_RC6_RESIDENCY; } static bool pmu_needs_timer(struct i915_pmu *pmu, bool gpu_active) { struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu); - u64 enable; + u32 enable; /* * Only some counters need the sampling timer. @@ -96,8 +124,8 @@ static bool pmu_needs_timer(struct i915_pmu *pmu, bool gpu_active) * Mask out all the ones which do not need the timer, or in * other words keep all the ones that could need the timer. */ - enable &= config_enabled_mask(I915_PMU_ACTUAL_FREQUENCY) | - config_enabled_mask(I915_PMU_REQUESTED_FREQUENCY) | + enable &= config_mask(I915_PMU_ACTUAL_FREQUENCY) | + config_mask(I915_PMU_REQUESTED_FREQUENCY) | ENGINE_SAMPLE_MASK; /* @@ -189,7 +217,7 @@ static void park_rc6(struct drm_i915_private *i915) { struct i915_pmu *pmu = &i915->pmu; - if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY)) + if (pmu->enable & config_mask(I915_PMU_RC6_RESIDENCY)) pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); pmu->sleep_last = ktime_get(); @@ -344,8 +372,8 @@ add_sample_mult(struct i915_pmu_sample *sample, u32 val, u32 mul) static bool frequency_sampling_enabled(struct i915_pmu *pmu) { return pmu->enable & - (config_enabled_mask(I915_PMU_ACTUAL_FREQUENCY) | - config_enabled_mask(I915_PMU_REQUESTED_FREQUENCY)); + (config_mask(I915_PMU_ACTUAL_FREQUENCY) | + config_mask(I915_PMU_REQUESTED_FREQUENCY)); } static void @@ -363,7 +391,7 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns) if (!intel_gt_pm_get_if_awake(gt)) return; - if (pmu->enable & config_enabled_mask(I915_PMU_ACTUAL_FREQUENCY)) { + if (pmu->enable & config_mask(I915_PMU_ACTUAL_FREQUENCY)) { u32 val; /* @@ -385,7 +413,7 @@ frequency_sample(struct intel_gt *gt, unsigned int period_ns) intel_gpu_freq(rps, val), period_ns / 1000); } - if (pmu->enable & config_enabled_mask(I915_PMU_REQUESTED_FREQUENCY)) { + if (pmu->enable & config_mask(I915_PMU_REQUESTED_FREQUENCY)) { add_sample_mult(&pmu->sample[__I915_SAMPLE_FREQ_REQ], intel_gpu_freq(rps, rps->cur_freq), period_ns / 1000); @@ -627,12 +655,19 @@ static void i915_pmu_enable(struct perf_event *event) { struct drm_i915_private *i915 = container_of(event->pmu, typeof(*i915), pmu.base); - unsigned int bit = event_enabled_bit(event); + bool need_wakeref = event_read_needs_wakeref(event); struct i915_pmu *pmu = &i915->pmu; - intel_wakeref_t wakeref; + intel_wakeref_t wakeref = 0; unsigned long flags; + unsigned int bit; + + if (need_wakeref) + wakeref = intel_runtime_pm_get(&i915->runtime_pm); + + bit = event_bit(event); + if (bit == -1) + goto update; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); spin_lock_irqsave(&pmu->lock, flags); /* @@ -644,7 +679,7 @@ static void i915_pmu_enable(struct perf_event *event) GEM_BUG_ON(pmu->enable_count[bit] == ~0); if (pmu->enable_count[bit] == 0 && - config_enabled_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) { + config_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) { pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = 0; pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt); pmu->sleep_last = ktime_get(); @@ -684,6 +719,7 @@ static void i915_pmu_enable(struct perf_event *event) spin_unlock_irqrestore(&pmu->lock, flags); +update: /* * Store the current counter value so we can report the correct delta * for all listeners. Even when the event was already enabled and has @@ -691,17 +727,21 @@ static void i915_pmu_enable(struct perf_event *event) */ local64_set(&event->hw.prev_count, __i915_pmu_event_read(event)); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + if (wakeref) + intel_runtime_pm_put(&i915->runtime_pm, wakeref); } static void i915_pmu_disable(struct perf_event *event) { struct drm_i915_private *i915 = container_of(event->pmu, typeof(*i915), pmu.base); - unsigned int bit = event_enabled_bit(event); + unsigned int bit = event_bit(event); struct i915_pmu *pmu = &i915->pmu; unsigned long flags; + if (bit == -1) + return; + spin_lock_irqsave(&pmu->lock, flags); if (is_engine_event(event)) { diff --git a/drivers/gpu/drm/i915/i915_pmu.h b/drivers/gpu/drm/i915/i915_pmu.h index a24885ab415c..e33be99e6454 100644 --- a/drivers/gpu/drm/i915/i915_pmu.h +++ b/drivers/gpu/drm/i915/i915_pmu.h @@ -14,6 +14,21 @@ struct drm_i915_private; +/** + * Non-engine events that we need to track enabled-disabled transition and + * current state. + */ +enum i915_pmu_tracked_events { + __I915_PMU_ACTUAL_FREQUENCY_ENABLED = 0, + __I915_PMU_REQUESTED_FREQUENCY_ENABLED, + __I915_PMU_RC6_RESIDENCY_ENABLED, + __I915_PMU_TRACKED_EVENT_COUNT, /* count marker */ +}; + +/** + * Slots used from the sampling timer (non-engine events) with some extras for + * convenience. + */ enum { __I915_SAMPLE_FREQ_ACT = 0, __I915_SAMPLE_FREQ_REQ, @@ -28,8 +43,7 @@ enum { * It is also used to know to needed number of event reference counters. */ #define I915_PMU_MASK_BITS \ - ((1 << I915_PMU_SAMPLE_BITS) + \ - (I915_PMU_LAST + 1 - __I915_PMU_OTHER(0))) + (I915_ENGINE_SAMPLE_COUNT + __I915_PMU_TRACKED_EVENT_COUNT) #define I915_ENGINE_SAMPLE_COUNT (I915_SAMPLE_SEMA + 1) @@ -66,18 +80,17 @@ struct i915_pmu { */ struct hrtimer timer; /** - * @enable: Bitmask of all currently enabled events. + * @enable: Bitmask of specific enabled events. * - * Bits are derived from uAPI event numbers in a way that low 16 bits - * correspond to engine event _sample_ _type_ (I915_SAMPLE_QUEUED is - * bit 0), and higher bits correspond to other events (for instance - * I915_PMU_ACTUAL_FREQUENCY is bit 16 etc). + * For some events we need to track their state and do some internal + * house keeping. * - * In other words, low 16 bits are not per engine but per engine - * sampler type, while the upper bits are directly mapped to other - * event types. + * Each engine event sampler type and event listed in enum + * i915_pmu_tracked_events gets a bit in this field. + * + * Low bits are engine samplers and other events continue from there. */ - u64 enable; + u32 enable; /** * @timer_last: diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index fa1f3d62f9a6..6edcb2b6c708 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -178,7 +178,7 @@ enum drm_i915_pmu_engine_sample { #define I915_PMU_INTERRUPTS __I915_PMU_OTHER(2) #define I915_PMU_RC6_RESIDENCY __I915_PMU_OTHER(3) -#define I915_PMU_LAST I915_PMU_RC6_RESIDENCY +#define I915_PMU_LAST /* Deprecated - do not use */ I915_PMU_RC6_RESIDENCY /* Each region is a minimum of 16k, and there are at most 255 of them. */ From a7e2e1c50450c6a0f020b35960edecbe25dde520 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 30 Nov 2020 16:26:12 +0000 Subject: [PATCH 0131/5577] drm: document that user-space should force-probe connectors It seems like we can't have nice things, so let's just document the disappointing behaviour instead. The previous version assumed the kernel would perform the probing work when appropriate, however this is not the case today. Update the documentation to reflect reality. v2: - Improve commit message to explain why this change is made (Pekka) - Keep the bit about flickering (Daniel) - Explain when user-space should force-probe, and when it shouldn't (Daniel) Signed-off-by: Simon Ser Fixes: 2ac5ef3b2362 ("drm: document drm_mode_get_connector") Reviewed-by: Daniel Vetter Reviewed-by: Pekka Paalanen Cc: Ville Syrjala Link: https://patchwork.freedesktop.org/patch/msgid/AxqLnTAsFCRishOVB5CLsqIesmrMrm7oytnOVB7oPA@cp7-web-043.plabs.ch --- include/uapi/drm/drm_mode.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index b49fbf2bdc40..1c064627e6c3 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -414,15 +414,12 @@ enum drm_mode_subconnector { * * If the @count_modes field is set to zero, the kernel will perform a forced * probe on the connector to refresh the connector status, modes and EDID. - * A forced-probe can be slow and the ioctl will block. A force-probe can cause - * flickering and temporary freezes, so it should not be performed - * automatically. + * A forced-probe can be slow, might cause flickering and the ioctl will block. * - * User-space shouldn't need to force-probe connectors in general: the kernel - * will automatically take care of probing connectors that don't support - * hot-plug detection when appropriate. However, user-space may force-probe - * connectors on user request (e.g. clicking a "Scan connectors" button, or - * opening a UI to manage screens). + * User-space needs to force-probe connectors to ensure their metadata is + * up-to-date at startup and after receiving a hot-plug event. User-space + * may perform a forced-probe when the user explicitly requests it. User-space + * shouldn't perform a forced-probe in other situations. */ struct drm_mode_get_connector { /** @encoders_ptr: Pointer to ``__u32`` array of object IDs. */ From 91bd7a441bf03f87fca72517541aa6e79909a624 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Wed, 2 Dec 2020 00:34:05 +0530 Subject: [PATCH 0132/5577] drm/i915/display/tgl: Disable FBC with PSR2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are some corner cases wrt underrun when we enable FBC with PSR2 on TGL. Recommendation from hardware is to keep this combination disabled. Bspec: 50422 HSD: 14010260002 v2: Added psr2 enabled check from crtc_state (Anshuman) Added Bspec link and HSD referneces (Jose) v3: Moved the logic to disable fbc to intel_fbc_update_state_cache and removed the crtc->config usages, as per Ville's recommendation. v4: Introduced a variable in fbc state_cache instead of the earlier plane.visible WA, as suggested by Jose. v5: Dropped an extra check for fbc in intel_fbc_enable and addressed review comments by Jose. v6: Move WA to end of function and added Jose's RB. Signed-off-by: Uma Shankar Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20201201190406.1752-2-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 12 ++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index a5b072816a7b..f5d5a648cb22 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -742,6 +742,8 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, cache->fence_id = plane_state->vma->fence->id; else cache->fence_id = -1; + + cache->psr2_active = crtc_state->has_psr2; } static bool intel_fbc_cfb_size_changed(struct drm_i915_private *dev_priv) @@ -914,6 +916,16 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return false; } + /* + * Tigerlake is not supporting FBC with PSR2. + * Recommendation is to keep this combination disabled + * Bspec: 50422 HSD: 14010260002 + */ + if (fbc->state_cache.psr2_active && IS_TIGERLAKE(dev_priv)) { + fbc->no_fbc_reason = "not supported with PSR2"; + return false; + } + return true; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 25af27e38764..972a52e35fb8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -416,6 +416,7 @@ struct intel_fbc { u16 gen9_wa_cfb_stride; u16 interval; s8 fence_id; + bool psr2_active; } state_cache; /* From f9c914a5b946e3e85fff939ebb7e36057b0c410d Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Wed, 2 Dec 2020 00:34:06 +0530 Subject: [PATCH 0133/5577] Revert "drm/i915/display/fbc: Disable fbc by default on TGL" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FBC can be re-enabled on TGL with WA of keeping it disabled while PSR2 is enabled. This reverts commit 2982ded2ff5ce0cf1a49bc39a526da182782b664. Signed-off-by: Uma Shankar Reviewed-by: José Roberto de Souza Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201201190406.1752-3-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index f5d5a648cb22..33200b5cfad0 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1445,13 +1445,6 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) if (!HAS_FBC(dev_priv)) return 0; - /* - * Fbc is causing random underruns in CI execution on TGL platforms. - * Disabling the same while the problem is being debugged and analyzed. - */ - if (IS_TIGERLAKE(dev_priv)) - return 0; - if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) return 1; From 54b3f0e6817314ff6b9a354c32a4ff217cea33d1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:16:01 +0200 Subject: [PATCH 0134/5577] drm/i915: remove last traces of I915_READ(), I915_WRITE() and POSTING_READ() Good riddance! Remove the macros and their remaining references in comments. The following functions should be used instead, depending on the use case: - intel_uncore_read(), intel_uncore_write(), intel_uncore_posting_read() - intel_de_read(), intel_de_write(), intel_de_posting_read() Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130111601.2817-10-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dvo.c | 4 ---- drivers/gpu/drm/i915/i915_drv.h | 8 -------- drivers/gpu/drm/i915/i915_reg.h | 6 ++++-- drivers/gpu/drm/i915/intel_sideband.c | 4 ++-- drivers/gpu/drm/i915/intel_uncore.c | 2 +- drivers/gpu/drm/i915/intel_uncore.h | 4 ++-- 6 files changed, 9 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index 237dbb1ba0ee..090cd76266c6 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -301,12 +301,8 @@ static void intel_dvo_pre_enable(struct intel_atomic_state *state, if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) dvo_val |= DVO_VSYNC_ACTIVE_HIGH; - /*I915_WRITE(DVOB_SRCDIM, - (adjusted_mode->crtc_hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | - (adjusted_mode->crtc_vdisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ intel_de_write(dev_priv, dvo_srcdim_reg, (adjusted_mode->crtc_hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | (adjusted_mode->crtc_vdisplay << DVO_SRCDIM_VERTICAL_SHIFT)); - /*I915_WRITE(DVOB, dvo_val);*/ intel_de_write(dev_priv, dvo_reg, dvo_val); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 972a52e35fb8..5a7df5621aa3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1972,14 +1972,6 @@ mkwrite_device_info(struct drm_i915_private *dev_priv) int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file); -#define __I915_REG_OP(op__, dev_priv__, ...) \ - intel_uncore_##op__(&(dev_priv__)->uncore, __VA_ARGS__) - -#define I915_READ(reg__) __I915_REG_OP(read, dev_priv, (reg__)) -#define I915_WRITE(reg__, val__) __I915_REG_OP(write, dev_priv, (reg__), (val__)) - -#define POSTING_READ(reg__) __I915_REG_OP(posting_read, dev_priv, (reg__)) - /* i915_mm.c */ int remap_io_mapping(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index fe1b3692d6ca..a8c4d16b7c30 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10853,8 +10853,10 @@ enum skl_power_gate { #define CNL_DRAM_RANK_3 (0x2 << 9) #define CNL_DRAM_RANK_4 (0x3 << 9) -/* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, - * since on HSW we can't write to it using I915_WRITE. */ +/* + * Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, + * since on HSW we can't write to it using intel_uncore_write. + */ #define D_COMP_HSW _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5F0C) #define D_COMP_BDW _MMIO(0x138144) #define D_COMP_RCOMP_IN_PROGRESS (1 << 9) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 02ebf5a04a9b..0ec0cf191955 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -404,8 +404,8 @@ static int __sandybridge_pcode_rw(struct drm_i915_private *i915, lockdep_assert_held(&i915->sb_lock); /* - * GEN6_PCODE_* are outside of the forcewake domain, we can - * use te fw I915_READ variants to reduce the amount of work + * GEN6_PCODE_* are outside of the forcewake domain, we can use + * intel_uncore_read/write_fw variants to reduce the amount of work * required when reading/writing. */ diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index ef40edfff412..9ac501bcfdad 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -2126,7 +2126,7 @@ int __intel_wait_for_register_fw(struct intel_uncore *uncore, * This routine waits until the target register @reg contains the expected * @value after applying the @mask, i.e. it waits until :: * - * (I915_READ(reg) & mask) == value + * (intel_uncore_read(uncore, reg) & mask) == value * * Otherwise, the wait will timeout after @timeout_ms milliseconds. * diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 5dcb7f4183b2..59f0da8f1fbb 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -318,8 +318,8 @@ __uncore_write(write_notrace, 32, l, false) * will be implemented using 2 32-bit writes in an arbitrary order with * an arbitrary delay between them. This can cause the hardware to * act upon the intermediate value, possibly leading to corruption and - * machine death. For this reason we do not support I915_WRITE64, or - * uncore->funcs.mmio_writeq. + * machine death. For this reason we do not support intel_uncore_write64, + * or uncore->funcs.mmio_writeq. * * When reading a 64-bit value as two 32-bit values, the delay may cause * the two reads to mismatch, e.g. a timestamp overflowing. Also note that From 840291a7b90b97246d430227aa9a157b7f26e98c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Dec 2020 13:04:06 +0000 Subject: [PATCH 0135/5577] drm/i915/selftests: Tidy prng constructor for client blits Since we only initialise the prng once within the scope of the selftest, we can use the default initialiser. Signed-off-by: Chris Wilson Cc: Matthew Auld Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20201202130406.18461-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c index 4e36d4897ea6..6a674a7994df 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c @@ -20,13 +20,11 @@ static int __igt_client_fill(struct intel_engine_cs *engine) { struct intel_context *ce = engine->kernel_context; struct drm_i915_gem_object *obj; - struct rnd_state prng; + I915_RND_STATE(prng); IGT_TIMEOUT(end); u32 *vaddr; int err = 0; - prandom_seed_state(&prng, i915_selftest.random_seed); - intel_engine_pm_get(engine); do { const u32 max_block_size = S16_MAX * PAGE_SIZE; From a2843b3bd17e5a1c6b270709dc5bb0091eba1074 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Dec 2020 17:34:43 +0000 Subject: [PATCH 0136/5577] drm/i915/gem: Limit lmem scatterlist elements to UINT_MAX Adhere to the i915_sg_max_segment() limit on the lengths of individual scatterlist elements, and in doing so split up very large chunks of lmem into manageable pieces for the dma-mapping backend. Reported-by: Venkata Sandeep Dhanalakota Suggested-by: Matthew Auld Signed-off-by: Chris Wilson Cc: Venkata Sandeep Dhanalakota Cc: Matthew Auld Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20201202173444.14903-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gem/i915_gem_region.c | 36 ++++++++++--------- .../drm/i915/selftests/intel_memory_region.c | 27 ++++++++++---- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index e72d78074c9e..7d05b5f346c1 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -22,6 +22,7 @@ i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj, int i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) { + const u64 max_segment = i915_sg_segment_size(); struct intel_memory_region *mem = obj->mm.region; struct list_head *blocks = &obj->mm.blocks; resource_size_t size = obj->base.size; @@ -37,7 +38,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) if (!st) return -ENOMEM; - if (sg_alloc_table(st, size >> ilog2(mem->mm.chunk_size), GFP_KERNEL)) { + if (sg_alloc_table(st, size >> PAGE_SHIFT, GFP_KERNEL)) { kfree(st); return -ENOMEM; } @@ -64,27 +65,30 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) i915_buddy_block_size(&mem->mm, block)); offset = i915_buddy_block_offset(block); - GEM_BUG_ON(overflows_type(block_size, sg->length)); + while (block_size) { + u64 len; - if (offset != prev_end || - add_overflows_t(typeof(sg->length), sg->length, block_size)) { - if (st->nents) { - sg_page_sizes |= sg->length; - sg = __sg_next(sg); + if (offset != prev_end || sg->length >= max_segment) { + if (st->nents) { + sg_page_sizes |= sg->length; + sg = __sg_next(sg); + } + + sg_dma_address(sg) = mem->region.start + offset; + sg_dma_len(sg) = 0; + sg->length = 0; + st->nents++; } - sg_dma_address(sg) = mem->region.start + offset; - sg_dma_len(sg) = block_size; + len = min(block_size, max_segment - sg->length); + sg->length += len; + sg_dma_len(sg) += len; - sg->length = block_size; + offset += len; + block_size -= len; - st->nents++; - } else { - sg->length += block_size; - sg_dma_len(sg) += block_size; + prev_end = offset; } - - prev_end = offset + block_size; } sg_page_sizes |= sg->length; diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 55ccd957a009..7c02a0c16fc1 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -129,6 +129,21 @@ static void igt_object_release(struct drm_i915_gem_object *obj) i915_gem_object_put(obj); } +static bool is_contiguous(struct drm_i915_gem_object *obj) +{ + struct scatterlist *sg; + dma_addr_t addr = -1; + + for (sg = obj->mm.pages->sgl; sg; sg = sg_next(sg)) { + if (addr != -1 && sg_dma_address(sg) != addr) + return false; + + addr = sg_dma_address(sg) + sg_dma_len(sg); + } + + return true; +} + static int igt_mock_contiguous(void *arg) { struct intel_memory_region *mem = arg; @@ -150,8 +165,8 @@ static int igt_mock_contiguous(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); - if (obj->mm.pages->nents != 1) { - pr_err("%s min object spans multiple sg entries\n", __func__); + if (!is_contiguous(obj)) { + pr_err("%s min object spans disjoint sg entries\n", __func__); err = -EINVAL; goto err_close_objects; } @@ -163,8 +178,8 @@ static int igt_mock_contiguous(void *arg) if (IS_ERR(obj)) return PTR_ERR(obj); - if (obj->mm.pages->nents != 1) { - pr_err("%s max object spans multiple sg entries\n", __func__); + if (!is_contiguous(obj)) { + pr_err("%s max object spans disjoint sg entries\n", __func__); err = -EINVAL; goto err_close_objects; } @@ -189,8 +204,8 @@ static int igt_mock_contiguous(void *arg) goto err_close_objects; } - if (obj->mm.pages->nents != 1) { - pr_err("%s object spans multiple sg entries\n", __func__); + if (!is_contiguous(obj)) { + pr_err("%s object spans disjoint sg entries\n", __func__); err = -EINVAL; goto err_close_objects; } From 7d1a31e128d3cb939cd70c95f898c13f85155571 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Dec 2020 17:34:44 +0000 Subject: [PATCH 0137/5577] Revert "drm/i915/lmem: Limit block size to 4G" Mixing I915_ALLOC_CONTIGUOUS and I915_ALLOC_MAX_SEGMENT_SIZE fared badly. The two directives conflict, with the contiguous request setting the min_order to the full size of the object, and the max-segment-size setting the max_order to the limit of the DMA mapper. This results in a situation where max_order < min_order, causing our sanity checks to fail. Instead of limiting the buddy block size, in the previous patch we split the oversized buddy into multiple scatterlist elements. Fixes: d2cf0125d4a1 ("drm/i915/lmem: Limit block size to 4G") Signed-off-by: Chris Wilson Cc: Niranjana Vishwanathapura Cc: Matthew Auld Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20201202173444.14903-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gem/i915_gem_region.c | 2 +- drivers/gpu/drm/i915/intel_memory_region.c | 18 +--------- drivers/gpu/drm/i915/intel_memory_region.h | 5 ++- .../drm/i915/selftests/intel_memory_region.c | 33 ++++++++++++------- 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index 7d05b5f346c1..835bd01f2e5d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -43,7 +43,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) return -ENOMEM; } - flags = I915_ALLOC_MIN_PAGE_SIZE | I915_ALLOC_MAX_SEGMENT_SIZE; + flags = I915_ALLOC_MIN_PAGE_SIZE; if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) flags |= I915_ALLOC_CONTIGUOUS; diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index ae36e2f6d6e3..b326993a1026 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -72,7 +72,6 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem, struct list_head *blocks) { unsigned int min_order = 0; - unsigned int max_order; unsigned long n_pages; GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.chunk_size)); @@ -93,28 +92,13 @@ __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem, n_pages = size >> ilog2(mem->mm.chunk_size); - /* - * If we going to feed this into an sg list we should limit the block - * sizes such that we don't exceed the i915_sg_segment_size(). - */ - if (flags & I915_ALLOC_MAX_SEGMENT_SIZE) { - unsigned int max_segment = i915_sg_segment_size(); - - if (GEM_WARN_ON(max_segment < mem->mm.chunk_size)) - max_order = 0; - else - max_order = ilog2(max_segment) - ilog2(mem->mm.chunk_size); - } else { - max_order = mem->mm.max_order; - } - mutex_lock(&mem->mm_lock); do { struct i915_buddy_block *block; unsigned int order; - order = min_t(u32, fls(n_pages) - 1, max_order); + order = fls(n_pages) - 1; GEM_BUG_ON(order > mem->mm.max_order); GEM_BUG_ON(order < min_order); diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h index 5fb9bcf86b97..232490d89a83 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.h +++ b/drivers/gpu/drm/i915/intel_memory_region.h @@ -44,9 +44,8 @@ enum intel_region_id { #define MEMORY_TYPE_FROM_REGION(r) (ilog2((r) >> INTEL_MEMORY_TYPE_SHIFT)) #define MEMORY_INSTANCE_FROM_REGION(r) (ilog2((r) & 0xffff)) -#define I915_ALLOC_MIN_PAGE_SIZE BIT(0) -#define I915_ALLOC_CONTIGUOUS BIT(1) -#define I915_ALLOC_MAX_SEGMENT_SIZE BIT(2) +#define I915_ALLOC_MIN_PAGE_SIZE BIT(0) +#define I915_ALLOC_CONTIGUOUS BIT(1) #define for_each_memory_region(mr, i915, id) \ for (id = 0; id < ARRAY_SIZE((i915)->mm.regions); id++) \ diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 7c02a0c16fc1..a0b518c255de 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -356,21 +356,21 @@ out_put: static int igt_mock_max_segment(void *arg) { + const unsigned int max_segment = i915_sg_segment_size(); struct intel_memory_region *mem = arg; struct drm_i915_private *i915 = mem->i915; struct drm_i915_gem_object *obj; struct i915_buddy_block *block; + struct scatterlist *sg; LIST_HEAD(objects); u64 size; int err = 0; /* - * The size of block are only limited by the largest power-of-two that - * will fit in the region size, but to construct an object we also - * require feeding it into an sg list, where the upper limit of the sg - * entry is at most UINT_MAX, therefore when allocating with - * I915_ALLOC_MAX_SEGMENT_SIZE we shouldn't see blocks larger than - * i915_sg_segment_size(). + * While we may create very large contiguous blocks, we may need + * to break those down for consumption elsewhere. In particular, + * dma-mapping with scatterlist elements have an implicit limit of + * UINT_MAX on each element. */ size = SZ_8G; @@ -384,12 +384,23 @@ static int igt_mock_max_segment(void *arg) goto out_put; } + err = -EINVAL; list_for_each_entry(block, &obj->mm.blocks, link) { - if (i915_buddy_block_size(&mem->mm, block) > i915_sg_segment_size()) { - pr_err("%s found block size(%llu) larger than max sg_segment_size(%u)", - __func__, - i915_buddy_block_size(&mem->mm, block), - i915_sg_segment_size()); + if (i915_buddy_block_size(&mem->mm, block) > max_segment) { + err = 0; + break; + } + } + if (err) { + pr_err("%s: Failed to create a huge contiguous block\n", + __func__); + goto out_close; + } + + for (sg = obj->mm.pages->sgl; sg; sg = sg_next(sg)) { + if (sg->length > max_segment) { + pr_err("%s: Created an oversized scatterlist entry, %u > %u\n", + __func__, sg->length, max_segment); err = -EINVAL; goto out_close; } From 829270e4552e9e6a0534d4d195f671363cb39e3e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Dec 2020 21:28:14 +0000 Subject: [PATCH 0138/5577] drm/i915/display: Record the plane update times for debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we try and estimate how long we require to update the registers to perform a plane update, it is of vital importance that we measure the distribution of plane updates to better guide our estimate. If we underestimate how long it takes to perform the plane update, we may slip into the next scanout frame causing a tear. If we overestimate, we may unnecessarily delay the update to the next frame, causing visible jitter. Replace the warning that we exceed some arbitrary threshold for the vblank update with a histogram for debugfs. v2: Add a per-crtc debugfs entry so that the information is easier to extract when testing individual CRTC, and so that it can be reset before a test. v3: Flip the graph on its side; creates space to label the time axis. Updates: 4684 | 1us | | 4us |******** |********** 16us |*********** |***** 66us | | 262us | | 1ms | | 4ms | | 17ms | | Min update: 5918ns Max update: 54781ns Average update: 16628ns Overruns > 250us: 0 Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/1982 Signed-off-by: Chris Wilson Cc: Jani Nikula Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä #v2 Link: https://patchwork.freedesktop.org/patch/msgid/20201202212814.26320-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/display/intel_display.c | 10 +- .../drm/i915/display/intel_display_debugfs.c | 124 ++++++++++++++++++ .../drm/i915/display/intel_display_debugfs.h | 3 + .../drm/i915/display/intel_display_types.h | 9 ++ drivers/gpu/drm/i915/display/intel_sprite.c | 49 ++++--- drivers/gpu/drm/i915/display/intel_sprite.h | 10 ++ 6 files changed, 187 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ba26545392bc..9187a20a8aca 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -45,6 +45,7 @@ #include "display/intel_crt.h" #include "display/intel_ddi.h" +#include "display/intel_display_debugfs.h" #include "display/intel_dp.h" #include "display/intel_dp_mst.h" #include "display/intel_dpll_mgr.h" @@ -17266,6 +17267,12 @@ fail: return ERR_PTR(ret); } +static int intel_crtc_late_register(struct drm_crtc *crtc) +{ + intel_crtc_debugfs_add(crtc); + return 0; +} + #define INTEL_CRTC_FUNCS \ .gamma_set = drm_atomic_helper_legacy_gamma_set, \ .set_config = drm_atomic_helper_set_config, \ @@ -17275,7 +17282,8 @@ fail: .atomic_destroy_state = intel_crtc_destroy_state, \ .set_crc_source = intel_crtc_set_crc_source, \ .verify_crc_source = intel_crtc_verify_crc_source, \ - .get_crc_sources = intel_crtc_get_crc_sources + .get_crc_sources = intel_crtc_get_crc_sources, \ + .late_register = intel_crtc_late_register static const struct drm_crtc_funcs bdw_crtc_funcs = { INTEL_CRTC_FUNCS, diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index ca41e8c00ad7..cd7e5519ee7d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -18,6 +18,7 @@ #include "intel_pm.h" #include "intel_psr.h" #include "intel_sideband.h" +#include "intel_sprite.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) { @@ -865,6 +866,110 @@ static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc) } } +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE) +static void crtc_updates_info(struct seq_file *m, + struct intel_crtc *crtc, + const char *hdr) +{ + u64 count; + int row; + + count = 0; + for (row = 0; row < ARRAY_SIZE(crtc->debug.vbl.times); row++) + count += crtc->debug.vbl.times[row]; + seq_printf(m, "%sUpdates: %llu\n", hdr, count); + if (!count) + return; + + for (row = 0; row < ARRAY_SIZE(crtc->debug.vbl.times); row++) { + char columns[80] = " |"; + unsigned int x; + + if (row & 1) { + const char *units; + + if (row > 10) { + x = 1000000; + units = "ms"; + } else { + x = 1000; + units = "us"; + } + + snprintf(columns, sizeof(columns), "%4ld%s |", + DIV_ROUND_CLOSEST(BIT(row + 9), x), units); + } + + if (crtc->debug.vbl.times[row]) { + x = ilog2(crtc->debug.vbl.times[row]); + memset(columns + 8, '*', x); + columns[8 + x] = '\0'; + } + + seq_printf(m, "%s%s\n", hdr, columns); + } + + seq_printf(m, "%sMin update: %lluns\n", + hdr, crtc->debug.vbl.min); + seq_printf(m, "%sMax update: %lluns\n", + hdr, crtc->debug.vbl.max); + seq_printf(m, "%sAverage update: %lluns\n", + hdr, div64_u64(crtc->debug.vbl.sum, count)); + seq_printf(m, "%sOverruns > %uus: %u\n", + hdr, VBLANK_EVASION_TIME_US, crtc->debug.vbl.over); +} + +static int crtc_updates_show(struct seq_file *m, void *data) +{ + crtc_updates_info(m, m->private, ""); + return 0; +} + +static int crtc_updates_open(struct inode *inode, struct file *file) +{ + return single_open(file, crtc_updates_show, inode->i_private); +} + +static ssize_t crtc_updates_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct intel_crtc *crtc = m->private; + + /* May race with an update. Meh. */ + memset(&crtc->debug.vbl, 0, sizeof(crtc->debug.vbl)); + + return len; +} + +static const struct file_operations crtc_updates_fops = { + .owner = THIS_MODULE, + .open = crtc_updates_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = crtc_updates_write +}; + +static void crtc_updates_add(struct drm_crtc *crtc) +{ + debugfs_create_file("i915_update_info", 0644, crtc->debugfs_entry, + to_intel_crtc(crtc), &crtc_updates_fops); +} + +#else +static void crtc_updates_info(struct seq_file *m, + struct intel_crtc *crtc, + const char *hdr) +{ +} + +static void crtc_updates_add(struct drm_crtc *crtc) +{ +} +#endif + static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -907,6 +1012,8 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s\n", yesno(!crtc->cpu_fifo_underrun_disabled), yesno(!crtc->pch_fifo_underrun_disabled)); + + crtc_updates_info(m, crtc, "\t"); } static int i915_display_info(struct seq_file *m, void *unused) @@ -2278,3 +2385,20 @@ int intel_connector_debugfs_add(struct drm_connector *connector) return 0; } + +/** + * intel_crtc_debugfs_add - add i915 specific crtc debugfs files + * @crtc: pointer to a drm_crtc + * + * Returns 0 on success, negative error codes on error. + * + * Failure to add debugfs entries should generally be ignored. + */ +int intel_crtc_debugfs_add(struct drm_crtc *crtc) +{ + if (!crtc->debugfs_entry) + return -ENODEV; + + crtc_updates_add(crtc); + return 0; +} diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.h b/drivers/gpu/drm/i915/display/intel_display_debugfs.h index c922c1745bfe..557901f3eb90 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.h +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.h @@ -7,14 +7,17 @@ #define __INTEL_DISPLAY_DEBUGFS_H__ struct drm_connector; +struct drm_crtc; struct drm_i915_private; #ifdef CONFIG_DEBUG_FS void intel_display_debugfs_register(struct drm_i915_private *i915); int intel_connector_debugfs_add(struct drm_connector *connector); +int intel_crtc_debugfs_add(struct drm_crtc *crtc); #else static inline void intel_display_debugfs_register(struct drm_i915_private *i915) {} static inline int intel_connector_debugfs_add(struct drm_connector *connector) { return 0; } +static inline int intel_crtc_debugfs_add(struct drm_crtc *crtc) { return 0; } #endif #endif /* __INTEL_DISPLAY_DEBUGFS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 491e3550174f..d426dd31479e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1188,6 +1188,15 @@ struct intel_crtc { ktime_t start_vbl_time; int min_vbl, max_vbl; int scanline_start; +#ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE + struct { + u64 min; + u64 max; + u64 sum; + unsigned int over; + unsigned int times[17]; /* [1us, 16ms] */ + } vbl; +#endif } debug; /* scalers available on this crtc */ diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 019a2d6d807a..b7e208816074 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -61,14 +61,6 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 1000 * adjusted_mode->crtc_htotal); } -/* FIXME: We should instead only take spinlocks once for the entire update - * instead of once per mmio. */ -#if IS_ENABLED(CONFIG_PROVE_LOCKING) -#define VBLANK_EVASION_TIME_US 250 -#else -#define VBLANK_EVASION_TIME_US 100 -#endif - /** * intel_pipe_update_start() - start update of a set of display registers * @new_crtc_state: the new crtc state @@ -187,6 +179,36 @@ irq_disable: local_irq_disable(); } +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE) +static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end) +{ + u64 delta = ktime_to_ns(ktime_sub(end, crtc->debug.start_vbl_time)); + unsigned int h; + + h = ilog2(delta >> 9); + if (h >= ARRAY_SIZE(crtc->debug.vbl.times)) + h = ARRAY_SIZE(crtc->debug.vbl.times) - 1; + crtc->debug.vbl.times[h]++; + + crtc->debug.vbl.sum += delta; + if (!crtc->debug.vbl.min || delta < crtc->debug.vbl.min) + crtc->debug.vbl.min = delta; + if (delta > crtc->debug.vbl.max) + crtc->debug.vbl.max = delta; + + if (delta > 1000 * VBLANK_EVASION_TIME_US) { + drm_dbg_kms(crtc->base.dev, + "Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n", + pipe_name(crtc->pipe), + div_u64(delta, 1000), + VBLANK_EVASION_TIME_US); + crtc->debug.vbl.over++; + } +} +#else +static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end) {} +#endif + /** * intel_pipe_update_end() - end update of a set of display registers * @new_crtc_state: the new crtc state @@ -249,15 +271,8 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) crtc->debug.min_vbl, crtc->debug.max_vbl, crtc->debug.scanline_start, scanline_end); } -#ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE - else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) > - VBLANK_EVASION_TIME_US) - drm_warn(&dev_priv->drm, - "Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n", - pipe_name(pipe), - ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), - VBLANK_EVASION_TIME_US); -#endif + + dbg_vblank_evade(crtc, end_vbl_time); } int intel_plane_check_stride(const struct intel_plane_state *plane_state) diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h index cd2104ba1ca1..76126dd8d584 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.h +++ b/drivers/gpu/drm/i915/display/intel_sprite.h @@ -17,6 +17,16 @@ struct drm_i915_private; struct intel_crtc_state; struct intel_plane_state; +/* + * FIXME: We should instead only take spinlocks once for the entire update + * instead of once per mmio. + */ +#if IS_ENABLED(CONFIG_PROVE_LOCKING) +#define VBLANK_EVASION_TIME_US 250 +#else +#define VBLANK_EVASION_TIME_US 100 +#endif + int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, int usecs); struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, From 0a8cad54792ebce476f6780d7fd1832d9d4b9217 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Nov 2020 13:13:53 +0200 Subject: [PATCH 0139/5577] drm/i915/gvt: avoid useless use of inline In most cases, we are better off letting the compiler decide whether to inline static functions in .c files or not. In this case, the inline will be ignored anyway as mmio_pm_restore_handler() is passed as a function pointer. Fixes: 5f60b12edcd0 ("drm/i915/gvt: Save/restore HW status to support GVT suspend/resume") Cc: Zhenyu Wang Cc: Hang Yuan Cc: Colin Xu Cc: Zhi Wang Cc: intel-gvt-dev@lists.freedesktop.org Reviewed-by: Zhenyu Wang Signed-off-by: Jani Nikula Signed-off-by: Zhenyu Wang Link: http://patchwork.freedesktop.org/patch/msgid/20201130111353.25406-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/gvt/handlers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 62b49c72a7d0..aa02d5556822 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -3645,8 +3645,7 @@ void intel_gvt_restore_fence(struct intel_gvt *gvt) } } -static inline int mmio_pm_restore_handler(struct intel_gvt *gvt, - u32 offset, void *data) +static int mmio_pm_restore_handler(struct intel_gvt *gvt, u32 offset, void *data) { struct intel_vgpu *vgpu = data; struct drm_i915_private *dev_priv = gvt->gt->i915; From 1494a1dec5bfca35a0c1dd777750768a35b2da77 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 1 Dec 2020 07:09:45 +1000 Subject: [PATCH 0140/5577] drm/i915: refactor panel backlight control functions. (v2) This moves the functions into static const instead of having funcs and data in the same struct. It leaves the power callback alone, as it is used in a different manner. v2: leave power callback alone (Jani) Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201130210945.31850-1-airlied@gmail.com --- .../drm/i915/display/intel_display_types.h | 20 ++- .../drm/i915/display/intel_dp_aux_backlight.c | 14 +- .../i915/display/intel_dsi_dcs_backlight.c | 14 +- drivers/gpu/drm/i915/display/intel_panel.c | 153 +++++++++++------- 4 files changed, 127 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index d426dd31479e..b5ecfc501e39 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -225,6 +225,17 @@ struct intel_encoder { const struct drm_connector *audio_connector; }; +struct intel_panel_bl_funcs { + /* Connector and platform specific backlight functions */ + int (*setup)(struct intel_connector *connector, enum pipe pipe); + u32 (*get)(struct intel_connector *connector); + void (*set)(const struct drm_connector_state *conn_state, u32 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); + u32 (*hz_to_pwm)(struct intel_connector *connector, u32 hz); +}; + struct intel_panel { struct drm_display_mode *fixed_mode; struct drm_display_mode *downclock_mode; @@ -251,14 +262,7 @@ struct intel_panel { struct backlight_device *device; - /* Connector and platform specific backlight functions */ - int (*setup)(struct intel_connector *connector, enum pipe pipe); - u32 (*get)(struct intel_connector *connector); - void (*set)(const struct drm_connector_state *conn_state, u32 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); - u32 (*hz_to_pwm)(struct intel_connector *connector, u32 hz); + const struct intel_panel_bl_funcs *funcs; void (*power)(struct intel_connector *, bool enable); } backlight; }; diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 51d27fc98d48..4fd536801b14 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -350,6 +350,14 @@ intel_dp_aux_display_control_capable(struct intel_connector *connector) return false; } +static const struct intel_panel_bl_funcs intel_dp_bl_funcs = { + .setup = intel_dp_aux_setup_backlight, + .enable = intel_dp_aux_enable_backlight, + .disable = intel_dp_aux_disable_backlight, + .set = intel_dp_aux_set_backlight, + .get = intel_dp_aux_get_backlight, +}; + int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector) { struct intel_panel *panel = &intel_connector->panel; @@ -379,11 +387,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector) return -ENODEV; } - panel->backlight.setup = intel_dp_aux_setup_backlight; - panel->backlight.enable = intel_dp_aux_enable_backlight; - panel->backlight.disable = intel_dp_aux_disable_backlight; - panel->backlight.set = intel_dp_aux_set_backlight; - panel->backlight.get = intel_dp_aux_get_backlight; + panel->backlight.funcs = &intel_dp_bl_funcs; return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c index b53c50372918..5c508d51f526 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c @@ -156,6 +156,14 @@ static int dcs_setup_backlight(struct intel_connector *connector, return 0; } +static const struct intel_panel_bl_funcs dcs_bl_funcs = { + .setup = dcs_setup_backlight, + .enable = dcs_enable_backlight, + .disable = dcs_disable_backlight, + .set = dcs_set_backlight, + .get = dcs_get_backlight, +}; + int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector) { struct drm_device *dev = intel_connector->base.dev; @@ -169,11 +177,7 @@ int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector) if (drm_WARN_ON(dev, encoder->type != INTEL_OUTPUT_DSI)) return -EINVAL; - panel->backlight.setup = dcs_setup_backlight; - panel->backlight.enable = dcs_enable_backlight; - panel->backlight.disable = dcs_disable_backlight; - panel->backlight.set = dcs_set_backlight; - panel->backlight.get = dcs_get_backlight; + panel->backlight.funcs = &dcs_bl_funcs; return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 9f23bac0d792..36b7693453ae 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -684,7 +684,7 @@ intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", level); level = intel_panel_compute_brightness(connector, level); - panel->backlight.set(conn_state, level); + panel->backlight.funcs->set(conn_state, level); } /* set backlight brightness to level in range [0..max], assuming hw min is @@ -870,7 +870,7 @@ void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_st if (panel->backlight.device) panel->backlight.device->props.power = FB_BLANK_POWERDOWN; panel->backlight.enabled = false; - panel->backlight.disable(old_conn_state); + panel->backlight.funcs->disable(old_conn_state); mutex_unlock(&dev_priv->backlight_lock); } @@ -1198,7 +1198,7 @@ static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_s panel->backlight.device->props.max_brightness); } - panel->backlight.enable(crtc_state, conn_state); + panel->backlight.funcs->enable(crtc_state, conn_state); panel->backlight.enabled = true; if (panel->backlight.device) panel->backlight.device->props.power = FB_BLANK_UNBLANK; @@ -1234,7 +1234,7 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector) mutex_lock(&dev_priv->backlight_lock); if (panel->backlight.enabled) { - val = panel->backlight.get(connector); + val = panel->backlight.funcs->get(connector); val = intel_panel_compute_brightness(connector, val); } @@ -1567,13 +1567,13 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector) u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv); u32 pwm; - if (!panel->backlight.hz_to_pwm) { + if (!panel->backlight.funcs->hz_to_pwm) { drm_dbg_kms(&dev_priv->drm, "backlight frequency conversion not supported\n"); return 0; } - pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz); + pwm = panel->backlight.funcs->hz_to_pwm(connector, pwm_freq_hz); if (!pwm) { drm_dbg_kms(&dev_priv->drm, "backlight frequency conversion failed\n"); @@ -1981,12 +1981,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) } /* ensure intel_panel has been initialized first */ - if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.setup)) + if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs)) return -ENODEV; /* set level and max in panel struct */ mutex_lock(&dev_priv->backlight_lock); - ret = panel->backlight.setup(intel_connector, pipe); + ret = panel->backlight.funcs->setup(intel_connector, pipe); mutex_unlock(&dev_priv->backlight_lock); if (ret) { @@ -2016,6 +2016,86 @@ static void intel_panel_destroy_backlight(struct intel_panel *panel) panel->backlight.present = false; } +static const struct intel_panel_bl_funcs bxt_funcs = { + .setup = bxt_setup_backlight, + .enable = bxt_enable_backlight, + .disable = bxt_disable_backlight, + .set = bxt_set_backlight, + .get = bxt_get_backlight, + .hz_to_pwm = bxt_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs cnp_funcs = { + .setup = cnp_setup_backlight, + .enable = cnp_enable_backlight, + .disable = cnp_disable_backlight, + .set = bxt_set_backlight, + .get = bxt_get_backlight, + .hz_to_pwm = cnp_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs lpt_funcs = { + .setup = lpt_setup_backlight, + .enable = lpt_enable_backlight, + .disable = lpt_disable_backlight, + .set = lpt_set_backlight, + .get = lpt_get_backlight, + .hz_to_pwm = lpt_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs spt_funcs = { + .setup = lpt_setup_backlight, + .enable = lpt_enable_backlight, + .disable = lpt_disable_backlight, + .set = lpt_set_backlight, + .get = lpt_get_backlight, + .hz_to_pwm = spt_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs pch_funcs = { + .setup = pch_setup_backlight, + .enable = pch_enable_backlight, + .disable = pch_disable_backlight, + .set = pch_set_backlight, + .get = pch_get_backlight, + .hz_to_pwm = pch_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs pwm_funcs = { + .setup = pwm_setup_backlight, + .enable = pwm_enable_backlight, + .disable = pwm_disable_backlight, + .set = pwm_set_backlight, + .get = pwm_get_backlight, +}; + +static const struct intel_panel_bl_funcs vlv_funcs = { + .setup = vlv_setup_backlight, + .enable = vlv_enable_backlight, + .disable = vlv_disable_backlight, + .set = vlv_set_backlight, + .get = vlv_get_backlight, + .hz_to_pwm = vlv_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs i965_funcs = { + .setup = i965_setup_backlight, + .enable = i965_enable_backlight, + .disable = i965_disable_backlight, + .set = i9xx_set_backlight, + .get = i9xx_get_backlight, + .hz_to_pwm = i965_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs i9xx_funcs = { + .setup = i9xx_setup_backlight, + .enable = i9xx_enable_backlight, + .disable = i9xx_disable_backlight, + .set = i9xx_set_backlight, + .get = i9xx_get_backlight, + .hz_to_pwm = i9xx_hz_to_pwm, +}; + /* Set up chip specific backlight functions */ static void intel_panel_init_backlight_funcs(struct intel_panel *panel) @@ -2033,65 +2113,26 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel) return; if (IS_GEN9_LP(dev_priv)) { - panel->backlight.setup = bxt_setup_backlight; - panel->backlight.enable = bxt_enable_backlight; - panel->backlight.disable = bxt_disable_backlight; - panel->backlight.set = bxt_set_backlight; - panel->backlight.get = bxt_get_backlight; - panel->backlight.hz_to_pwm = bxt_hz_to_pwm; + panel->backlight.funcs = &bxt_funcs; } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) { - 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; + panel->backlight.funcs = &cnp_funcs; } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) { - panel->backlight.setup = lpt_setup_backlight; - panel->backlight.enable = lpt_enable_backlight; - panel->backlight.disable = lpt_disable_backlight; - panel->backlight.set = lpt_set_backlight; - panel->backlight.get = lpt_get_backlight; if (HAS_PCH_LPT(dev_priv)) - panel->backlight.hz_to_pwm = lpt_hz_to_pwm; + panel->backlight.funcs = &lpt_funcs; else - panel->backlight.hz_to_pwm = spt_hz_to_pwm; + panel->backlight.funcs = &spt_funcs; } else if (HAS_PCH_SPLIT(dev_priv)) { - panel->backlight.setup = pch_setup_backlight; - panel->backlight.enable = pch_enable_backlight; - panel->backlight.disable = pch_disable_backlight; - panel->backlight.set = pch_set_backlight; - panel->backlight.get = pch_get_backlight; - panel->backlight.hz_to_pwm = pch_hz_to_pwm; + panel->backlight.funcs = &pch_funcs; } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { - panel->backlight.setup = pwm_setup_backlight; - panel->backlight.enable = pwm_enable_backlight; - panel->backlight.disable = pwm_disable_backlight; - panel->backlight.set = pwm_set_backlight; - panel->backlight.get = pwm_get_backlight; + panel->backlight.funcs = &pwm_funcs; } else { - panel->backlight.setup = vlv_setup_backlight; - panel->backlight.enable = vlv_enable_backlight; - panel->backlight.disable = vlv_disable_backlight; - panel->backlight.set = vlv_set_backlight; - panel->backlight.get = vlv_get_backlight; - panel->backlight.hz_to_pwm = vlv_hz_to_pwm; + panel->backlight.funcs = &vlv_funcs; } } else if (IS_GEN(dev_priv, 4)) { - panel->backlight.setup = i965_setup_backlight; - panel->backlight.enable = i965_enable_backlight; - panel->backlight.disable = i965_disable_backlight; - panel->backlight.set = i9xx_set_backlight; - panel->backlight.get = i9xx_get_backlight; - panel->backlight.hz_to_pwm = i965_hz_to_pwm; + panel->backlight.funcs = &i965_funcs; } else { - panel->backlight.setup = i9xx_setup_backlight; - panel->backlight.enable = i9xx_enable_backlight; - panel->backlight.disable = i9xx_disable_backlight; - panel->backlight.set = i9xx_set_backlight; - panel->backlight.get = i9xx_get_backlight; - panel->backlight.hz_to_pwm = i9xx_hz_to_pwm; + panel->backlight.funcs = &i9xx_funcs; } } From 770729f77d232495a5ba52daf5df3ed5cf1e9edf Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Wed, 2 Dec 2020 17:26:50 +0800 Subject: [PATCH 0141/5577] drm/hisilicon: Code refactoring for hibmc_drm_drv Use the devm_drm_dev_alloc provided by the drm framework to alloc a structure hibmc_drm_private. Signed-off-by: Tian Tao Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1606901212-8214-2-git-send-email-tiantao6@hisilicon.com --- .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 2 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 46 +++++++++---------- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 4 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 8 ++-- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index ea962acfeae0..096eea985b6f 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -499,7 +499,7 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = { int hibmc_de_init(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = &priv->dev; struct drm_crtc *crtc = &priv->crtc; struct drm_plane *plane = &priv->primary_plane; int ret; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index d845657fd99c..13e8a287f54b 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -79,31 +79,32 @@ static const struct dev_pm_ops hibmc_pm_ops = { static int hibmc_kms_init(struct hibmc_drm_private *priv) { + struct drm_device *dev = &priv->dev; int ret; - drm_mode_config_init(priv->dev); + drm_mode_config_init(dev); priv->mode_config_initialized = true; - priv->dev->mode_config.min_width = 0; - priv->dev->mode_config.min_height = 0; - priv->dev->mode_config.max_width = 1920; - priv->dev->mode_config.max_height = 1200; + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + dev->mode_config.max_width = 1920; + dev->mode_config.max_height = 1200; - priv->dev->mode_config.fb_base = priv->fb_base; - priv->dev->mode_config.preferred_depth = 32; - priv->dev->mode_config.prefer_shadow = 1; + dev->mode_config.fb_base = priv->fb_base; + dev->mode_config.preferred_depth = 32; + dev->mode_config.prefer_shadow = 1; - priv->dev->mode_config.funcs = (void *)&hibmc_mode_funcs; + dev->mode_config.funcs = (void *)&hibmc_mode_funcs; ret = hibmc_de_init(priv); if (ret) { - drm_err(priv->dev, "failed to init de: %d\n", ret); + drm_err(dev, "failed to init de: %d\n", ret); return ret; } ret = hibmc_vdac_init(priv); if (ret) { - drm_err(priv->dev, "failed to init vdac: %d\n", ret); + drm_err(dev, "failed to init vdac: %d\n", ret); return ret; } @@ -113,7 +114,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) static void hibmc_kms_fini(struct hibmc_drm_private *priv) { if (priv->mode_config_initialized) { - drm_mode_config_cleanup(priv->dev); + drm_mode_config_cleanup(&priv->dev); priv->mode_config_initialized = false; } } @@ -202,7 +203,7 @@ static void hibmc_hw_config(struct hibmc_drm_private *priv) static int hibmc_hw_map(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = &priv->dev; struct pci_dev *pdev = dev->pdev; resource_size_t addr, size, ioaddr, iosize; @@ -258,17 +259,9 @@ static int hibmc_unload(struct drm_device *dev) static int hibmc_load(struct drm_device *dev) { - struct hibmc_drm_private *priv; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); int ret; - priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - drm_err(dev, "no memory to allocate for hibmc_drm_private\n"); - return -ENOMEM; - } - dev->dev_private = priv; - priv->dev = dev; - ret = hibmc_hw_init(priv); if (ret) goto err; @@ -310,6 +303,7 @@ err: static int hibmc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct hibmc_drm_private *priv; struct drm_device *dev; int ret; @@ -318,12 +312,14 @@ static int hibmc_pci_probe(struct pci_dev *pdev, if (ret) return ret; - dev = drm_dev_alloc(&hibmc_driver, &pdev->dev); - if (IS_ERR(dev)) { + priv = devm_drm_dev_alloc(&pdev->dev, &hibmc_driver, + struct hibmc_drm_private, dev); + if (IS_ERR(priv)) { DRM_ERROR("failed to allocate drm_device\n"); - return PTR_ERR(dev); + return PTR_ERR(priv); } + dev = &priv->dev; dev->pdev = pdev; pci_set_drvdata(pdev, dev); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index f310a83d9c48..7e0c756a3323 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -37,7 +37,7 @@ struct hibmc_drm_private { resource_size_t fb_size; /* drm */ - struct drm_device *dev; + struct drm_device dev; struct drm_plane primary_plane; struct drm_crtc crtc; struct drm_encoder encoder; @@ -52,7 +52,7 @@ static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *c static inline struct hibmc_drm_private *to_hibmc_drm_private(struct drm_device *dev) { - return dev->dev_private; + return container_of(dev, struct hibmc_drm_private, dev); } void hibmc_set_power_mode(struct hibmc_drm_private *priv, diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index 74e26c27d878..d35548dd7f65 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -96,7 +96,7 @@ static const struct drm_encoder_funcs hibmc_encoder_funcs = { int hibmc_vdac_init(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = &priv->dev; struct hibmc_connector *hibmc_connector = &priv->connector; struct drm_encoder *encoder = &priv->encoder; struct drm_connector *connector = &hibmc_connector->base; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c index 602ece11bb4a..e84fb81849a7 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c @@ -25,7 +25,7 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) { struct drm_vram_mm *vmm; int ret; - struct drm_device *dev = hibmc->dev; + struct drm_device *dev = &hibmc->dev; vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0), @@ -41,10 +41,12 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) void hibmc_mm_fini(struct hibmc_drm_private *hibmc) { - if (!hibmc->dev->vram_mm) + struct drm_device *dev = &hibmc->dev; + + if (!dev->vram_mm) return; - drm_vram_helper_release_mm(hibmc->dev); + drm_vram_helper_release_mm(dev); } int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, From d96bc380a50f1e89769d38dd9c5739be3cb014b2 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Wed, 2 Dec 2020 17:26:51 +0800 Subject: [PATCH 0142/5577] drm/irq: Add the new api to install irq Add new api devm_drm_irq_install() to register interrupts, no need to call drm_irq_uninstall() when the drm module is removed. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1606901212-8214-3-git-send-email-tiantao6@hisilicon.com --- drivers/gpu/drm/drm_irq.c | 32 ++++++++++++++++++++++++++++++++ include/drm/drm_irq.h | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 09d6e9e2e075..803af4bbd214 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -214,6 +214,38 @@ int drm_irq_uninstall(struct drm_device *dev) } EXPORT_SYMBOL(drm_irq_uninstall); +static void devm_drm_irq_uninstall(void *data) +{ + drm_irq_uninstall(data); +} + +/** + * devm_drm_irq_install - install IRQ handler + * @dev: DRM device + * @irq: IRQ number to install the handler for + * + * devm_drm_irq_install is a help function of drm_irq_install. + * + * if the driver uses devm_drm_irq_install, there is no need + * to call drm_irq_uninstall when the drm module get unloaded, + * as this will done automagically. + * + * Returns: + * Zero on success or a negative error code on failure. + */ +int devm_drm_irq_install(struct drm_device *dev, int irq) +{ + int ret; + + ret = drm_irq_install(dev, irq); + if (ret) + return ret; + + return devm_add_action_or_reset(dev->dev, + devm_drm_irq_uninstall, dev); +} +EXPORT_SYMBOL(devm_drm_irq_install); + #if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_irq_control(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index d77f6e65b1c6..631b22f9757d 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -28,5 +28,5 @@ struct drm_device; int drm_irq_install(struct drm_device *dev, int irq); int drm_irq_uninstall(struct drm_device *dev); - +int devm_drm_irq_install(struct drm_device *dev, int irq); #endif From e4401247070a37c2fce62b2773a4eb7757983938 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Wed, 2 Dec 2020 17:26:52 +0800 Subject: [PATCH 0143/5577] drm/hisilicon: Use the new api devm_drm_irq_install Use devm_drm_irq_install to register interrupts so that drm_irq_uninstall is not called when hibmc is removed. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1606901212-8214-4-git-send-email-tiantao6@hisilicon.com --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 13e8a287f54b..802060418868 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -247,9 +247,6 @@ static int hibmc_unload(struct drm_device *dev) drm_atomic_helper_shutdown(dev); - if (dev->irq_enabled) - drm_irq_uninstall(dev); - pci_disable_msi(dev->pdev); hibmc_kms_fini(priv); hibmc_mm_fini(priv); @@ -284,7 +281,7 @@ static int hibmc_load(struct drm_device *dev) if (ret) { drm_warn(dev, "enabling MSI failed: %d\n", ret); } else { - ret = drm_irq_install(dev, dev->pdev->irq); + ret = devm_drm_irq_install(dev, dev->pdev->irq); if (ret) drm_warn(dev, "install irq failed: %d\n", ret); } From 15ccc39b3aab667c6fa131206f01f31bfbccdf6a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Dec 2020 11:40:48 +0300 Subject: [PATCH 0144/5577] gma500: clean up error handling in init The main problem with this error handling was that it didn't clean up if i2c_add_numbered_adapter() failed. This code is pretty old, and doesn't match with today's checkpatch.pl standards so I took the opportunity to tidy it up a bit. I changed the NULL comparison, and removed the WARNING message if kzalloc() fails and updated the label names. Fixes: 1b082ccf5901 ("gma500: Add Oaktrail support") Signed-off-by: Dan Carpenter Signed-off-by: Patrik Jakobsson Link: https://patchwork.freedesktop.org/patch/msgid/X8ikkAqZfnDO2lu6@mwanda --- drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c index e28107061148..fc9a34ed58bd 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c @@ -279,11 +279,8 @@ int oaktrail_hdmi_i2c_init(struct pci_dev *dev) hdmi_dev = pci_get_drvdata(dev); i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL); - if (i2c_dev == NULL) { - DRM_ERROR("Can't allocate interface\n"); - ret = -ENOMEM; - goto exit; - } + if (!i2c_dev) + return -ENOMEM; i2c_dev->adap = &oaktrail_hdmi_i2c_adapter; i2c_dev->status = I2C_STAT_INIT; @@ -300,16 +297,23 @@ int oaktrail_hdmi_i2c_init(struct pci_dev *dev) oaktrail_hdmi_i2c_adapter.name, hdmi_dev); if (ret) { DRM_ERROR("Failed to request IRQ for I2C controller\n"); - goto err; + goto free_dev; } /* Adapter registration */ ret = i2c_add_numbered_adapter(&oaktrail_hdmi_i2c_adapter); - return ret; + if (ret) { + DRM_ERROR("Failed to add I2C adapter\n"); + goto free_irq; + } -err: + return 0; + +free_irq: + free_irq(dev->irq, hdmi_dev); +free_dev: kfree(i2c_dev); -exit: + return ret; } From 14f2d7604f7ce4cb3d303aea17292d119dfafa75 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Dec 2020 11:45:17 +0300 Subject: [PATCH 0145/5577] drm/i915/gem: Check the correct variable in selftest There is a copy and paste bug in this code. It's supposed to check "obj2" instead of checking "obj" a second time. Fixes: 80f0b679d6f0 ("drm/i915: Add an implementation for i915_gem_ww_ctx locking, v2.") Signed-off-by: Dan Carpenter Reviewed-by: Chris Wilson Reviewed-by: Andi Shyti Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/8ilneOcJAjwqU4t@mwand --- drivers/gpu/drm/i915/selftests/i915_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c index 23a6132c5f4e..412e21604a05 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem.c @@ -211,8 +211,8 @@ static int igt_gem_ww_ctx(void *arg) return PTR_ERR(obj); obj2 = i915_gem_object_create_internal(i915, PAGE_SIZE); - if (IS_ERR(obj)) { - err = PTR_ERR(obj); + if (IS_ERR(obj2)) { + err = PTR_ERR(obj2); goto put1; } From a9b5e83a5d111861be7977d93c9c6100f000279a Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 30 Nov 2020 23:21:52 +0200 Subject: [PATCH 0146/5577] drm/i915: Use CRTC index consistently during getting/putting CRTC power domains The for_each_oldnew_intel_crtc_in_state() iterator index does match crtc->pipe, but using the same thing as array index when getting and putting CRTC power domains makes things clearer. Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9187a20a8aca..d94d2aca8f33 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -16377,8 +16377,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { intel_post_plane_update(state, crtc); - if (put_domains[i]) - modeset_put_power_domains(dev_priv, put_domains[i]); + if (put_domains[crtc->pipe]) + modeset_put_power_domains(dev_priv, put_domains[crtc->pipe]); intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state); From 6979cb9a2cb41f14b3ec7190126e56d7183310bb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 1 Dec 2020 18:13:39 +0200 Subject: [PATCH 0147/5577] drm/i915: Factor out helpers to get/put a set of tracked power domains Factor out helper functions to get/put a set of power domains that are tracked using their wakeref handles. The same is needed by the next patch adding tracking for enabled CRTC power domains. v2: s/uint64_t/u64/ (Chris) Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201201161340.2879202-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 62 +++++-------------- .../drm/i915/display/intel_display_power.c | 57 +++++++++++++++++ .../drm/i915/display/intel_display_power.h | 29 +++++++++ 3 files changed, 100 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d94d2aca8f33..0ce81a73ecec 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -11227,16 +11227,13 @@ static void hsw_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, static bool hsw_get_transcoder_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, - u64 *power_domain_mask, - intel_wakeref_t *wakerefs) + struct intel_display_power_domain_set *power_domain_set) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - enum intel_display_power_domain power_domain; unsigned long panel_transcoder_mask = BIT(TRANSCODER_EDP); unsigned long enabled_panel_transcoders = 0; enum transcoder panel_transcoder; - intel_wakeref_t wf; u32 tmp; if (INTEL_GEN(dev_priv) >= 11) @@ -11307,16 +11304,10 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, drm_WARN_ON(dev, (enabled_panel_transcoders & BIT(TRANSCODER_EDP)) && enabled_panel_transcoders != BIT(TRANSCODER_EDP)); - power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); - drm_WARN_ON(dev, *power_domain_mask & BIT_ULL(power_domain)); - - wf = intel_display_power_get_if_enabled(dev_priv, power_domain); - if (!wf) + if (!intel_display_power_get_in_set_if_enabled(dev_priv, power_domain_set, + POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) return false; - wakerefs[power_domain] = wf; - *power_domain_mask |= BIT_ULL(power_domain); - tmp = intel_de_read(dev_priv, PIPECONF(pipe_config->cpu_transcoder)); return tmp & PIPECONF_ENABLE; @@ -11324,14 +11315,11 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, - u64 *power_domain_mask, - intel_wakeref_t *wakerefs) + struct intel_display_power_domain_set *power_domain_set) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - enum intel_display_power_domain power_domain; enum transcoder cpu_transcoder; - intel_wakeref_t wf; enum port port; u32 tmp; @@ -11341,16 +11329,10 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, else cpu_transcoder = TRANSCODER_DSI_C; - power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - drm_WARN_ON(dev, *power_domain_mask & BIT_ULL(power_domain)); - - wf = intel_display_power_get_if_enabled(dev_priv, power_domain); - if (!wf) + if (!intel_display_power_get_in_set_if_enabled(dev_priv, power_domain_set, + POWER_DOMAIN_TRANSCODER(cpu_transcoder))) continue; - wakerefs[power_domain] = wf; - *power_domain_mask |= BIT_ULL(power_domain); - /* * The PLL needs to be enabled with a valid divider * configuration, otherwise accessing DSI registers will hang @@ -11433,30 +11415,22 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - intel_wakeref_t wakerefs[POWER_DOMAIN_NUM], wf; - enum intel_display_power_domain power_domain; - u64 power_domain_mask; + struct intel_display_power_domain_set power_domain_set = { }; bool active; u32 tmp; pipe_config->master_transcoder = INVALID_TRANSCODER; - power_domain = POWER_DOMAIN_PIPE(crtc->pipe); - wf = intel_display_power_get_if_enabled(dev_priv, power_domain); - if (!wf) + if (!intel_display_power_get_in_set_if_enabled(dev_priv, &power_domain_set, + POWER_DOMAIN_PIPE(crtc->pipe))) return false; - wakerefs[power_domain] = wf; - power_domain_mask = BIT_ULL(power_domain); - pipe_config->shared_dpll = NULL; - active = hsw_get_transcoder_state(crtc, pipe_config, - &power_domain_mask, wakerefs); + active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_set); if (IS_GEN9_LP(dev_priv) && - bxt_get_dsi_transcoder_state(crtc, pipe_config, - &power_domain_mask, wakerefs)) { + bxt_get_dsi_transcoder_state(crtc, pipe_config, &power_domain_set)) { drm_WARN_ON(&dev_priv->drm, active); active = true; } @@ -11520,14 +11494,8 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, pipe_config->ips_linetime = REG_FIELD_GET(HSW_IPS_LINETIME_MASK, tmp); - power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); - drm_WARN_ON(&dev_priv->drm, power_domain_mask & BIT_ULL(power_domain)); - - wf = intel_display_power_get_if_enabled(dev_priv, power_domain); - if (wf) { - wakerefs[power_domain] = wf; - power_domain_mask |= BIT_ULL(power_domain); - + if (intel_display_power_get_in_set_if_enabled(dev_priv, &power_domain_set, + POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe))) { if (INTEL_GEN(dev_priv) >= 9) skl_get_pfit_config(pipe_config); else @@ -11561,9 +11529,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, } out: - for_each_power_domain(power_domain, power_domain_mask) - intel_display_power_put(dev_priv, - power_domain, wakerefs[power_domain]); + intel_display_power_put_all_in_set(dev_priv, &power_domain_set); return active; } diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index fe2d90bba536..b48dbb7bdaf4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -2412,6 +2412,63 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, } #endif +void +intel_display_power_get_in_set(struct drm_i915_private *i915, + struct intel_display_power_domain_set *power_domain_set, + enum intel_display_power_domain domain) +{ + intel_wakeref_t __maybe_unused wf; + + drm_WARN_ON(&i915->drm, power_domain_set->mask & BIT_ULL(domain)); + + wf = intel_display_power_get(i915, domain); +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) + power_domain_set->wakerefs[domain] = wf; +#endif + power_domain_set->mask |= BIT_ULL(domain); +} + +bool +intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, + struct intel_display_power_domain_set *power_domain_set, + enum intel_display_power_domain domain) +{ + intel_wakeref_t wf; + + drm_WARN_ON(&i915->drm, power_domain_set->mask & BIT_ULL(domain)); + + wf = intel_display_power_get_if_enabled(i915, domain); + if (!wf) + return false; + +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) + power_domain_set->wakerefs[domain] = wf; +#endif + power_domain_set->mask |= BIT_ULL(domain); + + return true; +} + +void +intel_display_power_put_mask_in_set(struct drm_i915_private *i915, + struct intel_display_power_domain_set *power_domain_set, + u64 mask) +{ + enum intel_display_power_domain domain; + + drm_WARN_ON(&i915->drm, mask & ~power_domain_set->mask); + + for_each_power_domain(domain, mask) { + intel_wakeref_t __maybe_unused wf = -1; + +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) + wf = fetch_and_zero(&power_domain_set->wakerefs[domain]); +#endif + intel_display_power_put(i915, domain, wf); + power_domain_set->mask &= ~BIT_ULL(domain); + } +} + #define I830_PIPES_POWER_DOMAINS ( \ BIT_ULL(POWER_DOMAIN_PIPE_A) | \ BIT_ULL(POWER_DOMAIN_PIPE_B) | \ diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 4aa0a09cf14f..583d3df57fb2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -224,6 +224,13 @@ struct i915_power_domains { struct i915_power_well *power_wells; }; +struct intel_display_power_domain_set { + u64 mask; +#ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM + intel_wakeref_t wakerefs[POWER_DOMAIN_NUM]; +#endif +}; + #define for_each_power_domain(domain, mask) \ for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \ for_each_if(BIT_ULL(domain) & (mask)) @@ -314,6 +321,28 @@ intel_display_power_put_async(struct drm_i915_private *i915, } #endif +void +intel_display_power_get_in_set(struct drm_i915_private *i915, + struct intel_display_power_domain_set *power_domain_set, + enum intel_display_power_domain domain); + +bool +intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, + struct intel_display_power_domain_set *power_domain_set, + enum intel_display_power_domain domain); + +void +intel_display_power_put_mask_in_set(struct drm_i915_private *i915, + struct intel_display_power_domain_set *power_domain_set, + u64 mask); + +static inline void +intel_display_power_put_all_in_set(struct drm_i915_private *i915, + struct intel_display_power_domain_set *power_domain_set) +{ + intel_display_power_put_mask_in_set(i915, power_domain_set, power_domain_set->mask); +} + enum dbuf_slice { DBUF_S1, DBUF_S2, From 802034849a220022f2874ce700cf7829d95865bc Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 30 Nov 2020 23:21:54 +0200 Subject: [PATCH 0148/5577] drm/i915: Track power references taken for enabled CRTCs Add wakeref tracking for display power domain references taken for enabled CRTCs. Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 38 ++++++++----------- .../drm/i915/display/intel_display_types.h | 2 +- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 0ce81a73ecec..6e5b93f6a25e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7576,25 +7576,25 @@ modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state) enum intel_display_power_domain domain; u64 domains, new_domains, old_domains; - old_domains = crtc->enabled_power_domains; - crtc->enabled_power_domains = new_domains = - get_crtc_power_domains(crtc_state); + domains = get_crtc_power_domains(crtc_state); - domains = new_domains & ~old_domains; + new_domains = domains & ~crtc->enabled_power_domains.mask; + old_domains = crtc->enabled_power_domains.mask & ~domains; - for_each_power_domain(domain, domains) - intel_display_power_get(dev_priv, domain); + for_each_power_domain(domain, new_domains) + intel_display_power_get_in_set(dev_priv, + &crtc->enabled_power_domains, + domain); - return old_domains & ~new_domains; + return old_domains; } -static void modeset_put_power_domains(struct drm_i915_private *dev_priv, - u64 domains) +static void modeset_put_crtc_power_domains(struct intel_crtc *crtc, + u64 domains) { - enum intel_display_power_domain domain; - - for_each_power_domain(domain, domains) - intel_display_power_put_unchecked(dev_priv, domain); + intel_display_power_put_mask_in_set(to_i915(crtc->base.dev), + &crtc->enabled_power_domains, + domains); } static void valleyview_crtc_enable(struct intel_atomic_state *state, @@ -7790,12 +7790,10 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, to_intel_dbuf_state(dev_priv->dbuf.obj.state); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); - enum intel_display_power_domain domain; struct intel_plane *plane; struct drm_atomic_state *state; struct intel_crtc_state *temp_crtc_state; enum pipe pipe = crtc->pipe; - u64 domains; int ret; if (!crtc_state->hw.active) @@ -7851,10 +7849,7 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, intel_update_watermarks(crtc); intel_disable_shared_dpll(crtc_state); - domains = crtc->enabled_power_domains; - for_each_power_domain(domain, domains) - intel_display_power_put_unchecked(dev_priv, domain); - crtc->enabled_power_domains = 0; + intel_display_power_put_all_in_set(dev_priv, &crtc->enabled_power_domains); dev_priv->active_pipes &= ~BIT(pipe); cdclk_state->min_cdclk[pipe] = 0; @@ -16343,8 +16338,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { intel_post_plane_update(state, crtc); - if (put_domains[crtc->pipe]) - modeset_put_power_domains(dev_priv, put_domains[crtc->pipe]); + modeset_put_crtc_power_domains(crtc, put_domains[crtc->pipe]); intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state); @@ -19562,7 +19556,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev, put_domains = modeset_get_crtc_power_domains(crtc_state); if (drm_WARN_ON(dev, put_domains)) - modeset_put_power_domains(dev_priv, put_domains); + modeset_put_crtc_power_domains(crtc, put_domains); } intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b5ecfc501e39..45eca96e3e37 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1166,7 +1166,7 @@ struct intel_crtc { /* I915_MODE_FLAG_* */ u8 mode_flags; - unsigned long long enabled_power_domains; + struct intel_display_power_domain_set enabled_power_domains; struct intel_overlay *overlay; struct intel_crtc_state *config; From a4550977a0fa4e4e927be07f5a21f31e62aedbe6 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 30 Nov 2020 23:21:55 +0200 Subject: [PATCH 0149/5577] drm/i915/ddi: Track power reference taken for encoder DDI IO use Add wakeref tracking for the DDI encoders' DDI_IO display power domain references. Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 38 ++++++++++++------- .../drm/i915/display/intel_display_types.h | 1 + 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 76e975b4765b..ba2da3de7e42 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2285,9 +2285,11 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder, dig_port = enc_to_dig_port(encoder); if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) - intel_display_power_get(dev_priv, - dig_port->ddi_io_power_domain); + dig_port->tc_mode != TC_PORT_TBT_ALT) { + drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_power_domain); + } /* * AUX power is only needed for (e)DP mode, and for HDMI mode on TC @@ -3577,9 +3579,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) - intel_display_power_get(dev_priv, - dig_port->ddi_io_power_domain); + dig_port->tc_mode != TC_PORT_TBT_ALT) { + drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_power_domain); + } /* 6. Program DP_MODE */ icl_program_mg_dp_mode(dig_port, crtc_state); @@ -3698,9 +3702,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_clk_select(encoder, crtc_state); if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) - intel_display_power_get(dev_priv, - dig_port->ddi_io_power_domain); + dig_port->tc_mode != TC_PORT_TBT_ALT) { + drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_power_domain); + } icl_program_mg_dp_mode(dig_port, crtc_state); @@ -3778,7 +3784,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); intel_ddi_clk_select(encoder, crtc_state); - intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); + drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, + dig_port->ddi_io_power_domain); icl_program_mg_dp_mode(dig_port, crtc_state); @@ -3936,8 +3944,9 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, if (!intel_phy_is_tc(dev_priv, phy) || dig_port->tc_mode != TC_PORT_TBT_ALT) - intel_display_power_put_unchecked(dev_priv, - dig_port->ddi_io_power_domain); + intel_display_power_put(dev_priv, + dig_port->ddi_io_power_domain, + fetch_and_zero(&dig_port->ddi_io_wakeref)); intel_ddi_clk_disable(encoder); } @@ -3958,8 +3967,9 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, intel_disable_ddi_buf(encoder, old_crtc_state); - intel_display_power_put_unchecked(dev_priv, - dig_port->ddi_io_power_domain); + intel_display_power_put(dev_priv, + dig_port->ddi_io_power_domain, + fetch_and_zero(&dig_port->ddi_io_wakeref)); intel_ddi_clk_disable(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 45eca96e3e37..a648ce61c9b3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1482,6 +1482,7 @@ struct intel_digital_port { /* Used for DP and ICL+ TypeC/DP and TypeC/HDMI ports. */ enum aux_ch aux_ch; enum intel_display_power_domain ddi_io_power_domain; + intel_wakeref_t ddi_io_wakeref; struct mutex tc_lock; /* protects the TypeC port mode */ intel_wakeref_t tc_lock_wakeref; int tc_link_refcount; From 162e68e133d5e65546390d39890b8d24f7c9d0c9 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 30 Nov 2020 23:21:56 +0200 Subject: [PATCH 0150/5577] drm/i915/ddi: Track power reference taken for encoder main lane AUX use Add wakeref tracking for the DDI encoders' main lane AUX display power domain references. Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 23 ++++++++++++------- .../drm/i915/display/intel_display_types.h | 1 + 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ba2da3de7e42..5193473c838c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2296,9 +2296,12 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder, * ports. */ if (intel_crtc_has_dp_encoder(crtc_state) || - intel_phy_is_tc(dev_priv, phy)) - intel_display_power_get(dev_priv, - intel_ddi_main_link_aux_domain(dig_port)); + intel_phy_is_tc(dev_priv, phy)) { + drm_WARN_ON(&dev_priv->drm, dig_port->aux_wakeref); + dig_port->aux_wakeref = + intel_display_power_get(dev_priv, + intel_ddi_main_link_aux_domain(dig_port)); + } } void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder, @@ -4042,8 +4045,9 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, icl_unmap_plls_to_ports(encoder); if (intel_crtc_has_dp_encoder(old_crtc_state) || is_tc_port) - intel_display_power_put_unchecked(dev_priv, - intel_ddi_main_link_aux_domain(dig_port)); + intel_display_power_put(dev_priv, + intel_ddi_main_link_aux_domain(dig_port), + fetch_and_zero(&dig_port->aux_wakeref)); if (is_tc_port) intel_tc_port_put_link(dig_port); @@ -4382,9 +4386,12 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, if (is_tc_port) intel_tc_port_get_link(dig_port, crtc_state->lane_count); - if (intel_crtc_has_dp_encoder(crtc_state) || is_tc_port) - intel_display_power_get(dev_priv, - intel_ddi_main_link_aux_domain(dig_port)); + if (intel_crtc_has_dp_encoder(crtc_state) || is_tc_port) { + drm_WARN_ON(&dev_priv->drm, dig_port->aux_wakeref); + dig_port->aux_wakeref = + intel_display_power_get(dev_priv, + intel_ddi_main_link_aux_domain(dig_port)); + } if (is_tc_port && dig_port->tc_mode != TC_PORT_TBT_ALT) /* diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index a648ce61c9b3..fa7d36f1ad97 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1483,6 +1483,7 @@ struct intel_digital_port { enum aux_ch aux_ch; enum intel_display_power_domain ddi_io_power_domain; intel_wakeref_t ddi_io_wakeref; + intel_wakeref_t aux_wakeref; struct mutex tc_lock; /* protects the TypeC port mode */ intel_wakeref_t tc_lock_wakeref; int tc_link_refcount; From 719065500b5d1bb20f1fd5c46da13caa196432dd Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 30 Nov 2020 23:21:57 +0200 Subject: [PATCH 0151/5577] drm/i915: Track power reference taken for eDP VDD Add wakeref tracking for the eDP encoders' AUX display power domain references taken while the panel's VDD is enabled. Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-7-imre.deak@intel.com --- .../gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index fa7d36f1ad97..1fa0246b3a82 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1384,6 +1384,7 @@ struct intel_dp { unsigned long last_power_on; unsigned long last_backlight_off; ktime_t panel_power_off_time; + intel_wakeref_t vdd_wakeref; /* * Pipe whose power sequencer is currently locked into diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 21a0ca6ae2a6..2d4d5e95af84 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3094,8 +3094,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) if (edp_have_panel_vdd(intel_dp)) return need_to_disable; - intel_display_power_get(dev_priv, - intel_aux_power_domain(dig_port)); + drm_WARN_ON(&dev_priv->drm, intel_dp->vdd_wakeref); + intel_dp->vdd_wakeref = intel_display_power_get(dev_priv, + intel_aux_power_domain(dig_port)); drm_dbg_kms(&dev_priv->drm, "Turning [ENCODER:%d:%s] VDD on\n", dig_port->base.base.base.id, @@ -3188,8 +3189,9 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) if ((pp & PANEL_POWER_ON) == 0) intel_dp->panel_power_off_time = ktime_get_boottime(); - intel_display_power_put_unchecked(dev_priv, - intel_aux_power_domain(dig_port)); + intel_display_power_put(dev_priv, + intel_aux_power_domain(dig_port), + fetch_and_zero(&intel_dp->vdd_wakeref)); } static void edp_panel_vdd_work(struct work_struct *__work) @@ -3341,7 +3343,9 @@ static void edp_panel_off(struct intel_dp *intel_dp) intel_dp->panel_power_off_time = ktime_get_boottime(); /* We got a reference when we enabled the VDD. */ - intel_display_power_put_unchecked(dev_priv, intel_aux_power_domain(dig_port)); + intel_display_power_put(dev_priv, + intel_aux_power_domain(dig_port), + fetch_and_zero(&intel_dp->vdd_wakeref)); } void intel_edp_panel_off(struct intel_dp *intel_dp) @@ -6894,7 +6898,9 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) */ drm_dbg_kms(&dev_priv->drm, "VDD left on by BIOS, adjusting state tracking\n"); - intel_display_power_get(dev_priv, intel_aux_power_domain(dig_port)); + drm_WARN_ON(&dev_priv->drm, intel_dp->vdd_wakeref); + intel_dp->vdd_wakeref = intel_display_power_get(dev_priv, + intel_aux_power_domain(dig_port)); edp_panel_vdd_schedule_off(intel_dp); } From a0b024ed10bd866f2a9602998e626250883d58cc Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 30 Nov 2020 23:21:58 +0200 Subject: [PATCH 0152/5577] drm/i915: Rename power_domains.wakeref to init_wakeref Rename power_domains.wakeref to power_domains.init_wakeref to make the use of this reference clearer. The next patch adds tracking for another power reference user of the power_domains functionality. While at it add a missing zero wakeref assert when setting the wakeref. Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-8-imre.deak@intel.com --- .../gpu/drm/i915/display/intel_display_power.c | 17 +++++++++-------- .../gpu/drm/i915/display/intel_display_power.h | 2 +- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index b48dbb7bdaf4..75e805d11dd9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -5658,7 +5658,8 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume) * resources powered until display HW readout is complete. We drop * this reference in intel_power_domains_enable(). */ - power_domains->wakeref = + drm_WARN_ON(&i915->drm, power_domains->init_wakeref); + power_domains->init_wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); /* Disable power support if the user asked so. */ @@ -5683,7 +5684,7 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume) void intel_power_domains_driver_remove(struct drm_i915_private *i915) { intel_wakeref_t wakeref __maybe_unused = - fetch_and_zero(&i915->power_domains.wakeref); + fetch_and_zero(&i915->power_domains.init_wakeref); /* Remove the refcount we took to keep power well support disabled. */ if (!i915->params.disable_power_well) @@ -5712,7 +5713,7 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915) void intel_power_domains_enable(struct drm_i915_private *i915) { intel_wakeref_t wakeref __maybe_unused = - fetch_and_zero(&i915->power_domains.wakeref); + fetch_and_zero(&i915->power_domains.init_wakeref); intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); intel_power_domains_verify_state(i915); @@ -5729,8 +5730,8 @@ void intel_power_domains_disable(struct drm_i915_private *i915) { struct i915_power_domains *power_domains = &i915->power_domains; - drm_WARN_ON(&i915->drm, power_domains->wakeref); - power_domains->wakeref = + drm_WARN_ON(&i915->drm, power_domains->init_wakeref); + power_domains->init_wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); intel_power_domains_verify_state(i915); @@ -5752,7 +5753,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915, { struct i915_power_domains *power_domains = &i915->power_domains; intel_wakeref_t wakeref __maybe_unused = - fetch_and_zero(&power_domains->wakeref); + fetch_and_zero(&power_domains->init_wakeref); intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); @@ -5811,8 +5812,8 @@ void intel_power_domains_resume(struct drm_i915_private *i915) intel_power_domains_init_hw(i915, true); power_domains->display_core_suspended = false; } else { - drm_WARN_ON(&i915->drm, power_domains->wakeref); - power_domains->wakeref = + drm_WARN_ON(&i915->drm, power_domains->init_wakeref); + power_domains->init_wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); } diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 583d3df57fb2..34de5487d8fc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -212,7 +212,7 @@ struct i915_power_domains { bool display_core_suspended; int power_well_count; - intel_wakeref_t wakeref; + intel_wakeref_t init_wakeref; struct mutex lock; int domain_use_count[POWER_DOMAIN_NUM]; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 8b8b94dcde51..cc9b21ee9e73 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1243,7 +1243,7 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) seq_puts(m, "Runtime power management not supported\n"); seq_printf(m, "Runtime power status: %s\n", - enableddisabled(!dev_priv->power_domains.wakeref)); + enableddisabled(!dev_priv->power_domains.init_wakeref)); seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->gt.awake)); seq_printf(m, "IRQs disabled: %s\n", From 93b916fda6938937fceef7520b37d90e88615a43 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 1 Dec 2020 18:13:40 +0200 Subject: [PATCH 0153/5577] drm/i915: Track power reference taken to disable power well functionality Add wakeref tracking for the display power domain reference taken to keep the display power well functionality disabled. v2: Add missing wakeref zeroing to intel_power_domains_driver_remove() Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201201161340.2879202-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display_power.c | 13 +++++++++---- drivers/gpu/drm/i915/display/intel_display_power.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 75e805d11dd9..1b3b2de9158f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -5663,8 +5663,11 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume) intel_display_power_get(i915, POWER_DOMAIN_INIT); /* Disable power support if the user asked so. */ - if (!i915->params.disable_power_well) - intel_display_power_get(i915, POWER_DOMAIN_INIT); + if (!i915->params.disable_power_well) { + drm_WARN_ON(&i915->drm, power_domains->disable_wakeref); + i915->power_domains.disable_wakeref = intel_display_power_get(i915, + POWER_DOMAIN_INIT); + } intel_power_domains_sync_hw(i915); power_domains->initializing = false; @@ -5688,7 +5691,8 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915) /* Remove the refcount we took to keep power well support disabled. */ if (!i915->params.disable_power_well) - intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT); + intel_display_power_put(i915, POWER_DOMAIN_INIT, + fetch_and_zero(&i915->power_domains.disable_wakeref)); intel_display_power_flush_work_sync(i915); @@ -5777,7 +5781,8 @@ void intel_power_domains_suspend(struct drm_i915_private *i915, * power wells if power domains must be deinitialized for suspend. */ if (!i915->params.disable_power_well) - intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT); + intel_display_power_put(i915, POWER_DOMAIN_INIT, + fetch_and_zero(&i915->power_domains.disable_wakeref)); intel_display_power_flush_work(i915); intel_power_domains_verify_state(i915); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 34de5487d8fc..2ef95ce17f60 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -213,6 +213,7 @@ struct i915_power_domains { int power_well_count; intel_wakeref_t init_wakeref; + intel_wakeref_t disable_wakeref; struct mutex lock; int domain_use_count[POWER_DOMAIN_NUM]; From e352934659657f741005f3128012d73605f0ff68 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 30 Nov 2020 23:22:00 +0200 Subject: [PATCH 0154/5577] drm/i915: Make intel_display_power_put_unchecked() an internal-only function All the display power domain references are wakeref tracked now, so we can mark intel_display_power_put_unchecked() as an internal function (for suppressing wakeref tracking in non-debug builds). Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201130212200.2811939-10-imre.deak@intel.com --- .../drm/i915/display/intel_display_power.c | 40 +++++++++---------- .../drm/i915/display/intel_display_power.h | 5 ++- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1b3b2de9158f..d52374f01316 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -2184,26 +2184,6 @@ static void __intel_display_power_put(struct drm_i915_private *dev_priv, mutex_unlock(&power_domains->lock); } -/** - * intel_display_power_put_unchecked - release an unchecked power domain reference - * @dev_priv: i915 device instance - * @domain: power domain to reference - * - * This function drops the power domain reference obtained by - * intel_display_power_get() and might power down the corresponding hardware - * block right away if this is the last reference. - * - * This function exists only for historical reasons and should be avoided in - * new code, as the correctness of its use cannot be checked. Always use - * intel_display_power_put() instead. - */ -void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) -{ - __intel_display_power_put(dev_priv, domain); - intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); -} - static void queue_async_put_domains_work(struct i915_power_domains *power_domains, intel_wakeref_t wakeref) @@ -2410,6 +2390,26 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, __intel_display_power_put(dev_priv, domain); intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); } +#else +/** + * intel_display_power_put_unchecked - release an unchecked power domain reference + * @dev_priv: i915 device instance + * @domain: power domain to reference + * + * This function drops the power domain reference obtained by + * intel_display_power_get() and might power down the corresponding hardware + * block right away if this is the last reference. + * + * This function is only for the power domain code's internal use to suppress wakeref + * tracking when the correspondig debug kconfig option is disabled, should not + * be used otherwise. + */ +void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) +{ + __intel_display_power_put(dev_priv, domain); + intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); +} #endif void diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 2ef95ce17f60..bc30c479be53 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -287,8 +287,6 @@ intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, intel_wakeref_t intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); -void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); void __intel_display_power_put_async(struct drm_i915_private *i915, enum intel_display_power_domain domain, intel_wakeref_t wakeref); @@ -305,6 +303,9 @@ intel_display_power_put_async(struct drm_i915_private *i915, __intel_display_power_put_async(i915, domain, wakeref); } #else +void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); + static inline void intel_display_power_put(struct drm_i915_private *i915, enum intel_display_power_domain domain, From 0a260e731d6c4c17547ac275a2cde888a9eb4a3d Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Thu, 3 Dec 2020 22:42:48 +0800 Subject: [PATCH 0155/5577] drm/fb-helper: Add missed unlocks in setcmap_legacy() setcmap_legacy() does not call drm_modeset_unlock_all() in some exits, add the missed unlocks with goto to fix it. Fixes: 964c60063bff ("drm/fb-helper: separate the fb_setcmap helper into atomic and legacy paths") Signed-off-by: Chuhong Yuan Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201203144248.418281-1-hslester96@gmail.com --- drivers/gpu/drm/drm_fb_helper.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 4b8119510687..e82db0f4e771 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -946,11 +946,15 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info) drm_modeset_lock_all(fb_helper->dev); drm_client_for_each_modeset(modeset, &fb_helper->client) { crtc = modeset->crtc; - if (!crtc->funcs->gamma_set || !crtc->gamma_size) - return -EINVAL; + if (!crtc->funcs->gamma_set || !crtc->gamma_size) { + ret = -EINVAL; + goto out; + } - if (cmap->start + cmap->len > crtc->gamma_size) - return -EINVAL; + if (cmap->start + cmap->len > crtc->gamma_size) { + ret = -EINVAL; + goto out; + } r = crtc->gamma_store; g = r + crtc->gamma_size; @@ -963,8 +967,9 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info) ret = crtc->funcs->gamma_set(crtc, r, g, b, crtc->gamma_size, NULL); if (ret) - return ret; + goto out; } +out: drm_modeset_unlock_all(fb_helper->dev); return ret; From cf977e18610e66e48c31619e7e0cfa871be9eada Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Dec 2020 11:21:40 +0000 Subject: [PATCH 0156/5577] drm/i915/gem: Spring clean debugfs Throw away all the debugfs entries that are not being actively used for debugging/developing IGT. Note that a couple of these are already and will remain available under the gt/ Files removed: i915_gem_fence_regs i915_gem_interrupt i915_ring_freq_table i915_context_status i915_llc i915_shrinker_info Signed-off-by: Chris Wilson Cc: Andi Shyti Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20201202112140.16759-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 435 ---------------------------- 1 file changed, 435 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index cc9b21ee9e73..e81aca53f5cb 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -378,308 +378,6 @@ static int i915_gem_object_info(struct seq_file *m, void *data) return 0; } -static void gen8_display_interrupt_info(struct seq_file *m) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - enum pipe pipe; - - for_each_pipe(dev_priv, pipe) { - enum intel_display_power_domain power_domain; - intel_wakeref_t wakeref; - - power_domain = POWER_DOMAIN_PIPE(pipe); - wakeref = intel_display_power_get_if_enabled(dev_priv, - power_domain); - if (!wakeref) { - seq_printf(m, "Pipe %c power disabled\n", - pipe_name(pipe)); - continue; - } - seq_printf(m, "Pipe %c IMR:\t%08x\n", - pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IMR(pipe))); - seq_printf(m, "Pipe %c IIR:\t%08x\n", - pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IIR(pipe))); - seq_printf(m, "Pipe %c IER:\t%08x\n", - pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, GEN8_DE_PIPE_IER(pipe))); - - intel_display_power_put(dev_priv, power_domain, wakeref); - } - - seq_printf(m, "Display Engine port interrupt mask:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IMR)); - seq_printf(m, "Display Engine port interrupt identity:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IIR)); - seq_printf(m, "Display Engine port interrupt enable:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_DE_PORT_IER)); - - seq_printf(m, "Display Engine misc interrupt mask:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IMR)); - seq_printf(m, "Display Engine misc interrupt identity:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IIR)); - seq_printf(m, "Display Engine misc interrupt enable:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IER)); - - seq_printf(m, "PCU interrupt mask:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IMR)); - seq_printf(m, "PCU interrupt identity:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IIR)); - seq_printf(m, "PCU interrupt enable:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IER)); -} - -static int i915_interrupt_info(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct intel_engine_cs *engine; - intel_wakeref_t wakeref; - int i, pipe; - - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - - if (IS_CHERRYVIEW(dev_priv)) { - intel_wakeref_t pref; - - seq_printf(m, "Master Interrupt Control:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_MASTER_IRQ)); - - seq_printf(m, "Display IER:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IER)); - seq_printf(m, "Display IIR:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IIR)); - seq_printf(m, "Display IIR_RW:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IIR_RW)); - seq_printf(m, "Display IMR:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IMR)); - for_each_pipe(dev_priv, pipe) { - enum intel_display_power_domain power_domain; - - power_domain = POWER_DOMAIN_PIPE(pipe); - pref = intel_display_power_get_if_enabled(dev_priv, - power_domain); - if (!pref) { - seq_printf(m, "Pipe %c power disabled\n", - pipe_name(pipe)); - continue; - } - - seq_printf(m, "Pipe %c stat:\t%08x\n", - pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, PIPESTAT(pipe))); - - intel_display_power_put(dev_priv, power_domain, pref); - } - - pref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); - seq_printf(m, "Port hotplug:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_EN)); - seq_printf(m, "DPFLIPSTAT:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_DPFLIPSTAT)); - seq_printf(m, "DPINVGTT:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, DPINVGTT)); - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, pref); - - for (i = 0; i < 4; i++) { - seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", - i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IMR(i))); - seq_printf(m, "GT Interrupt IIR %d:\t%08x\n", - i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IIR(i))); - seq_printf(m, "GT Interrupt IER %d:\t%08x\n", - i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IER(i))); - } - - seq_printf(m, "PCU interrupt mask:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IMR)); - seq_printf(m, "PCU interrupt identity:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IIR)); - seq_printf(m, "PCU interrupt enable:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_PCU_IER)); - } else if (INTEL_GEN(dev_priv) >= 11) { - if (HAS_MASTER_UNIT_IRQ(dev_priv)) - seq_printf(m, "Master Unit Interrupt Control: %08x\n", - intel_uncore_read(&dev_priv->uncore, DG1_MSTR_UNIT_INTR)); - - seq_printf(m, "Master Interrupt Control: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_GFX_MSTR_IRQ)); - - seq_printf(m, "Render/Copy Intr Enable: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_RENDER_COPY_INTR_ENABLE)); - seq_printf(m, "VCS/VECS Intr Enable: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_VCS_VECS_INTR_ENABLE)); - seq_printf(m, "GUC/SG Intr Enable:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_GUC_SG_INTR_ENABLE)); - seq_printf(m, "GPM/WGBOXPERF Intr Enable: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE)); - seq_printf(m, "Crypto Intr Enable:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE)); - seq_printf(m, "GUnit/CSME Intr Enable:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_GUNIT_CSME_INTR_ENABLE)); - - seq_printf(m, "Display Interrupt Control:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_DISPLAY_INT_CTL)); - - gen8_display_interrupt_info(m); - } else if (INTEL_GEN(dev_priv) >= 8) { - seq_printf(m, "Master Interrupt Control:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN8_MASTER_IRQ)); - - for (i = 0; i < 4; i++) { - seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", - i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IMR(i))); - seq_printf(m, "GT Interrupt IIR %d:\t%08x\n", - i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IIR(i))); - seq_printf(m, "GT Interrupt IER %d:\t%08x\n", - i, intel_uncore_read(&dev_priv->uncore, GEN8_GT_IER(i))); - } - - gen8_display_interrupt_info(m); - } else if (IS_VALLEYVIEW(dev_priv)) { - intel_wakeref_t pref; - - seq_printf(m, "Display IER:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IER)); - seq_printf(m, "Display IIR:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IIR)); - seq_printf(m, "Display IIR_RW:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IIR_RW)); - seq_printf(m, "Display IMR:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_IMR)); - for_each_pipe(dev_priv, pipe) { - enum intel_display_power_domain power_domain; - - power_domain = POWER_DOMAIN_PIPE(pipe); - pref = intel_display_power_get_if_enabled(dev_priv, - power_domain); - if (!pref) { - seq_printf(m, "Pipe %c power disabled\n", - pipe_name(pipe)); - continue; - } - - seq_printf(m, "Pipe %c stat:\t%08x\n", - pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, PIPESTAT(pipe))); - intel_display_power_put(dev_priv, power_domain, pref); - } - - seq_printf(m, "Master IER:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_MASTER_IER)); - - seq_printf(m, "Render IER:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GTIER)); - seq_printf(m, "Render IIR:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GTIIR)); - seq_printf(m, "Render IMR:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GTIMR)); - - seq_printf(m, "PM IER:\t\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN6_PMIER)); - seq_printf(m, "PM IIR:\t\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN6_PMIIR)); - seq_printf(m, "PM IMR:\t\t%08x\n", - intel_uncore_read(&dev_priv->uncore, GEN6_PMIMR)); - - pref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); - seq_printf(m, "Port hotplug:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_EN)); - seq_printf(m, "DPFLIPSTAT:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, VLV_DPFLIPSTAT)); - seq_printf(m, "DPINVGTT:\t%08x\n", - intel_uncore_read(&dev_priv->uncore, DPINVGTT)); - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, pref); - - } else if (!HAS_PCH_SPLIT(dev_priv)) { - seq_printf(m, "Interrupt enable: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN2_IER)); - seq_printf(m, "Interrupt identity: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN2_IIR)); - seq_printf(m, "Interrupt mask: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN2_IMR)); - for_each_pipe(dev_priv, pipe) - seq_printf(m, "Pipe %c stat: %08x\n", - pipe_name(pipe), - intel_uncore_read(&dev_priv->uncore, PIPESTAT(pipe))); - } else { - seq_printf(m, "North Display Interrupt enable: %08x\n", - intel_uncore_read(&dev_priv->uncore, DEIER)); - seq_printf(m, "North Display Interrupt identity: %08x\n", - intel_uncore_read(&dev_priv->uncore, DEIIR)); - seq_printf(m, "North Display Interrupt mask: %08x\n", - intel_uncore_read(&dev_priv->uncore, DEIMR)); - seq_printf(m, "South Display Interrupt enable: %08x\n", - intel_uncore_read(&dev_priv->uncore, SDEIER)); - seq_printf(m, "South Display Interrupt identity: %08x\n", - intel_uncore_read(&dev_priv->uncore, SDEIIR)); - seq_printf(m, "South Display Interrupt mask: %08x\n", - intel_uncore_read(&dev_priv->uncore, SDEIMR)); - seq_printf(m, "Graphics Interrupt enable: %08x\n", - intel_uncore_read(&dev_priv->uncore, GTIER)); - seq_printf(m, "Graphics Interrupt identity: %08x\n", - intel_uncore_read(&dev_priv->uncore, GTIIR)); - seq_printf(m, "Graphics Interrupt mask: %08x\n", - intel_uncore_read(&dev_priv->uncore, GTIMR)); - } - - if (INTEL_GEN(dev_priv) >= 11) { - seq_printf(m, "RCS Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_RCS0_RSVD_INTR_MASK)); - seq_printf(m, "BCS Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_BCS_RSVD_INTR_MASK)); - seq_printf(m, "VCS0/VCS1 Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_VCS0_VCS1_INTR_MASK)); - seq_printf(m, "VCS2/VCS3 Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_VCS2_VCS3_INTR_MASK)); - seq_printf(m, "VECS0/VECS1 Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_VECS0_VECS1_INTR_MASK)); - seq_printf(m, "GUC/SG Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_GUC_SG_INTR_MASK)); - seq_printf(m, "GPM/WGBOXPERF Intr Mask: %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_GPM_WGBOXPERF_INTR_MASK)); - seq_printf(m, "Crypto Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_CRYPTO_RSVD_INTR_MASK)); - seq_printf(m, "Gunit/CSME Intr Mask:\t %08x\n", - intel_uncore_read(&dev_priv->uncore, GEN11_GUNIT_CSME_INTR_MASK)); - - } else if (INTEL_GEN(dev_priv) >= 6) { - for_each_uabi_engine(engine, dev_priv) { - seq_printf(m, - "Graphics Interrupt mask (%s): %08x\n", - engine->name, ENGINE_READ(engine, RING_IMR)); - } - } - - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); - - return 0; -} - -static int i915_gem_fence_regs_info(struct seq_file *m, void *data) -{ - struct drm_i915_private *i915 = node_to_i915(m->private); - unsigned int i; - - seq_printf(m, "Total fences = %d\n", i915->ggtt.num_fences); - - rcu_read_lock(); - for (i = 0; i < i915->ggtt.num_fences; i++) { - struct i915_fence_reg *reg = &i915->ggtt.fence_regs[i]; - struct i915_vma *vma = reg->vma; - - seq_printf(m, "Fence %d, pin count = %d, object = ", - i, atomic_read(®->pin_count)); - if (!vma) - seq_puts(m, "unused"); - else - i915_debugfs_describe_obj(m, vma->obj); - seq_putc(m, '\n'); - } - rcu_read_unlock(); - - return 0; -} - #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) static ssize_t gpu_state_read(struct file *file, char __user *ubuf, size_t count, loff_t *pos) @@ -1011,111 +709,6 @@ static int i915_frequency_info(struct seq_file *m, void *unused) return 0; } -static int i915_ring_freq_table(struct seq_file *m, void *unused) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct intel_rps *rps = &dev_priv->gt.rps; - unsigned int max_gpu_freq, min_gpu_freq; - intel_wakeref_t wakeref; - int gpu_freq, ia_freq; - - if (!HAS_LLC(dev_priv)) - return -ENODEV; - - min_gpu_freq = rps->min_freq; - max_gpu_freq = rps->max_freq; - if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) { - /* Convert GT frequency to 50 HZ units */ - min_gpu_freq /= GEN9_FREQ_SCALER; - max_gpu_freq /= GEN9_FREQ_SCALER; - } - - seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); - - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - for (gpu_freq = min_gpu_freq; gpu_freq <= max_gpu_freq; gpu_freq++) { - ia_freq = gpu_freq; - sandybridge_pcode_read(dev_priv, - GEN6_PCODE_READ_MIN_FREQ_TABLE, - &ia_freq, NULL); - seq_printf(m, "%d\t\t%d\t\t\t\t%d\n", - intel_gpu_freq(rps, - (gpu_freq * - (IS_GEN9_BC(dev_priv) || - INTEL_GEN(dev_priv) >= 10 ? - GEN9_FREQ_SCALER : 1))), - ((ia_freq >> 0) & 0xff) * 100, - ((ia_freq >> 8) & 0xff) * 100); - } - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); - - return 0; -} - -static void describe_ctx_ring(struct seq_file *m, struct intel_ring *ring) -{ - seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u, emit: %u)", - ring->space, ring->head, ring->tail, ring->emit); -} - -static int i915_context_status(struct seq_file *m, void *unused) -{ - struct drm_i915_private *i915 = node_to_i915(m->private); - struct i915_gem_context *ctx, *cn; - - spin_lock(&i915->gem.contexts.lock); - list_for_each_entry_safe(ctx, cn, &i915->gem.contexts.list, link) { - struct i915_gem_engines_iter it; - struct intel_context *ce; - - if (!kref_get_unless_zero(&ctx->ref)) - continue; - - spin_unlock(&i915->gem.contexts.lock); - - seq_puts(m, "HW context "); - if (ctx->pid) { - struct task_struct *task; - - task = get_pid_task(ctx->pid, PIDTYPE_PID); - if (task) { - seq_printf(m, "(%s [%d]) ", - task->comm, task->pid); - put_task_struct(task); - } - } else if (IS_ERR(ctx->file_priv)) { - seq_puts(m, "(deleted) "); - } else { - seq_puts(m, "(kernel) "); - } - - seq_putc(m, ctx->remap_slice ? 'R' : 'r'); - seq_putc(m, '\n'); - - for_each_gem_engine(ce, - i915_gem_context_lock_engines(ctx), it) { - if (intel_context_pin_if_active(ce)) { - seq_printf(m, "%s: ", ce->engine->name); - if (ce->state) - i915_debugfs_describe_obj(m, ce->state->obj); - describe_ctx_ring(m, ce->ring); - seq_putc(m, '\n'); - intel_context_unpin(ce); - } - } - i915_gem_context_unlock_engines(ctx); - - seq_putc(m, '\n'); - - spin_lock(&i915->gem.contexts.lock); - list_safe_reset_next(ctx, cn, link); - i915_gem_context_put(ctx); - } - spin_unlock(&i915->gem.contexts.lock); - - return 0; -} - static const char *swizzle_string(unsigned swizzle) { switch (swizzle) { @@ -1222,18 +815,6 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) return 0; } -static int i915_llc(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - const bool edram = INTEL_GEN(dev_priv) > 8; - - seq_printf(m, "LLC: %s\n", yesno(HAS_LLC(dev_priv))); - seq_printf(m, "%s: %uMB\n", edram ? "eDRAM" : "eLLC", - dev_priv->edram_size_mb); - - return 0; -} - static int i915_runtime_pm_status(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -1291,16 +872,6 @@ static int i915_engine_info(struct seq_file *m, void *unused) return 0; } -static int i915_shrinker_info(struct seq_file *m, void *unused) -{ - struct drm_i915_private *i915 = node_to_i915(m->private); - - seq_printf(m, "seeks = %d\n", i915->mm.shrinker.seeks); - seq_printf(m, "batch = %lu\n", i915->mm.shrinker.batch); - - return 0; -} - static int i915_wa_registers(struct seq_file *m, void *unused) { struct drm_i915_private *i915 = node_to_i915(m->private); @@ -1535,16 +1106,10 @@ static const struct file_operations i915_forcewake_fops = { static const struct drm_info_list i915_debugfs_list[] = { {"i915_capabilities", i915_capabilities, 0}, {"i915_gem_objects", i915_gem_object_info, 0}, - {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, - {"i915_gem_interrupt", i915_interrupt_info, 0}, {"i915_frequency_info", i915_frequency_info, 0}, - {"i915_ring_freq_table", i915_ring_freq_table, 0}, - {"i915_context_status", i915_context_status, 0}, {"i915_swizzle_info", i915_swizzle_info, 0}, - {"i915_llc", i915_llc, 0}, {"i915_runtime_pm_status", i915_runtime_pm_status, 0}, {"i915_engine_info", i915_engine_info, 0}, - {"i915_shrinker_info", i915_shrinker_info, 0}, {"i915_wa_registers", i915_wa_registers, 0}, {"i915_sseu_status", i915_sseu_status, 0}, {"i915_rps_boost_info", i915_rps_boost_info, 0}, From 97ffcd0d1eeca8b123453a900e7768d07408ebf9 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Wed, 2 Dec 2020 10:27:27 -0800 Subject: [PATCH 0157/5577] drm/i915: Add VRR_CTL_LINE_COUNT field to VRR_CTL register def VRR_CTL register only had a GENMASK but no field prep define for TRANS_VRR_CTL_LINE_COUNT field so add that Cc: Aditya Swarup Signed-off-by: Manasi Navare Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201202182727.26158-1-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a8c4d16b7c30..593b6c97dcbd 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4352,6 +4352,7 @@ enum { #define VRR_CTL_IGN_MAX_SHIFT REG_BIT(30) #define VRR_CTL_FLIP_LINE_EN REG_BIT(29) #define VRR_CTL_LINE_COUNT_MASK REG_GENMASK(10, 3) +#define VRR_CTL_LINE_COUNT(x) REG_FIELD_PREP(VRR_CTL_LINE_COUNT_MASK, (x)) #define VRR_CTL_SW_FULLLINE_COUNT REG_BIT(0) #define _TRANS_VRR_VMAX_A 0x60424 From 9f941375aa1d2e4aff596f8bf37abc00549989dd Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 16 Nov 2020 18:53:01 +0100 Subject: [PATCH 0158/5577] drm/ingenic: depend on COMMON_CLK to fix compile tests The Ingenic DRM uses Common Clock Framework thus it cannot be built on platforms without it (e.g. compile test on MIPS with RALINK and SOC_RT305X): /usr/bin/mips-linux-gnu-ld: drivers/gpu/drm/ingenic/ingenic-drm-drv.o: in function `ingenic_drm_bind.isra.0': ingenic-drm-drv.c:(.text+0x1600): undefined reference to `clk_get_parent' /usr/bin/mips-linux-gnu-ld: ingenic-drm-drv.c:(.text+0x16b0): undefined reference to `clk_get_parent' Reported-by: kernel test robot Signed-off-by: Krzysztof Kozlowski Signed-off-by: Paul Cercueil Link: https://patchwork.freedesktop.org/patch/msgid/20201116175301.402787-2-krzk@kernel.org --- drivers/gpu/drm/ingenic/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/ingenic/Kconfig b/drivers/gpu/drm/ingenic/Kconfig index 477d5387e43e..3b57f8be007c 100644 --- a/drivers/gpu/drm/ingenic/Kconfig +++ b/drivers/gpu/drm/ingenic/Kconfig @@ -4,6 +4,7 @@ config DRM_INGENIC depends on DRM depends on CMA depends on OF + depends on COMMON_CLK select DRM_BRIDGE select DRM_PANEL_BRIDGE select DRM_KMS_HELPER From 717ea76addb3f9b0a1754fd8e9b29c0295d753f7 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Thu, 3 Dec 2020 11:09:13 +0800 Subject: [PATCH 0159/5577] drm/hisilicon: Use managed VRAM-helper initialization updated to use drmm_vram_helper_init() Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1606964953-24309-1-git-send-email-tiantao6@hisilicon.com --- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 1 - .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 - drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 19 +++---------------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 802060418868..5aea2e901b82 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -249,7 +249,6 @@ static int hibmc_unload(struct drm_device *dev) pci_disable_msi(dev->pdev); hibmc_kms_fini(priv); - hibmc_mm_fini(priv); dev->dev_private = NULL; return 0; } diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 7e0c756a3323..2786de562267 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -64,7 +64,6 @@ int hibmc_de_init(struct hibmc_drm_private *priv); int hibmc_vdac_init(struct hibmc_drm_private *priv); int hibmc_mm_init(struct hibmc_drm_private *hibmc); -void hibmc_mm_fini(struct hibmc_drm_private *hibmc); int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c index e84fb81849a7..892d566b17cd 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c @@ -23,15 +23,12 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) { - struct drm_vram_mm *vmm; int ret; struct drm_device *dev = &hibmc->dev; - vmm = drm_vram_helper_alloc_mm(dev, - pci_resource_start(dev->pdev, 0), - hibmc->fb_size); - if (IS_ERR(vmm)) { - ret = PTR_ERR(vmm); + ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0), + hibmc->fb_size); + if (ret) { drm_err(dev, "Error initializing VRAM MM; %d\n", ret); return ret; } @@ -39,16 +36,6 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) return 0; } -void hibmc_mm_fini(struct hibmc_drm_private *hibmc) -{ - struct drm_device *dev = &hibmc->dev; - - if (!dev->vram_mm) - return; - - drm_vram_helper_release_mm(dev); -} - int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) { From 552a77bab3ff86dfe3f6c5d2db75880bc625373d Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 4 Dec 2020 09:23:18 +0800 Subject: [PATCH 0160/5577] drm/hisilicon: Delete the entire file hibmc_ttm.c Delete the entire file hibmc_ttm.c. drmm_vram_helper_init() can be called directly from hibmc_load(). hibmc_dumb_create() and hibmc_mode_funcs can go to hibmc_drm_drv.c v2: change Deletted to Delete Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1607044999-47666-13-git-send-email-tiantao6@hisilicon.com --- drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 21 +++++++- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 4 -- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 50 ------------------- 4 files changed, 20 insertions(+), 57 deletions(-) delete mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile index 684ef794eb7c..d25c75e60d3d 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o hibmc_drm_i2c.o +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_i2c.o obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 5aea2e901b82..3687753dba9a 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,12 @@ static irqreturn_t hibmc_drm_interrupt(int irq, void *arg) return IRQ_HANDLED; } +static int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, + struct drm_mode_create_dumb *args) +{ + return drm_gem_vram_fill_create_dumb(file, dev, 0, 128, args); +} + static const struct drm_driver hibmc_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &hibmc_fops, @@ -77,6 +84,13 @@ static const struct dev_pm_ops hibmc_pm_ops = { hibmc_pm_resume) }; +static const struct drm_mode_config_funcs hibmc_mode_funcs = { + .mode_valid = drm_vram_helper_mode_valid, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, + .fb_create = drm_gem_fb_create, +}; + static int hibmc_kms_init(struct hibmc_drm_private *priv) { struct drm_device *dev = &priv->dev; @@ -262,9 +276,12 @@ static int hibmc_load(struct drm_device *dev) if (ret) goto err; - ret = hibmc_mm_init(priv); - if (ret) + ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0), + priv->fb_size); + if (ret) { + drm_err(dev, "Error initializing VRAM MM; %d\n", ret); goto err; + } ret = hibmc_kms_init(priv); if (ret) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 2786de562267..a49c10e3ec34 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -64,10 +64,6 @@ int hibmc_de_init(struct hibmc_drm_private *priv); int hibmc_vdac_init(struct hibmc_drm_private *priv); int hibmc_mm_init(struct hibmc_drm_private *hibmc); -int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args); int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector); -extern const struct drm_mode_config_funcs hibmc_mode_funcs; - #endif diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c deleted file mode 100644 index 892d566b17cd..000000000000 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* Hisilicon Hibmc SoC drm driver - * - * Based on the bochs drm driver. - * - * Copyright (c) 2016 Huawei Limited. - * - * Author: - * Rongrong Zou - * Rongrong Zou - * Jianhua Li - */ - -#include - -#include -#include -#include -#include -#include - -#include "hibmc_drm_drv.h" - -int hibmc_mm_init(struct hibmc_drm_private *hibmc) -{ - int ret; - struct drm_device *dev = &hibmc->dev; - - ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0), - hibmc->fb_size); - if (ret) { - drm_err(dev, "Error initializing VRAM MM; %d\n", ret); - return ret; - } - - return 0; -} - -int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - return drm_gem_vram_fill_create_dumb(file, dev, 0, 128, args); -} - -const struct drm_mode_config_funcs hibmc_mode_funcs = { - .mode_valid = drm_vram_helper_mode_valid, - .atomic_check = drm_atomic_helper_check, - .atomic_commit = drm_atomic_helper_commit, - .fb_create = drm_gem_fb_create, -}; From ba38b79eaeaeed29d2383f122d5c711ebf5ed3d1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 3 Dec 2020 10:34:32 +0000 Subject: [PATCH 0161/5577] drm/i915/gem: Propagate error from cancelled submit due to context closure In the course of discovering and closing many races with context closure and execbuf submission, since commit 61231f6bd056 ("drm/i915/gem: Check that the context wasn't closed during setup") we started checking that the context was not closed by another userspace thread during the execbuf ioctl. In doing so we cancelled the inflight request (by telling it to be skipped), but kept reporting success since we do submit a request, albeit one that doesn't execute. As the error is known before we return from the ioctl, we can report the error we detect immediately, rather than leave it on the fence status. With the immediate propagation of the error, it is easier for userspace to handle. Fixes: 61231f6bd056 ("drm/i915/gem: Check that the context wasn't closed during setup") Testcase: igt/gem_ctx_exec/basic-close-race Signed-off-by: Chris Wilson Cc: # v5.7+ Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20201203103432.31526-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 1904e6e5ea64..b07dc1156a0e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -3097,7 +3097,7 @@ static void retire_requests(struct intel_timeline *tl, struct i915_request *end) break; } -static void eb_request_add(struct i915_execbuffer *eb) +static int eb_request_add(struct i915_execbuffer *eb, int err) { struct i915_request *rq = eb->request; struct intel_timeline * const tl = i915_request_timeline(rq); @@ -3118,6 +3118,7 @@ static void eb_request_add(struct i915_execbuffer *eb) /* Serialise with context_close via the add_to_timeline */ i915_request_set_error_once(rq, -ENOENT); __i915_request_skip(rq); + err = -ENOENT; /* override any transient errors */ } __i915_request_queue(rq, &attr); @@ -3127,6 +3128,8 @@ static void eb_request_add(struct i915_execbuffer *eb) retire_requests(tl, prev); mutex_unlock(&tl->mutex); + + return err; } static const i915_user_extension_fn execbuf_extensions[] = { @@ -3332,7 +3335,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, err = eb_submit(&eb, batch); err_request: i915_request_get(eb.request); - eb_request_add(&eb); + err = eb_request_add(&eb, err); if (eb.fences) signal_fence_array(&eb); From b969540500bce60cf1cdfff5464388af32b9a553 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Dec 2020 15:12:31 +0000 Subject: [PATCH 0162/5577] drm/i915/gt: Ignore repeated attempts to suspend request flow across reset Before reseting the engine, we suspend the execution of the guilty request, so that we can continue execution with a new context while we slowly compress the captured error state for the guilty context. However, if the reset fails, we will promptly attempt to reset the same request again, and discover the ongoing capture. Ignore the second attempt to suspend and capture the same request. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/1168 Fixes: 32ff621fd744 ("drm/i915/gt: Allow temporary suspension of inflight requests") Signed-off-by: Chris Wilson Cc: # v5.7+ Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201204151234.19729-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 43703efb36d1..1d209a8a95e8 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2823,6 +2823,9 @@ static void __execlists_hold(struct i915_request *rq) static bool execlists_hold(struct intel_engine_cs *engine, struct i915_request *rq) { + if (i915_request_on_hold(rq)) + return false; + spin_lock_irq(&engine->active.lock); if (i915_request_completed(rq)) { /* too late! */ From d997e240ceecb4f732611985d3a939ad1bfc1893 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Dec 2020 15:12:32 +0000 Subject: [PATCH 0163/5577] drm/i915/gt: Cancel the preemption timeout on responding to it We currently presume that the engine reset is successful, cancelling the expired preemption timer in the process. However, engine resets can fail, leaving the timeout still pending and we will then respond to the timeout again next time the tasklet fires. What we want is for the failed engine reset to be promoted to a full device reset, which is kicked by the heartbeat once the engine stops processing events. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/1168 Fixes: 3a7a92aba8fb ("drm/i915/execlists: Force preemption") Signed-off-by: Chris Wilson Cc: # v5.5+ Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201204151234.19729-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 1d209a8a95e8..7f25894e41d5 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -3209,8 +3209,10 @@ static void execlists_submission_tasklet(unsigned long data) spin_unlock_irqrestore(&engine->active.lock, flags); /* Recheck after serialising with direct-submission */ - if (unlikely(timeout && preempt_timeout(engine))) + if (unlikely(timeout && preempt_timeout(engine))) { + cancel_timer(&engine->execlists.preempt); execlists_reset(engine, "preemption time out"); + } } } From cb56a07d2fd9bffbefff38c2918b096c89193218 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Dec 2020 15:12:33 +0000 Subject: [PATCH 0164/5577] drm/i915/gt: Include reset failures in the trace The GT and engine reset failures are completely invisible when looking at a trace for a bug, but are vital to understanding the incomplete flow. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201204151234.19729-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_reset.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index 9fb4306b2900..b3ccf7859ab1 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -231,7 +231,7 @@ static int g4x_do_reset(struct intel_gt *gt, GRDOM_MEDIA | GRDOM_RESET_ENABLE); ret = wait_for_atomic(g4x_reset_complete(pdev), 50); if (ret) { - drm_dbg(>->i915->drm, "Wait for media reset failed\n"); + GT_TRACE(gt, "Wait for media reset failed\n"); goto out; } @@ -239,7 +239,7 @@ static int g4x_do_reset(struct intel_gt *gt, GRDOM_RENDER | GRDOM_RESET_ENABLE); ret = wait_for_atomic(g4x_reset_complete(pdev), 50); if (ret) { - drm_dbg(>->i915->drm, "Wait for render reset failed\n"); + GT_TRACE(gt, "Wait for render reset failed\n"); goto out; } @@ -265,7 +265,7 @@ static int ilk_do_reset(struct intel_gt *gt, intel_engine_mask_t engine_mask, 5000, 0, NULL); if (ret) { - drm_dbg(>->i915->drm, "Wait for render reset failed\n"); + GT_TRACE(gt, "Wait for render reset failed\n"); goto out; } @@ -276,7 +276,7 @@ static int ilk_do_reset(struct intel_gt *gt, intel_engine_mask_t engine_mask, 5000, 0, NULL); if (ret) { - drm_dbg(>->i915->drm, "Wait for media reset failed\n"); + GT_TRACE(gt, "Wait for media reset failed\n"); goto out; } @@ -305,9 +305,9 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask) 500, 0, NULL); if (err) - drm_dbg(>->i915->drm, - "Wait for 0x%08x engines reset failed\n", - hw_domain_mask); + GT_TRACE(gt, + "Wait for 0x%08x engines reset failed\n", + hw_domain_mask); return err; } @@ -407,8 +407,7 @@ static int gen11_lock_sfc(struct intel_engine_cs *engine, u32 *hw_mask) return 0; if (ret) { - drm_dbg(&engine->i915->drm, - "Wait for SFC forced lock ack failed\n"); + ENGINE_TRACE(engine, "Wait for SFC forced lock ack failed\n"); return ret; } @@ -1148,8 +1147,7 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg) ret = intel_guc_reset_engine(&engine->gt->uc.guc, engine); if (ret) { /* If we fail here, we expect to fallback to a global reset */ - drm_dbg(>->i915->drm, "%sFailed to reset %s, ret=%d\n", - uses_guc ? "GuC " : "", engine->name, ret); + ENGINE_TRACE(engine, "Failed to reset, err: %d\n", ret); goto out; } @@ -1186,7 +1184,7 @@ static void intel_gt_reset_global(struct intel_gt *gt, kobject_uevent_env(kobj, KOBJ_CHANGE, error_event); - drm_dbg(>->i915->drm, "resetting chip, engines=%x\n", engine_mask); + GT_TRACE(gt, "resetting chip, engines=%x\n", engine_mask); kobject_uevent_env(kobj, KOBJ_CHANGE, reset_event); /* Use a watchdog to ensure that our reset completes */ From f867b66e47973dfa420afd00d8f9f7498287bb60 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Dec 2020 15:12:34 +0000 Subject: [PATCH 0165/5577] drm/i915/gt: Clear the execlists timers upon reset Across a reset, we stop the engine but not the timers. This leaves a window where the timers have inconsistent state with the engine, but should only result in a spurious timeout. As we cancel the outstanding events, also cancel their timers. Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20201204151234.19729-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_lrc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 7f25894e41d5..0c7f1e3dee5c 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2450,6 +2450,11 @@ cancel_port_requests(struct intel_engine_execlists * const execlists) smp_wmb(); /* complete the seqlock for execlists_active() */ WRITE_ONCE(execlists->active, execlists->inflight); + + /* Having cancelled all outstanding process_csb(), stop their timers */ + GEM_BUG_ON(execlists->pending[0]); + cancel_timer(&execlists->timer); + cancel_timer(&execlists->preempt); } static inline void From ee42ec19ca2e5575815cbccf2a039ea823d8e7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 24 Nov 2020 22:11:53 +0200 Subject: [PATCH 0166/5577] drm/i915: Track logically enabled planes for hw state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently crtc_state->uapi.plane_mask only tracks logically enabled planes on the uapi level. For bigjoiner purposes we want to do the same for the hw state. Let's follow the pattern established by active_planes & co. here. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201124201156.17095-1-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 3 +++ drivers/gpu/drm/i915/display/intel_display.c | 13 +++++++++---- drivers/gpu/drm/i915/display/intel_display_types.h | 5 ++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 7e9f84b00859..b5e1ee99535c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -312,10 +312,13 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ int ret; intel_plane_set_invisible(new_crtc_state, new_plane_state); + new_crtc_state->enabled_planes &= ~BIT(plane->id); if (!new_plane_state->hw.crtc && !old_plane_state->hw.crtc) return 0; + new_crtc_state->enabled_planes |= BIT(plane->id); + ret = plane->check_plane(new_crtc_state, new_plane_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6e5b93f6a25e..2d0d1b2ef957 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3552,7 +3552,7 @@ intel_set_plane_visible(struct intel_crtc_state *crtc_state, crtc_state->uapi.plane_mask &= ~drm_plane_mask(&plane->base); } -static void fixup_active_planes(struct intel_crtc_state *crtc_state) +static void fixup_plane_bitmasks(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); struct drm_plane *plane; @@ -3562,11 +3562,14 @@ static void fixup_active_planes(struct intel_crtc_state *crtc_state) * have been used on the same (or wrong) pipe. plane_mask uses * unique ids, hence we can use that to reconstruct active_planes. */ + crtc_state->enabled_planes = 0; crtc_state->active_planes = 0; drm_for_each_plane_mask(plane, &dev_priv->drm, - crtc_state->uapi.plane_mask) + crtc_state->uapi.plane_mask) { + crtc_state->enabled_planes |= BIT(to_intel_plane(plane)->id); crtc_state->active_planes |= BIT(to_intel_plane(plane)->id); + } } static void intel_plane_disable_noatomic(struct intel_crtc *crtc, @@ -3584,7 +3587,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc, crtc->base.base.id, crtc->base.name); intel_set_plane_visible(crtc_state, plane_state, false); - fixup_active_planes(crtc_state); + fixup_plane_bitmasks(crtc_state); crtc_state->data_rate[plane->id] = 0; crtc_state->min_cdclk[plane->id] = 0; @@ -12804,6 +12807,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state) plane_state->planar_linked_plane = NULL; if (plane_state->planar_slave && !plane_state->uapi.visible) { + crtc_state->enabled_planes &= ~BIT(plane->id); crtc_state->active_planes &= ~BIT(plane->id); crtc_state->update_planes |= BIT(plane->id); } @@ -12847,6 +12851,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state) linked_state->planar_slave = true; linked_state->planar_linked_plane = plane; + crtc_state->enabled_planes |= BIT(linked->id); crtc_state->active_planes |= BIT(linked->id); crtc_state->update_planes |= BIT(linked->id); drm_dbg_kms(&dev_priv->drm, "Using %s as Y plane for %s\n", @@ -19133,7 +19138,7 @@ static void readout_plane_state(struct drm_i915_private *dev_priv) struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); - fixup_active_planes(crtc_state); + fixup_plane_bitmasks(crtc_state); } } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 1fa0246b3a82..5bc5bfbc4551 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1053,7 +1053,10 @@ struct intel_crtc_state { u32 cgm_mode; }; - /* bitmask of visible planes (enum plane_id) */ + /* bitmask of logically enabled planes (enum plane_id) */ + u8 enabled_planes; + + /* bitmask of actually visible planes (enum plane_id) */ u8 active_planes; u8 nv12_planes; u8 c8_planes; From 9e363c82baf185baba9c42ae78c30b5e7be98937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 24 Nov 2020 22:11:54 +0200 Subject: [PATCH 0167/5577] drm/i915: Add intel_atomic_add_affected_planes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_atomic_add_affected_planes() only considers planes which are logically enabled in the uapi state. For bigjoiner we need to consider planes logically enabled in the hw state. Add a helper for that. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201124201156.17095-2-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/display/intel_cdclk.c | 3 +-- drivers/gpu/drm/i915/display/intel_display.c | 13 +++++++++++++ drivers/gpu/drm/i915/display/intel_display.h | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 088d5908176c..2e878cc274b7 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2415,8 +2415,7 @@ static int intel_modeset_all_pipes(struct intel_atomic_state *state) if (ret) return ret; - ret = drm_atomic_add_affected_planes(&state->base, - &crtc->base); + ret = intel_atomic_add_affected_planes(state, crtc); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2d0d1b2ef957..bcc7d5f8e0a8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -15069,6 +15069,19 @@ static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state, return 0; } +int intel_atomic_add_affected_planes(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + const struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + return intel_crtc_add_planes_to_state(state, crtc, + old_crtc_state->enabled_planes | + new_crtc_state->enabled_planes); +} + static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv) { /* See {hsw,vlv,ivb}_plane_ratio() */ diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 5e0d42d82c11..a5771bfecba6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -499,6 +499,8 @@ enum phy_fia { ((connector) = to_intel_connector((__state)->base.connectors[__i].ptr), \ (new_connector_state) = to_intel_digital_connector_state((__state)->base.connectors[__i].new_state), 1)) +int intel_atomic_add_affected_planes(struct intel_atomic_state *state, + struct intel_crtc *crtc); u8 intel_calc_active_pipes(struct intel_atomic_state *state, u8 active_pipes); void intel_link_compute_m_n(u16 bpp, int nlanes, From 72305a8080701cb4e3aff585aa90bcd5afd3bd9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 24 Nov 2020 22:11:55 +0200 Subject: [PATCH 0168/5577] drm/i915: Properly flag modesets for all bigjoiner pipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If either of the bigjoiner pipes needs a modeset then we need a modeset on both pipes. Make it so. v2: Split out the kill_bigjoiner_slave() change (Manasi) Add affected connectors/planes Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201124201156.17095-3-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/display/intel_display.c | 32 ++++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bcc7d5f8e0a8..be741c537892 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -15487,20 +15487,36 @@ static int intel_atomic_check_async(struct intel_atomic_state *state) static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state) { - const struct intel_crtc_state *crtc_state; + struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; int i; for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { struct intel_crtc_state *linked_crtc_state; + struct intel_crtc *linked_crtc; + int ret; if (!crtc_state->bigjoiner) continue; - linked_crtc_state = intel_atomic_get_crtc_state(&state->base, - crtc_state->bigjoiner_linked_crtc); + linked_crtc = crtc_state->bigjoiner_linked_crtc; + linked_crtc_state = intel_atomic_get_crtc_state(&state->base, linked_crtc); if (IS_ERR(linked_crtc_state)) return PTR_ERR(linked_crtc_state); + + if (!needs_modeset(crtc_state)) + continue; + + linked_crtc_state->uapi.mode_changed = true; + + ret = drm_atomic_add_affected_connectors(&state->base, + &linked_crtc->base); + if (ret) + return ret; + + ret = intel_atomic_add_affected_planes(state, linked_crtc); + if (ret) + return ret; } return 0; @@ -15620,6 +15636,16 @@ static int intel_atomic_check(struct drm_device *dev, new_crtc_state->update_pipe = false; } } + + if (new_crtc_state->bigjoiner) { + struct intel_crtc_state *linked_crtc_state = + intel_atomic_get_new_crtc_state(state, new_crtc_state->bigjoiner_linked_crtc); + + if (needs_modeset(linked_crtc_state)) { + new_crtc_state->uapi.mode_changed = true; + new_crtc_state->update_pipe = false; + } + } } for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, From 005650283a9b97993629daa1ab5e0aa127282fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 24 Nov 2020 22:11:56 +0200 Subject: [PATCH 0169/5577] drm/i915: Call kill_bigjoiner_slave() earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's do the kill_bigjoiner_slave() thing from intel_bigjoiner_add_affected_crtcs() since it's related to what we do there. This cleans up the logic in the compute_config() loop a bit. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201124201156.17095-4-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/display/intel_display.c | 25 ++++++++------------ 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index be741c537892..c567c0cada7e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -15335,21 +15335,16 @@ claimed: return -EINVAL; } -static int kill_bigjoiner_slave(struct intel_atomic_state *state, - struct intel_crtc_state *master_crtc_state) +static void kill_bigjoiner_slave(struct intel_atomic_state *state, + struct intel_crtc_state *master_crtc_state) { struct intel_crtc_state *slave_crtc_state = - intel_atomic_get_crtc_state(&state->base, - master_crtc_state->bigjoiner_linked_crtc); - - if (IS_ERR(slave_crtc_state)) - return PTR_ERR(slave_crtc_state); + intel_atomic_get_new_crtc_state(state, master_crtc_state->bigjoiner_linked_crtc); slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false; slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false; slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL; intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state); - return 0; } /** @@ -15519,6 +15514,13 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state) return ret; } + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + /* Kill old bigjoiner link, we may re-establish afterwards */ + if (needs_modeset(crtc_state) && + crtc_state->bigjoiner && !crtc_state->bigjoiner_slave) + kill_bigjoiner_slave(state, crtc_state); + } + return 0; } @@ -15560,13 +15562,6 @@ static int intel_atomic_check(struct drm_device *dev, continue; } - /* Kill old bigjoiner link, we may re-establish afterwards */ - if (old_crtc_state->bigjoiner && !old_crtc_state->bigjoiner_slave) { - ret = kill_bigjoiner_slave(state, new_crtc_state); - if (ret) - goto fail; - } - if (!new_crtc_state->uapi.enable) { if (!new_crtc_state->bigjoiner_slave) { intel_crtc_copy_uapi_to_hw_state(state, new_crtc_state); From 9d8fddf8579a2a20d0e8a8b631547069a62b953e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Dec 2020 16:16:01 +0000 Subject: [PATCH 0170/5577] drm/i915: Disable outputs during unregister MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch off the scanout during driver unregister, so we can shutdown the HW immediately for unbind. v2: Remove the old shutdown from remove, it should now be redundant. Signed-off-by: Chris Wilson Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201204161601.20897-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index abd49017aea1..7285634914fc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -738,6 +738,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) * events. */ drm_kms_helper_poll_fini(&dev_priv->drm); + drm_atomic_helper_shutdown(&dev_priv->drm); intel_gt_driver_unregister(&dev_priv->gt); acpi_video_unregister(); @@ -940,8 +941,6 @@ void i915_driver_remove(struct drm_i915_private *i915) i915_gem_suspend(i915); - drm_atomic_helper_shutdown(&i915->drm); - intel_gvt_driver_remove(i915); intel_modeset_driver_remove(i915); From 1efa473e65e3cefbd03c5cc9fed6f7fa73bf31d2 Mon Sep 17 00:00:00 2001 From: Swathi Dhanavanthri Date: Sat, 5 Dec 2020 01:25:39 -0800 Subject: [PATCH 0171/5577] drm/i915/dg1: Implement WA_16011163337 Set GS Timer to 224 to prevent a HS/DS hang. Bspec: 53508 v2: reword commit message and add comment explaining why read verification is ignored (Chris) Cc: Matt Roper Signed-off-by: Swathi Dhanavanthri Signed-off-by: Lucas De Marchi Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201205092542.2325477-1-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 7c6b21ced56f..a81728c52bd5 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -686,6 +686,16 @@ static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine, /* Wa_22010493298 */ WA_SET_BIT_MASKED(HIZ_CHICKEN, DG1_HZ_READ_SUPPRESSION_OPTIMIZATION_DISABLE); + + /* + * Wa_16011163337 + * + * Like in tgl_ctx_workarounds_init(), read verification is ignored due + * to Wa_1608008084. + */ + wa_add(wal, + FF_MODE2, + FF_MODE2_GS_TIMER_MASK, FF_MODE2_GS_TIMER_224, 0); } static void From b9bdccd51afdfb2d7ba276872f5cd102df042744 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Sat, 5 Dec 2020 01:25:40 -0800 Subject: [PATCH 0172/5577] drm/i915: remove WA_SET_BIT_MASKED() Just ommitting the list it's operating on doesn't save much typing and adds another way to do the same thing. Just replace it with wa_masked_en(). Signed-off-by: Lucas De Marchi Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201205092542.2325477-2-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 159 ++++++++++---------- 1 file changed, 78 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index a81728c52bd5..b359eaed2da2 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -229,9 +229,6 @@ wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val) wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val); } -#define WA_SET_BIT_MASKED(addr, mask) \ - wa_masked_en(wal, (addr), (mask)) - #define WA_CLR_BIT_MASKED(addr, mask) \ wa_masked_dis(wal, (addr), (mask)) @@ -241,26 +238,26 @@ wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val) static void gen6_ctx_workarounds_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) { - WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); + wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING); } static void gen7_ctx_workarounds_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) { - WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); + wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING); } static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) { - WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); + wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING); /* WaDisableAsyncFlipPerfMode:bdw,chv */ - WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE); + wa_masked_en(wal, MI_MODE, ASYNC_FLIP_PERF_DISABLE); /* WaDisablePartialInstShootdown:bdw,chv */ - WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, - PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); + wa_masked_en(wal, GEN8_ROW_CHICKEN, + PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); /* Use Force Non-Coherent whenever executing a 3D context. This is a * workaround for for a possible hang in the unlikely event a TLB @@ -268,9 +265,9 @@ static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine, */ /* WaForceEnableNonCoherent:bdw,chv */ /* WaHdcDisableFetchWhenMasked:bdw,chv */ - WA_SET_BIT_MASKED(HDC_CHICKEN0, - HDC_DONOT_FETCH_MEM_WHEN_MASKED | - HDC_FORCE_NON_COHERENT); + wa_masked_en(wal, HDC_CHICKEN0, + HDC_DONOT_FETCH_MEM_WHEN_MASKED | + HDC_FORCE_NON_COHERENT); /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: * "The Hierarchical Z RAW Stall Optimization allows non-overlapping @@ -283,7 +280,7 @@ static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine, WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); /* Wa4x4STCOptimizationDisable:bdw,chv */ - WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); + wa_masked_en(wal, CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); /* * BSpec recommends 8x4 when MSAA is used, @@ -306,24 +303,24 @@ static void bdw_ctx_workarounds_init(struct intel_engine_cs *engine, gen8_ctx_workarounds_init(engine, wal); /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ - WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); + wa_masked_en(wal, GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); /* WaDisableDopClockGating:bdw * * Also see the related UCGTCL1 write in bdw_init_clock_gating() * to disable EUTC clock gating. */ - WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, - DOP_CLOCK_GATING_DISABLE); + wa_masked_en(wal, GEN7_ROW_CHICKEN2, + DOP_CLOCK_GATING_DISABLE); - WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, - GEN8_SAMPLER_POWER_BYPASS_DIS); + wa_masked_en(wal, HALF_SLICE_CHICKEN3, + GEN8_SAMPLER_POWER_BYPASS_DIS); - WA_SET_BIT_MASKED(HDC_CHICKEN0, - /* WaForceContextSaveRestoreNonCoherent:bdw */ - HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | - /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ - (IS_BDW_GT3(i915) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); + wa_masked_en(wal, HDC_CHICKEN0, + /* WaForceContextSaveRestoreNonCoherent:bdw */ + HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | + /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ + (IS_BDW_GT3(i915) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); } static void chv_ctx_workarounds_init(struct intel_engine_cs *engine, @@ -332,10 +329,10 @@ static void chv_ctx_workarounds_init(struct intel_engine_cs *engine, gen8_ctx_workarounds_init(engine, wal); /* WaDisableThreadStallDopClockGating:chv */ - WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); + wa_masked_en(wal, GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); /* Improve HiZ throughput on CHV. */ - WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); + wa_masked_en(wal, HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); } static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine, @@ -349,38 +346,38 @@ static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine, * Must match Display Engine. See * WaCompressedResourceDisplayNewHashMode. */ - WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, - GEN9_PBE_COMPRESSED_HASH_SELECTION); - WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, - GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR); + wa_masked_en(wal, COMMON_SLICE_CHICKEN2, + GEN9_PBE_COMPRESSED_HASH_SELECTION); + wa_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7, + GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR); } /* 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); + wa_masked_en(wal, GEN8_ROW_CHICKEN, + FLOW_CONTROL_ENABLE | + PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); /* 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); + wa_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7, + GEN9_ENABLE_YV12_BUGFIX | + GEN9_ENABLE_GPGPU_PREEMPTION); /* 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); + wa_masked_en(wal, CACHE_MODE_1, + GEN8_4x4_STC_OPTIMIZATION_DISABLE | + GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */ WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, GEN9_CCS_TLB_PREFETCH_ENABLE); /* 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); + wa_masked_en(wal, HDC_CHICKEN0, + HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | + HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE); /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are * both tied to WaForceContextSaveRestoreNonCoherent @@ -396,19 +393,19 @@ static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine, */ /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */ - WA_SET_BIT_MASKED(HDC_CHICKEN0, - HDC_FORCE_NON_COHERENT); + wa_masked_en(wal, HDC_CHICKEN0, + HDC_FORCE_NON_COHERENT); /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */ if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) - WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, - GEN8_SAMPLER_POWER_BYPASS_DIS); + wa_masked_en(wal, HALF_SLICE_CHICKEN3, + GEN8_SAMPLER_POWER_BYPASS_DIS); /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */ - WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); + wa_masked_en(wal, HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); /* * Supporting preemption with fine-granularity requires changes in the @@ -431,7 +428,7 @@ static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine, /* WaClearHIZ_WM_CHICKEN3:bxt,glk */ if (IS_GEN9_LP(i915)) - WA_SET_BIT_MASKED(GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ); + wa_masked_en(wal, GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ); } static void skl_tune_iz_hashing(struct intel_engine_cs *engine, @@ -487,12 +484,12 @@ static void bxt_ctx_workarounds_init(struct intel_engine_cs *engine, gen9_ctx_workarounds_init(engine, wal); /* WaDisableThreadStallDopClockGating:bxt */ - WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, - STALL_DOP_GATING_DISABLE); + wa_masked_en(wal, GEN8_ROW_CHICKEN, + STALL_DOP_GATING_DISABLE); /* WaToEnableHwFixForPushConstHWBug:bxt */ - WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, - GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); + wa_masked_en(wal, COMMON_SLICE_CHICKEN2, + GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); } static void kbl_ctx_workarounds_init(struct intel_engine_cs *engine, @@ -504,12 +501,12 @@ static void kbl_ctx_workarounds_init(struct intel_engine_cs *engine, /* WaToEnableHwFixForPushConstHWBug:kbl */ if (IS_KBL_GT_REVID(i915, KBL_REVID_C0, REVID_FOREVER)) - WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, - GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); + wa_masked_en(wal, COMMON_SLICE_CHICKEN2, + GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); /* WaDisableSbeCacheDispatchPortSharing:kbl */ - WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1, - GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); + wa_masked_en(wal, GEN7_HALF_SLICE_CHICKEN1, + GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); } static void glk_ctx_workarounds_init(struct intel_engine_cs *engine, @@ -518,8 +515,8 @@ static void glk_ctx_workarounds_init(struct intel_engine_cs *engine, gen9_ctx_workarounds_init(engine, wal); /* WaToEnableHwFixForPushConstHWBug:glk */ - WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, - GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); + wa_masked_en(wal, COMMON_SLICE_CHICKEN2, + GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); } static void cfl_ctx_workarounds_init(struct intel_engine_cs *engine, @@ -528,30 +525,30 @@ static void cfl_ctx_workarounds_init(struct intel_engine_cs *engine, gen9_ctx_workarounds_init(engine, wal); /* WaToEnableHwFixForPushConstHWBug:cfl */ - WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, - GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); + wa_masked_en(wal, COMMON_SLICE_CHICKEN2, + GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); /* WaDisableSbeCacheDispatchPortSharing:cfl */ - WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1, - GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); + wa_masked_en(wal, GEN7_HALF_SLICE_CHICKEN1, + GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); } static void cnl_ctx_workarounds_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) { /* WaForceContextSaveRestoreNonCoherent:cnl */ - WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0, - HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT); + wa_masked_en(wal, CNL_HDC_CHICKEN0, + HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT); /* WaDisableReplayBufferBankArbitrationOptimization:cnl */ - WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, - GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); + wa_masked_en(wal, COMMON_SLICE_CHICKEN2, + GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); /* WaPushConstantDereferenceHoldDisable:cnl */ - WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE); + wa_masked_en(wal, GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE); /* FtrEnableFastAnisoL1BankingFix:cnl */ - WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX); + wa_masked_en(wal, HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX); /* WaDisable3DMidCmdPreemption:cnl */ WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); @@ -562,7 +559,7 @@ static void cnl_ctx_workarounds_init(struct intel_engine_cs *engine, GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); /* WaDisableEarlyEOT:cnl */ - WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, DISABLE_EARLY_EOT); + wa_masked_en(wal, GEN8_ROW_CHICKEN, DISABLE_EARLY_EOT); } static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, @@ -580,8 +577,8 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, * Formerly known as WaPushConstantDereferenceHoldDisable */ if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0)) - WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, - PUSH_CONSTANT_DEREF_DISABLE); + wa_masked_en(wal, GEN7_ROW_CHICKEN2, + PUSH_CONSTANT_DEREF_DISABLE); /* WaForceEnableNonCoherent:icl * This is not the same workaround as in early Gen9 platforms, where @@ -590,19 +587,19 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, * (the register is whitelisted in hardware now, so UMDs can opt in * for coherency if they have a good reason). */ - WA_SET_BIT_MASKED(ICL_HDC_MODE, HDC_FORCE_NON_COHERENT); + wa_masked_en(wal, ICL_HDC_MODE, HDC_FORCE_NON_COHERENT); /* Wa_2006611047:icl (pre-prod) * Formerly known as WaDisableImprovedTdlClkGating */ if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0)) - WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, - GEN11_TDL_CLOCK_GATING_FIX_DISABLE); + wa_masked_en(wal, GEN7_ROW_CHICKEN2, + GEN11_TDL_CLOCK_GATING_FIX_DISABLE); /* Wa_2006665173:icl (pre-prod) */ if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0)) - WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3, - GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC); + wa_masked_en(wal, GEN11_COMMON_SLICE_CHICKEN3, + GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC); /* WaEnableFloatBlendOptimization:icl */ wa_write_masked_or(wal, @@ -616,8 +613,8 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL); /* allow headerless messages for preemptible GPGPU context */ - WA_SET_BIT_MASKED(GEN10_SAMPLER_MODE, - GEN11_SAMPLER_ENABLE_HEADLESS_MSG); + wa_masked_en(wal, GEN10_SAMPLER_MODE, + GEN11_SAMPLER_ENABLE_HEADLESS_MSG); /* Wa_1604278689:icl,ehl */ wa_write(wal, IVB_FBC_RT_BASE, 0xFFFFFFFF & ~ILK_FBC_RT_VALID); @@ -643,8 +640,8 @@ static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine, * Wa_14010443199:rkl * Wa_14010698770:rkl */ - WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3, - GEN12_DISABLE_CPS_AWARE_COLOR_PIPE); + wa_masked_en(wal, GEN11_COMMON_SLICE_CHICKEN3, + GEN12_DISABLE_CPS_AWARE_COLOR_PIPE); /* WaDisableGPGPUMidThreadPreemption:gen12 */ WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, @@ -684,8 +681,8 @@ static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine, DG1_FLOAT_POINT_BLEND_OPT_STRICT_MODE_EN); /* Wa_22010493298 */ - WA_SET_BIT_MASKED(HIZ_CHICKEN, - DG1_HZ_READ_SUPPRESSION_OPTIMIZATION_DISABLE); + wa_masked_en(wal, HIZ_CHICKEN, + DG1_HZ_READ_SUPPRESSION_OPTIMIZATION_DISABLE); /* * Wa_16011163337 From 66901614283b4691dd7622e56d07fec322045716 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Sat, 5 Dec 2020 01:25:41 -0800 Subject: [PATCH 0173/5577] drm/i915: remove WA_CLR_BIT_MASKED() Just ommitting the list it's operating on doesn't save much typing and adds another way to do the same thing. Just replace it with wa_masked_dis(). Signed-off-by: Lucas De Marchi Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201205092542.2325477-3-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index b359eaed2da2..0d8ae0096e8c 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -229,9 +229,6 @@ wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val) wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val); } -#define WA_CLR_BIT_MASKED(addr, mask) \ - wa_masked_dis(wal, (addr), (mask)) - #define WA_SET_FIELD_MASKED(addr, mask, value) \ wa_write_masked_or(wal, (addr), 0, _MASKED_FIELD((mask), (value))) @@ -277,7 +274,7 @@ static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine, * * This optimization is off by default for BDW and CHV; turn it on. */ - WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); + wa_masked_dis(wal, CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); /* Wa4x4STCOptimizationDisable:bdw,chv */ wa_masked_en(wal, CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); @@ -371,8 +368,8 @@ static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine, GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */ - WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, - GEN9_CCS_TLB_PREFETCH_ENABLE); + wa_masked_dis(wal, GEN9_HALF_SLICE_CHICKEN5, + GEN9_CCS_TLB_PREFETCH_ENABLE); /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */ wa_masked_en(wal, HDC_CHICKEN0, @@ -419,7 +416,7 @@ static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine, */ /* WaDisable3DMidCmdPreemption:skl,bxt,glk,cfl,[cnl] */ - WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); + wa_masked_dis(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); /* WaDisableGPGPUMidCmdPreemption:skl,bxt,blk,cfl,[cnl] */ WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, @@ -551,7 +548,7 @@ static void cnl_ctx_workarounds_init(struct intel_engine_cs *engine, wa_masked_en(wal, HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX); /* WaDisable3DMidCmdPreemption:cnl */ - WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); + wa_masked_dis(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); /* WaDisableGPGPUMidCmdPreemption:cnl */ WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, @@ -677,8 +674,8 @@ static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine, gen12_ctx_workarounds_init(engine, wal); /* Wa_1409044764 */ - WA_CLR_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3, - DG1_FLOAT_POINT_BLEND_OPT_STRICT_MODE_EN); + wa_masked_dis(wal, GEN11_COMMON_SLICE_CHICKEN3, + DG1_FLOAT_POINT_BLEND_OPT_STRICT_MODE_EN); /* Wa_22010493298 */ wa_masked_en(wal, HIZ_CHICKEN, From 6ca07255ac409fd78931b3def62896e7e6541a47 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Sat, 5 Dec 2020 01:25:42 -0800 Subject: [PATCH 0174/5577] drm/i915: remove WA_SET_FIELD_MASKED() Remove the last macro and implement it as a function like the rest of the operations that don't assume there is a `wal` list, but rather receive it as argument. Signed-off-by: Lucas De Marchi Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201205092542.2325477-4-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 0d8ae0096e8c..2db1e68d7464 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -229,8 +229,12 @@ wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val) wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val); } -#define WA_SET_FIELD_MASKED(addr, mask, value) \ - wa_write_masked_or(wal, (addr), 0, _MASKED_FIELD((mask), (value))) +static void +wa_masked_field_set(struct i915_wa_list *wal, i915_reg_t reg, + u32 mask, u32 val) +{ + wa_write_masked_or(wal, reg, 0, _MASKED_FIELD(mask, val)); +} static void gen6_ctx_workarounds_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) @@ -287,7 +291,7 @@ static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine, * disable bit, which we don't touch here, but it's good * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). */ - WA_SET_FIELD_MASKED(GEN7_GT_MODE, + wa_masked_field_set(wal, GEN7_GT_MODE, GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4); } @@ -419,7 +423,7 @@ static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine, wa_masked_dis(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); /* WaDisableGPGPUMidCmdPreemption:skl,bxt,blk,cfl,[cnl] */ - WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, + wa_masked_field_set(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); @@ -459,7 +463,7 @@ static void skl_tune_iz_hashing(struct intel_engine_cs *engine, return; /* Tune IZ hashing. See intel_device_info_runtime_init() */ - WA_SET_FIELD_MASKED(GEN7_GT_MODE, + wa_masked_field_set(wal, GEN7_GT_MODE, GEN9_IZ_HASHING_MASK(2) | GEN9_IZ_HASHING_MASK(1) | GEN9_IZ_HASHING_MASK(0), @@ -551,7 +555,7 @@ static void cnl_ctx_workarounds_init(struct intel_engine_cs *engine, wa_masked_dis(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL); /* WaDisableGPGPUMidCmdPreemption:cnl */ - WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, + wa_masked_field_set(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); @@ -605,7 +609,7 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, _MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE)); /* WaDisableGPGPUMidThreadPreemption:icl */ - WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, + wa_masked_field_set(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL); @@ -641,7 +645,7 @@ static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine, GEN12_DISABLE_CPS_AWARE_COLOR_PIPE); /* WaDisableGPGPUMidThreadPreemption:gen12 */ - WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, + wa_masked_field_set(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL); } From 1cdd3f739f4e839e77b83bb3238150c41905c748 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 4 Dec 2020 11:29:32 +0200 Subject: [PATCH 0175/5577] drm: Remove drmm_add_final_kfree() declaration from public headers The drmm_add_final_kfree() function is declared in the include/drm/drm_managed.h public header, but has become an internal API not exposed to drivers. Drop it from drm_managed.h as it's already declared in drm_internal.h. Signed-off-by: Laurent Pinchart Acked-by: Thomas Zimmermann Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201204092932.21636-1-laurent.pinchart+renesas@ideasonboard.com --- include/drm/drm_managed.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h index ca4114633bf9..b45c6fbf53ac 100644 --- a/include/drm/drm_managed.h +++ b/include/drm/drm_managed.h @@ -44,8 +44,6 @@ int __must_check __drmm_add_action_or_reset(struct drm_device *dev, drmres_release_t action, void *data, const char *name); -void drmm_add_final_kfree(struct drm_device *dev, void *container); - void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc; /** From a00fa4285878e5fe5b452111bc8004c185cc2dd5 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 1 Dec 2020 12:59:12 -0800 Subject: [PATCH 0176/5577] drm: panel: Fully transition panel_desc kerneldoc to inline style In commit 131f909ad55f ("drm: panel: simple: Fixup the struct panel_desc kernel doc") I transitioned the more deeply nested kerneldoc comments into the inline style. Apparently it is desirable to continue the job and move _everything_ in this struct to inline. Let's do it. While doing this, we also add a short summary for the whole struct to fix a warning when we run with extra warnings, AKA: scripts/kernel-doc -v -rst drivers/gpu/drm/panel/panel-simple.c The warning was: drivers/gpu/drm/panel/panel-simple.c:42: warning: missing initial short description on line: * struct panel_desc Suggested-by: Sam Ravnborg Signed-off-by: Douglas Anderson Cc: Douglas Anderson Cc: Sam Ravnborg Cc: Thierry Reding Cc: dri-devel@lists.freedesktop.org Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201201125822.1.I3c4191336014bd57364309439e56f600c94bb12b@changeid --- drivers/gpu/drm/panel/panel-simple.c | 43 +++++++++++++++++----------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 216cde33b5c4..faa45af48c15 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -39,31 +39,36 @@ #include /** - * struct panel_desc - * @modes: Pointer to array of fixed modes appropriate for this panel. If - * only one mode then this can just be the address of this the mode. - * NOTE: cannot be used with "timings" and also if this is specified - * then you cannot override the mode in the device tree. - * @num_modes: Number of elements in modes array. - * @timings: Pointer to array of display timings. NOTE: cannot be used with - * "modes" and also these will be used to validate a device tree - * override if one is present. - * @num_timings: Number of elements in timings array. - * @bpc: Bits per color. - * @size: Structure containing the physical size of this panel. - * @delay: Structure containing various delay values for this panel. - * @bus_format: See MEDIA_BUS_FMT_... defines. - * @bus_flags: See DRM_BUS_FLAG_... defines. - * @connector_type: LVDS, eDP, DSI, DPI, etc. + * struct panel_desc - Describes a simple panel. */ struct panel_desc { + /** + * @modes: Pointer to array of fixed modes appropriate for this panel. + * + * If only one mode then this can just be the address of the mode. + * NOTE: cannot be used with "timings" and also if this is specified + * then you cannot override the mode in the device tree. + */ const struct drm_display_mode *modes; + + /** @num_modes: Number of elements in modes array. */ unsigned int num_modes; + + /** + * @timings: Pointer to array of display timings + * + * NOTE: cannot be used with "modes" and also these will be used to + * validate a device tree override if one is present. + */ const struct display_timing *timings; + + /** @num_timings: Number of elements in timings array. */ unsigned int num_timings; + /** @bpc: Bits per color. */ unsigned int bpc; + /** @size: Structure containing the physical size of this panel. */ struct { /** * @size.width: Width (in mm) of the active display area. @@ -76,6 +81,7 @@ struct panel_desc { unsigned int height; } size; + /** @delay: Structure containing various delay values for this panel. */ struct { /** * @delay.prepare: Time for the panel to become ready. @@ -154,8 +160,13 @@ struct panel_desc { unsigned int unprepare; } delay; + /** @bus_format: See MEDIA_BUS_FMT_... defines. */ u32 bus_format; + + /** @bus_flags: See DRM_BUS_FLAG_... defines. */ u32 bus_flags; + + /** @connector_type: LVDS, eDP, DSI, DPI, etc. */ int connector_type; }; From 9dbf1a4516cff8617fde63d265ccbdd6a0f56854 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 1 Dec 2020 12:56:11 -0800 Subject: [PATCH 0177/5577] drm: panel: add flags to BOE NV110WTM-N61 I forgot to add these when posting up the support for BOE NV110WTM-N61. Add them now. Fixes: a96ee0f6b58d ("drm: panel: simple: Add BOE NV110WTM-N61") Signed-off-by: Douglas Anderson Cc: Douglas Anderson Cc: Sam Ravnborg Cc: Thierry Reding Cc: dri-devel@lists.freedesktop.org Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201201125554.v2.1.I8a7bfc0966e803ab91001c9e6d01a736950c4981@changeid --- drivers/gpu/drm/panel/panel-simple.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index faa45af48c15..71ae200ac48a 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1418,6 +1418,7 @@ static const struct drm_display_mode boe_nv110wtm_n61_modes[] = { .vsync_start = 1440 + 3, .vsync_end = 1440 + 3 + 6, .vtotal = 1440 + 3 + 6 + 31, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, }, { .clock = 138500, @@ -1429,6 +1430,7 @@ static const struct drm_display_mode boe_nv110wtm_n61_modes[] = { .vsync_start = 1440 + 3, .vsync_end = 1440 + 3 + 6, .vtotal = 1440 + 3 + 6 + 31, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, }, }; From 98fdd0042c7c82e0b4bca6100eec35f73b48878d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 29 Nov 2020 21:09:08 +0100 Subject: [PATCH 0178/5577] drm/kmb: fix array bounds warning gcc warns about an out-of-bounds access when the using nonzero values for 'plane_id' on kmb->plane_status: drivers/gpu/drm/kmb/kmb_plane.c: In function 'kmb_plane_atomic_disable': drivers/gpu/drm/kmb/kmb_plane.c:128:20: warning: array subscript 3 is above array bounds of 'struct layer_status[1]' [-Warray-bounds] 128 | kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL2_ENABLE; | ~~~~~~~~~~~~~~~~~^~~~~~~~~~ drivers/gpu/drm/kmb/kmb_plane.c:125:20: warning: array subscript 2 is above array bounds of 'struct layer_status[1]' [-Warray-bounds] 125 | kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL1_ENABLE; | ~~~~~~~~~~~~~~~~~^~~~~~~~~~ drivers/gpu/drm/kmb/kmb_plane.c:122:20: warning: array subscript 1 is above array bounds of 'struct layer_status[1]' [-Warray-bounds] 122 | kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL2_ENABLE; Having the array truncated to one entry seems intentional, so add a range check before indexing it to make it clearer what is going on and shut up the warning. I received the warning from the kernel test robot after a private patch that turns on Warray-bounds unconditionally. Fixes: 7f7b96a8a0a1 ("drm/kmb: Add support for KeemBay Display") Reported-by: kernel test robot Signed-off-by: Arnd Bergmann Reviewed-by: Anitha Chrisanthus Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201129200927.1854104-1-arnd@kernel.org --- drivers/gpu/drm/kmb/kmb_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/kmb/kmb_plane.c b/drivers/gpu/drm/kmb/kmb_plane.c index 8448d1edb553..be8eea3830c1 100644 --- a/drivers/gpu/drm/kmb/kmb_plane.c +++ b/drivers/gpu/drm/kmb/kmb_plane.c @@ -114,6 +114,9 @@ static void kmb_plane_atomic_disable(struct drm_plane *plane, kmb = to_kmb(plane->dev); + if (WARN_ON(plane_id >= KMB_MAX_PLANES)) + return; + switch (plane_id) { case LAYER_0: kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL1_ENABLE; From c96da175ba88ea1585b21e7331f1d3a1f9ba8292 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:08 +0100 Subject: [PATCH 0179/5577] video: fbdev: omapfb: Fix set but not used warnings in dsi Fix several W=1 warnings. This removes unused code and avoids an assignment by moving the use inside the conditional block. The register read FLD_GET(r, 15, 8) could be dropped as it was done a few lines before too. v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Aditya Pakki Cc: Sam Ravnborg Cc: Bartlomiej Zolnierkiewicz Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-23-sam@ravnborg.org --- drivers/video/fbdev/omap2/omapfb/dss/dsi.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c index 101fa66f9b58..58c7aa279ab1 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c @@ -1178,13 +1178,12 @@ static int dsi_regulator_init(struct platform_device *dsidev) static void _dsi_print_reset_status(struct platform_device *dsidev) { - u32 l; int b0, b1, b2; /* A dummy read using the SCP interface to any DSIPHY register is * required after DSIPHY reset to complete the reset of the DSI complex * I/O. */ - l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); + dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) { b0 = 28; @@ -3627,7 +3626,7 @@ static int dsi_proto_config(struct platform_device *dsidev) static void dsi_proto_timings(struct platform_device *dsidev) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; + unsigned tlpx, tclk_zero, tclk_prepare; unsigned tclk_pre, tclk_post; unsigned ths_prepare, ths_prepare_ths_zero, ths_zero; unsigned ths_trail, ths_exit; @@ -3646,7 +3645,6 @@ static void dsi_proto_timings(struct platform_device *dsidev) r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); tlpx = FLD_GET(r, 20, 16) * 2; - tclk_trail = FLD_GET(r, 15, 8); tclk_zero = FLD_GET(r, 7, 0); r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); @@ -4040,7 +4038,6 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel, { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - u16 dw, dh; dsi_perf_mark_setup(dsidev); @@ -4049,11 +4046,8 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel, dsi->framedone_callback = callback; dsi->framedone_data = data; - dw = dsi->timings.x_res; - dh = dsi->timings.y_res; - #ifdef DSI_PERF_MEASURE - dsi->update_bytes = dw * dh * + dsi->update_bytes = dsi->timings.x_res * dsi->timings.y_res * dsi_get_pixel_size(dsi->pix_fmt) / 8; #endif dsi_update_screen_dispc(dsidev); From ab2b29e64e05f2d92dc4a584de7818bc9a1eea4c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:10 +0100 Subject: [PATCH 0180/5577] video: fbdev: s3c-fb: Fix kernel-doc and set but not used warnings Fix several W=1 warnings - Updated kernel-doc as needed - Deleted unused local variable, it was assigned but never used v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Jingoo Han Cc: linux-fbdev@vger.kernel.org Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-25-sam@ravnborg.org --- drivers/video/fbdev/s3c-fb.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c index ba316bd56efd..3b134e1bbc38 100644 --- a/drivers/video/fbdev/s3c-fb.c +++ b/drivers/video/fbdev/s3c-fb.c @@ -75,6 +75,7 @@ struct s3c_fb; * @buf_size: Offset of buffer size registers. * @buf_end: Offset of buffer end registers. * @osd: The base for the OSD registers. + * @osd_stride: stride of osd * @palette: Address of palette memory, or 0 if none. * @has_prtcon: Set if has PRTCON register. * @has_shadowcon: Set if has SHADOWCON register. @@ -155,7 +156,7 @@ struct s3c_fb_palette { * @windata: The platform data supplied for the window configuration. * @parent: The hardware that this window is part of. * @fbinfo: Pointer pack to the framebuffer info for this window. - * @varint: The variant information for this window. + * @variant: The variant information for this window. * @palette_buffer: Buffer/cache to hold palette entries. * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/ * @index: The window number of this window. @@ -336,7 +337,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, /** * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. * @sfb: The hardware state. - * @pixclock: The pixel clock wanted, in picoseconds. + * @pixclk: The pixel clock wanted, in picoseconds. * * Given the specified pixel clock, work out the necessary divider to get * close to the output frequency. @@ -733,7 +734,7 @@ static inline unsigned int chan_to_field(unsigned int chan, * @red: The red field for the palette data. * @green: The green field for the palette data. * @blue: The blue field for the palette data. - * @trans: The transparency (alpha) field for the palette data. + * @transp: The transparency (alpha) field for the palette data. * @info: The framebuffer being changed. */ static int s3c_fb_setcolreg(unsigned regno, @@ -1133,6 +1134,7 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) /** * s3c_fb_release_win() - release resources for a framebuffer window. + * @sfb: The base resources for the hardware. * @win: The window to cleanup the resources for. * * Release the resources that where claimed for the hardware window, @@ -1160,6 +1162,7 @@ static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) /** * s3c_fb_probe_win() - register an hardware window * @sfb: The base resources for the hardware + * @win_no: The window number * @variant: The variant information for this window. * @res: Pointer to where to place the resultant window. * @@ -1170,7 +1173,6 @@ static int s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, struct s3c_fb_win_variant *variant, struct s3c_fb_win **res) { - struct fb_var_screeninfo *var; struct fb_videomode initmode; struct s3c_fb_pd_win *windata; struct s3c_fb_win *win; @@ -1198,7 +1200,6 @@ static int s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, win = fbinfo->par; *res = win; - var = &fbinfo->var; win->variant = *variant; win->fbinfo = fbinfo; win->parent = sfb; From 5a15468b724bbe385bb8531942a715731c241520 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:12 +0100 Subject: [PATCH 0181/5577] video: fbdev: uvesafb: Fix string related warnings Two W=1 string related warnings. - Using strncpy to copy string without null-termination generates a warning. Use memcpy to copy only the relevant chars - Fix a potential bug with a very long string, subtract one from the length to make room for the termination null. Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Michal Januszewski Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-27-sam@ravnborg.org --- drivers/video/fbdev/uvesafb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index def14ac0ebe1..6c9cfab39313 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -423,7 +423,7 @@ static int uvesafb_vbe_getinfo(struct uvesafb_ktask *task, task->t.flags = TF_VBEIB; task->t.buf_len = sizeof(struct vbe_ib); task->buf = &par->vbe_ib; - strncpy(par->vbe_ib.vbe_signature, "VBE2", 4); + memcpy(par->vbe_ib.vbe_signature, "VBE2", 4); err = uvesafb_exec(task); if (err || (task->t.regs.eax & 0xffff) != 0x004f) { @@ -1871,7 +1871,7 @@ static ssize_t v86d_show(struct device_driver *dev, char *buf) static ssize_t v86d_store(struct device_driver *dev, const char *buf, size_t count) { - strncpy(v86d_path, buf, PATH_MAX); + strncpy(v86d_path, buf, PATH_MAX - 1); return count; } static DRIVER_ATTR_RW(v86d); From 630a159a0bf35fdc944c8e9633ed5aef0a6834db Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Nov 2020 23:41:13 +0100 Subject: [PATCH 0182/5577] video: fbdev: cirrusfb: Fix kernel-doc and set but not used warnings Fix warnings: - drop kernel-doc for the two debug functions to avoid the warnings - delete unused code v2: - Updated subject (Lee) Signed-off-by: Sam Ravnborg Acked-by: Thomas Zimmermann Cc: Thomas Zimemrmann Cc: Sam Ravnborg Cc: "Gustavo A. R. Silva" Cc: Daniel Vetter Cc: Saeed Mirzamohammadi Cc: Jani Nikula Cc: Mike Rapoport Cc: Lee Jones Link: https://patchwork.freedesktop.org/patch/msgid/20201128224114.1033617-28-sam@ravnborg.org --- drivers/video/fbdev/cirrusfb.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c index e9027172c0f5..93802abbbc72 100644 --- a/drivers/video/fbdev/cirrusfb.c +++ b/drivers/video/fbdev/cirrusfb.c @@ -2463,8 +2463,6 @@ static void AttrOn(const struct cirrusfb_info *cinfo) */ static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) { - unsigned char dummy; - if (is_laguna(cinfo)) return; if (cinfo->btype == BT_PICASSO) { @@ -2473,18 +2471,18 @@ static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) WGen(cinfo, VGA_PEL_MSK, 0x00); udelay(200); /* next read dummy from pixel address (3c8) */ - dummy = RGen(cinfo, VGA_PEL_IW); + RGen(cinfo, VGA_PEL_IW); udelay(200); } /* now do the usual stuff to access the HDR */ - dummy = RGen(cinfo, VGA_PEL_MSK); + RGen(cinfo, VGA_PEL_MSK); udelay(200); - dummy = RGen(cinfo, VGA_PEL_MSK); + RGen(cinfo, VGA_PEL_MSK); udelay(200); - dummy = RGen(cinfo, VGA_PEL_MSK); + RGen(cinfo, VGA_PEL_MSK); udelay(200); - dummy = RGen(cinfo, VGA_PEL_MSK); + RGen(cinfo, VGA_PEL_MSK); udelay(200); WGen(cinfo, VGA_PEL_MSK, val); @@ -2492,7 +2490,7 @@ static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) if (cinfo->btype == BT_PICASSO) { /* now first reset HDR access counter */ - dummy = RGen(cinfo, VGA_PEL_IW); + RGen(cinfo, VGA_PEL_IW); udelay(200); /* and at the end, restore the mask value */ @@ -2800,9 +2798,9 @@ static void bestclock(long freq, int *nom, int *den, int *div) #ifdef CIRRUSFB_DEBUG -/** +/* * cirrusfb_dbg_print_regs - * @base: If using newmmio, the newmmio base address, otherwise %NULL + * @regbase: If using newmmio, the newmmio base address, otherwise %NULL * @reg_class: type of registers to read: %CRT, or %SEQ * * DESCRIPTION: @@ -2847,7 +2845,7 @@ static void cirrusfb_dbg_print_regs(struct fb_info *info, va_end(list); } -/** +/* * cirrusfb_dbg_reg_dump * @base: If using newmmio, the newmmio base address, otherwise %NULL * From 2abb0b994db569422c79e77208d1c0d560faa57f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 15 Nov 2020 19:51:45 +0100 Subject: [PATCH 0183/5577] dt-bindings: display: mcde: Convert to YAML schema This moves the MCDE bindings over to using the YAML schema to describe the ST-Ericsson MCDE display controller, making use of the generic DSI controller schema. In the process we correct an error in the old text bindings: the clocks for the SDI host controllers were specified as part of the main MCDE component while they should be specified in the DSI host controller subnodes. This was a leftover from an earlier iteration of the first patch series adding the MCDE. We also add the "port" node, we will use this when adding LCD panels using the direct parallel interface DPI instead of DSI. Signed-off-by: Linus Walleij Reviewed-by: Sam Ravnborg Reviewed-by: Rob Herring Cc: devicetree@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20201115185145.566772-1-linus.walleij@linaro.org --- .../devicetree/bindings/display/ste,mcde.txt | 104 ----------- .../devicetree/bindings/display/ste,mcde.yaml | 169 ++++++++++++++++++ 2 files changed, 169 insertions(+), 104 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/ste,mcde.txt create mode 100644 Documentation/devicetree/bindings/display/ste,mcde.yaml diff --git a/Documentation/devicetree/bindings/display/ste,mcde.txt b/Documentation/devicetree/bindings/display/ste,mcde.txt deleted file mode 100644 index 4c33c692bd5f..000000000000 --- a/Documentation/devicetree/bindings/display/ste,mcde.txt +++ /dev/null @@ -1,104 +0,0 @@ -ST-Ericsson Multi Channel Display Engine MCDE - -The ST-Ericsson MCDE is a display controller with support for compositing -and displaying several channels memory resident graphics data on DSI or -LCD displays or bridges. It is used in the ST-Ericsson U8500 platform. - -Required properties: - -- compatible: must be: - "ste,mcde" -- reg: register base for the main MCDE control registers, should be - 0x1000 in size -- interrupts: the interrupt line for the MCDE -- epod-supply: a phandle to the EPOD regulator -- vana-supply: a phandle to the analog voltage regulator -- clocks: an array of the MCDE clocks in this strict order: - MCDECLK (main MCDE clock), LCDCLK (LCD clock), PLLDSI - (HDMI clock), DSI0ESCLK (DSI0 energy save clock), - DSI1ESCLK (DSI1 energy save clock), DSI2ESCLK (DSI2 energy - save clock) -- clock-names: must be the following array: - "mcde", "lcd", "hdmi" - to match the required clock inputs above. -- #address-cells: should be <1> (for the DSI hosts that will be children) -- #size-cells: should be <1> (for the DSI hosts that will be children) -- ranges: this should always be stated - -Required subnodes: - -The devicetree must specify subnodes for the DSI host adapters. -These must have the following characteristics: - -- compatible: must be: - "ste,mcde-dsi" -- reg: must specify the register range for the DSI host -- vana-supply: phandle to the VANA voltage regulator -- clocks: phandles to the high speed and low power (energy save) clocks - the high speed clock is not present on the third (dsi2) block, so it - should only have the "lp" clock -- clock-names: "hs" for the high speed clock and "lp" for the low power - (energy save) clock -- #address-cells: should be <1> -- #size-cells: should be <0> - -Display panels and bridges will appear as children on the DSI hosts, and -the displays are connected to the DSI hosts using the common binding -for video transmitter interfaces; see -Documentation/devicetree/bindings/media/video-interfaces.txt - -If a DSI host is unused (not connected) it will have no children defined. - -Example: - -mcde@a0350000 { - compatible = "ste,mcde"; - reg = <0xa0350000 0x1000>; - interrupts = ; - epod-supply = <&db8500_b2r2_mcde_reg>; - vana-supply = <&ab8500_ldo_ana_reg>; - clocks = <&prcmu_clk PRCMU_MCDECLK>, /* Main MCDE clock */ - <&prcmu_clk PRCMU_LCDCLK>, /* LCD clock */ - <&prcmu_clk PRCMU_PLLDSI>; /* HDMI clock */ - clock-names = "mcde", "lcd", "hdmi"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - dsi0: dsi@a0351000 { - compatible = "ste,mcde-dsi"; - reg = <0xa0351000 0x1000>; - vana-supply = <&ab8500_ldo_ana_reg>; - clocks = <&prcmu_clk PRCMU_DSI0CLK>, <&prcmu_clk PRCMU_DSI0ESCCLK>; - clock-names = "hs", "lp"; - #address-cells = <1>; - #size-cells = <0>; - - panel { - compatible = "samsung,s6d16d0"; - reg = <0>; - vdd1-supply = <&ab8500_ldo_aux1_reg>; - reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; - }; - - }; - dsi1: dsi@a0352000 { - compatible = "ste,mcde-dsi"; - reg = <0xa0352000 0x1000>; - vana-supply = <&ab8500_ldo_ana_reg>; - clocks = <&prcmu_clk PRCMU_DSI1CLK>, <&prcmu_clk PRCMU_DSI1ESCCLK>; - clock-names = "hs", "lp"; - #address-cells = <1>; - #size-cells = <0>; - }; - dsi2: dsi@a0353000 { - compatible = "ste,mcde-dsi"; - reg = <0xa0353000 0x1000>; - vana-supply = <&ab8500_ldo_ana_reg>; - /* This DSI port only has the Low Power / Energy Save clock */ - clocks = <&prcmu_clk PRCMU_DSI2ESCCLK>; - clock-names = "lp"; - #address-cells = <1>; - #size-cells = <0>; - }; -}; diff --git a/Documentation/devicetree/bindings/display/ste,mcde.yaml b/Documentation/devicetree/bindings/display/ste,mcde.yaml new file mode 100644 index 000000000000..830c9b4091cc --- /dev/null +++ b/Documentation/devicetree/bindings/display/ste,mcde.yaml @@ -0,0 +1,169 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/ste,mcde.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ST-Ericsson Multi Channel Display Engine MCDE + +maintainers: + - Linus Walleij + +properties: + compatible: + const: ste,mcde + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + description: an array of the MCDE clocks + items: + - description: MCDECLK (main MCDE clock) + - description: LCDCLK (LCD clock) + - description: PLLDSI (HDMI clock) + + clock-names: + items: + - const: mcde + - const: lcd + - const: hdmi + + resets: + maxItems: 1 + + epod-supply: + description: a phandle to the EPOD regulator + + vana-supply: + description: a phandle to the analog voltage regulator + + port: + type: object + description: + A DPI port node with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + +patternProperties: + "^dsi@[0-9a-f]+$": + description: subnodes for the three DSI host adapters + type: object + allOf: + - $ref: dsi-controller.yaml# + properties: + compatible: + const: ste,mcde-dsi + + reg: + maxItems: 1 + + vana-supply: + description: a phandle to the analog voltage regulator + + clocks: + description: phandles to the high speed and low power (energy save) clocks + the high speed clock is not present on the third (dsi2) block, so it + should only have the "lp" clock + minItems: 1 + maxItems: 2 + + clock-names: + oneOf: + - items: + - const: hs + - const: lp + - items: + - const: lp + + required: + - compatible + - reg + - vana-supply + - clocks + - clock-names + + unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - epod-supply + - vana-supply + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + mcde@a0350000 { + compatible = "ste,mcde"; + reg = <0xa0350000 0x1000>; + interrupts = ; + epod-supply = <&db8500_b2r2_mcde_reg>; + vana-supply = <&ab8500_ldo_ana_reg>; + clocks = <&prcmu_clk PRCMU_MCDECLK>, + <&prcmu_clk PRCMU_LCDCLK>, + <&prcmu_clk PRCMU_PLLDSI>; + clock-names = "mcde", "lcd", "hdmi"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + dsi0: dsi@a0351000 { + compatible = "ste,mcde-dsi"; + reg = <0xa0351000 0x1000>; + vana-supply = <&ab8500_ldo_ana_reg>; + clocks = <&prcmu_clk PRCMU_DSI0CLK>, <&prcmu_clk PRCMU_DSI0ESCCLK>; + clock-names = "hs", "lp"; + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,s6d16d0"; + reg = <0>; + vdd1-supply = <&ab8500_ldo_aux1_reg>; + reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; + }; + }; + + dsi1: dsi@a0352000 { + compatible = "ste,mcde-dsi"; + reg = <0xa0352000 0x1000>; + vana-supply = <&ab8500_ldo_ana_reg>; + clocks = <&prcmu_clk PRCMU_DSI1CLK>, <&prcmu_clk PRCMU_DSI1ESCCLK>; + clock-names = "hs", "lp"; + #address-cells = <1>; + #size-cells = <0>; + }; + + dsi2: dsi@a0353000 { + compatible = "ste,mcde-dsi"; + reg = <0xa0353000 0x1000>; + vana-supply = <&ab8500_ldo_ana_reg>; + /* This DSI port only has the Low Power / Energy Save clock */ + clocks = <&prcmu_clk PRCMU_DSI2ESCCLK>; + clock-names = "lp"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + +... From 47b1adc1d2a3b39233a56e183296b335222c9a6d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 5 Dec 2020 13:22:29 +0100 Subject: [PATCH 0184/5577] drm/panel: s6e63m0: Fix init sequence again The DSI version of the panel behaved instable and close scrutiny of the vendor driver from the Samsung GT-S8190 shows a different initialization sequence for the DSI mode panel than the DPI mode panel. Make the initialization depend on whether we are in DSI or DPI mode and handle the differences. After this the panel on the GT-I8190 becomes much more stable. Also spell out some more custom DCS commands found in the vendor source code to cut down a bit on magic where we can. Fixes: f0aee45ffc8b ("drm/panel: s6e63m0: Fix init sequence") Signed-off-by: Linus Walleij Reviewed-by: Sam Ravnborg Cc: Stephan Gerhold Link: https://patchwork.freedesktop.org/patch/msgid/20201205122229.1952980-1-linus.walleij@linaro.org --- drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c index 6b4e97bfd46e..bf6d704d4d27 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c @@ -25,6 +25,14 @@ /* Manufacturer Command Set */ #define MCS_ELVSS_ON 0xb1 #define MCS_TEMP_SWIRE 0xb2 +#define MCS_PENTILE_1 0xb3 +#define MCS_PENTILE_2 0xb4 +#define MCS_GAMMA_DELTA_Y_RED 0xb5 +#define MCS_GAMMA_DELTA_X_RED 0xb6 +#define MCS_GAMMA_DELTA_Y_GREEN 0xb7 +#define MCS_GAMMA_DELTA_X_GREEN 0xb8 +#define MCS_GAMMA_DELTA_Y_BLUE 0xb9 +#define MCS_GAMMA_DELTA_X_BLUE 0xba #define MCS_MIECTL1 0xc0 #define MCS_BCMODE 0xc1 #define MCS_ERROR_CHECK 0xd5 @@ -281,6 +289,7 @@ struct s6e63m0 { struct backlight_device *bl_dev; u8 lcd_type; u8 elvss_pulse; + bool dsi_mode; struct regulator_bulk_data supplies[2]; struct gpio_desc *reset_gpio; @@ -395,9 +404,21 @@ static int s6e63m0_check_lcd_type(struct s6e63m0 *ctx) static void s6e63m0_init(struct s6e63m0 *ctx) { - s6e63m0_dcs_write_seq_static(ctx, MCS_PANELCTL, - 0x01, 0x27, 0x27, 0x07, 0x07, 0x54, 0x9f, - 0x63, 0x8f, 0x1a, 0x33, 0x0d, 0x00, 0x00); + /* + * We do not know why there is a difference in the DSI mode. + * (No datasheet.) + * + * In the vendor driver this sequence is called + * "SEQ_PANEL_CONDITION_SET" or "DCS_CMD_SEQ_PANEL_COND_SET". + */ + if (ctx->dsi_mode) + s6e63m0_dcs_write_seq_static(ctx, MCS_PANELCTL, + 0x01, 0x2c, 0x2c, 0x07, 0x07, 0x5f, 0xb3, + 0x6d, 0x97, 0x1d, 0x3a, 0x0f, 0x00, 0x00); + else + s6e63m0_dcs_write_seq_static(ctx, MCS_PANELCTL, + 0x01, 0x27, 0x27, 0x07, 0x07, 0x54, 0x9f, + 0x63, 0x8f, 0x1a, 0x33, 0x0d, 0x00, 0x00); s6e63m0_dcs_write_seq_static(ctx, MCS_DISCTL, 0x02, 0x03, 0x1c, 0x10, 0x10); @@ -414,40 +435,40 @@ static void s6e63m0_init(struct s6e63m0 *ctx) s6e63m0_dcs_write_seq_static(ctx, MCS_SRCCTL, 0x00, 0x8e, 0x07); - s6e63m0_dcs_write_seq_static(ctx, 0xb3, 0x6c); + s6e63m0_dcs_write_seq_static(ctx, MCS_PENTILE_1, 0x6c); - s6e63m0_dcs_write_seq_static(ctx, 0xb5, + s6e63m0_dcs_write_seq_static(ctx, MCS_GAMMA_DELTA_Y_RED, 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17, 0x13, 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b, 0x1a, 0x17, 0x2b, 0x26, 0x22, 0x20, 0x3a, 0x34, 0x30, 0x2c, 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1e, 0x1e); - s6e63m0_dcs_write_seq_static(ctx, 0xb6, + s6e63m0_dcs_write_seq_static(ctx, MCS_GAMMA_DELTA_X_RED, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66); - s6e63m0_dcs_write_seq_static(ctx, 0xb7, + s6e63m0_dcs_write_seq_static(ctx, MCS_GAMMA_DELTA_Y_GREEN, 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17, 0x13, 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b, 0x1a, 0x17, 0x2b, 0x26, 0x22, 0x20, 0x3a, 0x34, 0x30, 0x2c, 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1e, 0x1e); - s6e63m0_dcs_write_seq_static(ctx, 0xb8, + s6e63m0_dcs_write_seq_static(ctx, MCS_GAMMA_DELTA_X_GREEN, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66); - s6e63m0_dcs_write_seq_static(ctx, 0xb9, + s6e63m0_dcs_write_seq_static(ctx, MCS_GAMMA_DELTA_Y_BLUE, 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17, 0x13, 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b, 0x1a, 0x17, 0x2b, 0x26, 0x22, 0x20, 0x3a, 0x34, 0x30, 0x2c, 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1e, 0x1e); - s6e63m0_dcs_write_seq_static(ctx, 0xba, + s6e63m0_dcs_write_seq_static(ctx, MCS_GAMMA_DELTA_X_BLUE, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66); @@ -704,6 +725,7 @@ int s6e63m0_probe(struct device *dev, if (!ctx) return -ENOMEM; + ctx->dsi_mode = dsi_mode; ctx->dcs_read = dcs_read; ctx->dcs_write = dcs_write; dev_set_drvdata(dev, ctx); From e2f9b2edf7b5554cfe013d621e295e9b853d545a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Dec 2020 08:46:24 +0100 Subject: [PATCH 0185/5577] drm/vc4: hdmi: Don't poll for the infoframes status on setup The infoframes are sent at a regular interval as a data island packet, so we don't need to wait for them to be sent when we're setting them up. However, we do need to poll when we're enabling since the we can't update the packet RAM until it has been sent. Let's add a boolean flag to tell whether we want to poll or not to support both cases. Suggested-by: Dave Stevenson Signed-off-by: Maxime Ripard Reviewed-by: Dave Stevenson Link: https://patchwork.freedesktop.org/patch/msgid/20201203074624.721559-1-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_hdmi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index b80eb9d3d9d5..ab5da0e4a233 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -219,7 +219,8 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, } static int vc4_hdmi_stop_packet(struct drm_encoder *encoder, - enum hdmi_infoframe_type type) + enum hdmi_infoframe_type type, + bool poll) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); u32 packet_id = type - 0x80; @@ -227,6 +228,9 @@ static int vc4_hdmi_stop_packet(struct drm_encoder *encoder, HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id)); + if (!poll) + return 0; + return wait_for(!(HDMI_READ(HDMI_RAM_PACKET_STATUS) & BIT(packet_id)), 100); } @@ -253,7 +257,7 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, if (len < 0) return; - ret = vc4_hdmi_stop_packet(encoder, frame->any.type); + ret = vc4_hdmi_stop_packet(encoder, frame->any.type, true); if (ret) { DRM_ERROR("Failed to wait for infoframe to go idle: %d\n", ret); return; @@ -893,7 +897,7 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi) int ret; vc4_hdmi->audio.streaming = false; - ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO); + ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO, false); if (ret) dev_err(dev, "Failed to stop audio infoframe: %d\n", ret); From 51f4fcd9c4ea867c3b4fe58111f342ad0e80642a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Dec 2020 14:25:36 +0100 Subject: [PATCH 0186/5577] drm/vc4: drv: Remove the DSI pointer in vc4_drv That pointer isn't used anywhere, so there's no point in keeping it. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-2-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_drv.h | 1 - drivers/gpu/drm/vc4/vc4_dsi.c | 9 --------- 2 files changed, 10 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 137c382256d5..dcafb4cf4b18 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -77,7 +77,6 @@ struct vc4_dev { struct vc4_hvs *hvs; struct vc4_v3d *v3d; struct vc4_dpi *dpi; - struct vc4_dsi *dsi1; struct vc4_vec *vec; struct vc4_txp *txp; diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 19aab4e7e209..b1d8765795f1 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1459,7 +1459,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_dsi *dsi = dev_get_drvdata(dev); struct vc4_dsi_encoder *vc4_dsi_encoder; struct drm_panel *panel; @@ -1612,9 +1611,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - if (dsi->port == 1) - vc4->dsi1 = dsi; - drm_simple_encoder_init(drm, dsi->encoder, DRM_MODE_ENCODER_DSI); drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs); @@ -1643,8 +1639,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) static void vc4_dsi_unbind(struct device *dev, struct device *master, void *data) { - struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_dsi *dsi = dev_get_drvdata(dev); if (dsi->bridge) @@ -1656,9 +1650,6 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master, */ list_splice_init(&dsi->bridge_chain, &dsi->encoder->bridge_chain); drm_encoder_cleanup(dsi->encoder); - - if (dsi->port == 1) - vc4->dsi1 = NULL; } static const struct component_ops vc4_dsi_ops = { From e02d5c43f2fdf7d71935de16e8c91b2cd3139f71 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 3 Dec 2020 14:25:37 +0100 Subject: [PATCH 0187/5577] drm/vc4: dsi: Correct DSI register definition The DSI1_PHY_AFEC0_PD_DLANE1 and DSI1_PHY_AFEC0_PD_DLANE3 register definitions were swapped, so trying to use more than a single data lane failed as lane 1 would get powered down. (In theory a 4 lane device would work as all lanes would remain powered). Correct the definitions. Signed-off-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-3-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index b1d8765795f1..bb316e6cc12b 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -306,11 +306,11 @@ # define DSI0_PHY_AFEC0_RESET BIT(11) # define DSI1_PHY_AFEC0_PD_BG BIT(11) # define DSI0_PHY_AFEC0_PD BIT(10) -# define DSI1_PHY_AFEC0_PD_DLANE3 BIT(10) +# define DSI1_PHY_AFEC0_PD_DLANE1 BIT(10) # define DSI0_PHY_AFEC0_PD_BG BIT(9) # define DSI1_PHY_AFEC0_PD_DLANE2 BIT(9) # define DSI0_PHY_AFEC0_PD_DLANE1 BIT(8) -# define DSI1_PHY_AFEC0_PD_DLANE1 BIT(8) +# define DSI1_PHY_AFEC0_PD_DLANE3 BIT(8) # define DSI_PHY_AFEC0_PTATADJ_MASK VC4_MASK(7, 4) # define DSI_PHY_AFEC0_PTATADJ_SHIFT 4 # define DSI_PHY_AFEC0_CTATADJ_MASK VC4_MASK(3, 0) From dc0bf36401e891c853e0a25baeb4e0b4e6f3626d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Dec 2020 14:25:38 +0100 Subject: [PATCH 0188/5577] drm/vc4: dsi: Use snprintf for the PHY clocks instead of an array The DSI clocks setup function has been using an array to store the clock name of either the DSI0 or DSI1 blocks, using the port ID to choose the proper one. Let's switch to an snprintf call to do the same thing and simplify the array a bit. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-4-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_dsi.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index bb316e6cc12b..f704d959e65b 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1398,12 +1398,12 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) struct device *dev = &dsi->pdev->dev; const char *parent_name = __clk_get_name(dsi->pll_phy_clock); static const struct { - const char *dsi0_name, *dsi1_name; + const char *name; int div; } phy_clocks[] = { - { "dsi0_byte", "dsi1_byte", 8 }, - { "dsi0_ddr2", "dsi1_ddr2", 4 }, - { "dsi0_ddr", "dsi1_ddr", 2 }, + { "byte", 8 }, + { "ddr2", 4 }, + { "ddr", 2 }, }; int i; @@ -1419,8 +1419,12 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) for (i = 0; i < ARRAY_SIZE(phy_clocks); i++) { struct clk_fixed_factor *fix = &dsi->phy_clocks[i]; struct clk_init_data init; + char clk_name[16]; int ret; + snprintf(clk_name, sizeof(clk_name), + "dsi%u_%s", dsi->port, phy_clocks[i].name); + /* We just use core fixed factor clock ops for the PHY * clocks. The clocks are actually gated by the * PHY_AFEC0_DDRCLK_EN bits, which we should be @@ -1437,10 +1441,7 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) memset(&init, 0, sizeof(init)); init.parent_names = &parent_name; init.num_parents = 1; - if (dsi->port == 1) - init.name = phy_clocks[i].dsi1_name; - else - init.name = phy_clocks[i].dsi0_name; + init.name = clk_name; init.ops = &clk_fixed_factor_ops; ret = devm_clk_hw_register(dev, &fix->hw); From d1d195ce26a14ec0a87816c09ae514e1c40e97f7 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Dec 2020 14:25:39 +0100 Subject: [PATCH 0189/5577] drm/vc4: dsi: Introduce a variant structure Most of the differences between DSI0 and DSI1 are handled through the ID. However, the BCM2711 DSI is going to introduce one more variable to the mix and will break some expectations of the earlier, simpler, test. Let's add a variant structure that will address most of the differences between those three controllers. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-5-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_dsi.c | 63 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index f704d959e65b..601020c10053 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -493,6 +493,18 @@ */ #define DSI1_ID 0x8c +struct vc4_dsi_variant { + /* Whether we're on bcm2835's DSI0 or DSI1. */ + unsigned int port; + + bool broken_axi_workaround; + + const char *debugfs_name; + const struct debugfs_reg32 *regs; + size_t nregs; + +}; + /* General DSI hardware state. */ struct vc4_dsi { struct platform_device *pdev; @@ -509,8 +521,7 @@ struct vc4_dsi { u32 *reg_dma_mem; dma_addr_t reg_paddr; - /* Whether we're on bcm2835's DSI0 or DSI1. */ - int port; + const struct vc4_dsi_variant *variant; /* DSI channel for the panel we're connected to. */ u32 channel; @@ -586,10 +597,10 @@ dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val) #define DSI_READ(offset) readl(dsi->regs + (offset)) #define DSI_WRITE(offset, val) dsi_dma_workaround_write(dsi, offset, val) #define DSI_PORT_READ(offset) \ - DSI_READ(dsi->port ? DSI1_##offset : DSI0_##offset) + DSI_READ(dsi->variant->port ? DSI1_##offset : DSI0_##offset) #define DSI_PORT_WRITE(offset, val) \ - DSI_WRITE(dsi->port ? DSI1_##offset : DSI0_##offset, val) -#define DSI_PORT_BIT(bit) (dsi->port ? DSI1_##bit : DSI0_##bit) + DSI_WRITE(dsi->variant->port ? DSI1_##offset : DSI0_##offset, val) +#define DSI_PORT_BIT(bit) (dsi->variant->port ? DSI1_##bit : DSI0_##bit) /* VC4 DSI encoder KMS struct */ struct vc4_dsi_encoder { @@ -837,7 +848,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) ret = pm_runtime_get_sync(dev); if (ret) { - DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->port); + DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->variant->port); return; } @@ -871,7 +882,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) DSI_PORT_WRITE(STAT, DSI_PORT_READ(STAT)); /* Set AFE CTR00/CTR1 to release powerdown of analog. */ - if (dsi->port == 0) { + if (dsi->variant->port == 0) { u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) | VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ)); @@ -1017,7 +1028,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) DSI_PORT_BIT(PHYC_CLANE_ENABLE) | ((dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : DSI_PORT_BIT(PHYC_HS_CLK_CONTINUOUS)) | - (dsi->port == 0 ? + (dsi->variant->port == 0 ? VC4_SET_FIELD(lpx - 1, DSI0_PHYC_ESC_CLK_LPDT) : VC4_SET_FIELD(lpx - 1, DSI1_PHYC_ESC_CLK_LPDT))); @@ -1043,13 +1054,13 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) DSI_DISP1_ENABLE); /* Ungate the block. */ - if (dsi->port == 0) + if (dsi->variant->port == 0) DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI0_CTRL_CTRL0); else DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN); /* Bring AFE out of reset. */ - if (dsi->port == 0) { + if (dsi->variant->port == 0) { } else { DSI_PORT_WRITE(PHY_AFEC0, DSI_PORT_READ(PHY_AFEC0) & @@ -1313,8 +1324,16 @@ static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = { .mode_fixup = vc4_dsi_encoder_mode_fixup, }; +static const struct vc4_dsi_variant bcm2835_dsi1_variant = { + .port = 1, + .broken_axi_workaround = true, + .debugfs_name = "dsi1_regs", + .regs = dsi1_regs, + .nregs = ARRAY_SIZE(dsi1_regs), +}; + static const struct of_device_id vc4_dsi_dt_match[] = { - { .compatible = "brcm,bcm2835-dsi1", (void *)(uintptr_t)1 }, + { .compatible = "brcm,bcm2835-dsi1", &bcm2835_dsi1_variant }, {} }; @@ -1325,7 +1344,7 @@ static void dsi_handle_error(struct vc4_dsi *dsi, if (!(stat & bit)) return; - DRM_ERROR("DSI%d: %s error\n", dsi->port, type); + DRM_ERROR("DSI%d: %s error\n", dsi->variant->port, type); *ret = IRQ_HANDLED; } @@ -1423,7 +1442,7 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) int ret; snprintf(clk_name, sizeof(clk_name), - "dsi%u_%s", dsi->port, phy_clocks[i].name); + "dsi%u_%s", dsi->variant->port, phy_clocks[i].name); /* We just use core fixed factor clock ops for the PHY * clocks. The clocks are actually gated by the @@ -1471,7 +1490,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) if (!match) return -ENODEV; - dsi->port = (uintptr_t)match->data; + dsi->variant = match->data; vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder), GFP_KERNEL); @@ -1488,13 +1507,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) return PTR_ERR(dsi->regs); dsi->regset.base = dsi->regs; - if (dsi->port == 0) { - dsi->regset.regs = dsi0_regs; - dsi->regset.nregs = ARRAY_SIZE(dsi0_regs); - } else { - dsi->regset.regs = dsi1_regs; - dsi->regset.nregs = ARRAY_SIZE(dsi1_regs); - } + dsi->regset.regs = dsi->variant->regs; + dsi->regset.nregs = dsi->variant->nregs; if (DSI_PORT_READ(ID) != DSI_ID_VALUE) { dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n", @@ -1506,7 +1520,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) * from the ARM. It does handle writes from the DMA engine, * so set up a channel for talking to it. */ - if (dsi->port == 1) { + if (dsi->variant->broken_axi_workaround) { dsi->reg_dma_mem = dma_alloc_coherent(dev, 4, &dsi->reg_dma_paddr, GFP_KERNEL); @@ -1627,10 +1641,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) */ list_splice_init(&dsi->encoder->bridge_chain, &dsi->bridge_chain); - if (dsi->port == 0) - vc4_debugfs_add_regset32(drm, "dsi0_regs", &dsi->regset); - else - vc4_debugfs_add_regset32(drm, "dsi1_regs", &dsi->regset); + vc4_debugfs_add_regset32(drm, dsi->variant->debugfs_name, &dsi->regset); pm_runtime_enable(dev); From 4b265fe11fad4234b12d92dd8091f9aa0c878eea Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 3 Dec 2020 14:25:40 +0100 Subject: [PATCH 0190/5577] drm/vc4: dsi: Add support for DSI0 DSI0 was partially supported, but didn't register with the main driver, and the code was inconsistent as to whether it checked port == 0 or port == 1. Add compatible string and other support to make it consistent. Signed-off-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-6-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_dsi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 601020c10053..82162900e351 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1324,6 +1324,13 @@ static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = { .mode_fixup = vc4_dsi_encoder_mode_fixup, }; +static const struct vc4_dsi_variant bcm2835_dsi0_variant = { + .port = 0, + .debugfs_name = "dsi0_regs", + .regs = dsi0_regs, + .nregs = ARRAY_SIZE(dsi0_regs), +}; + static const struct vc4_dsi_variant bcm2835_dsi1_variant = { .port = 1, .broken_axi_workaround = true, @@ -1333,6 +1340,7 @@ static const struct vc4_dsi_variant bcm2835_dsi1_variant = { }; static const struct of_device_id vc4_dsi_dt_match[] = { + { .compatible = "brcm,bcm2835-dsi0", &bcm2835_dsi0_variant }, { .compatible = "brcm,bcm2835-dsi1", &bcm2835_dsi1_variant }, {} }; From 00aedfa4592d93ed7a6d54ffa7f5e22efb9d9147 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 3 Dec 2020 14:25:41 +0100 Subject: [PATCH 0191/5577] dt-bindings: Add compatible for BCM2711 DSI1 DSI1 on BCM2711 doesn't require the DMA workaround that is used on BCM2835/6/7, therefore it needs a new compatible string. Signed-off-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-7-maxime@cerno.tech --- Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml index eb44e072b6e5..55c60919991f 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml @@ -18,6 +18,7 @@ properties: compatible: enum: + - brcm,bcm2711-dsi1 - brcm,bcm2835-dsi0 - brcm,bcm2835-dsi1 From d0666be8ef9e8e65d4b7fabc1606ec51f61384c0 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 3 Dec 2020 14:25:42 +0100 Subject: [PATCH 0192/5577] drm/vc4: dsi: Add configuration for BCM2711 DSI1 BCM2711 DSI1 doesn't have the issue with the ARM not being able to write to the registers, therefore remove the DMA workaround for that compatible string. Signed-off-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201203132543.861591-8-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_dsi.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 82162900e351..a55256ed0955 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1324,6 +1324,13 @@ static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = { .mode_fixup = vc4_dsi_encoder_mode_fixup, }; +static const struct vc4_dsi_variant bcm2711_dsi1_variant = { + .port = 1, + .debugfs_name = "dsi1_regs", + .regs = dsi1_regs, + .nregs = ARRAY_SIZE(dsi1_regs), +}; + static const struct vc4_dsi_variant bcm2835_dsi0_variant = { .port = 0, .debugfs_name = "dsi0_regs", @@ -1340,6 +1347,7 @@ static const struct vc4_dsi_variant bcm2835_dsi1_variant = { }; static const struct of_device_id vc4_dsi_dt_match[] = { + { .compatible = "brcm,bcm2711-dsi1", &bcm2711_dsi1_variant }, { .compatible = "brcm,bcm2835-dsi0", &bcm2835_dsi0_variant }, { .compatible = "brcm,bcm2835-dsi1", &bcm2835_dsi1_variant }, {} @@ -1524,8 +1532,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) return -ENODEV; } - /* DSI1 has a broken AXI slave that doesn't respond to writes - * from the ARM. It does handle writes from the DMA engine, + /* DSI1 on BCM2835/6/7 has a broken AXI slave that doesn't respond to + * writes from the ARM. It does handle writes from the DMA engine, * so set up a channel for talking to it. */ if (dsi->variant->broken_axi_workaround) { From e70956a2498dc81d8f2522cba074f55ae910e13c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 2 Oct 2020 18:03:54 +0100 Subject: [PATCH 0193/5577] drm/i915: fix size_t greater or equal to zero comparison Currently the check that the unsigned size_t variable i is >= 0 is always true because the unsigned variable will never be negative, causing the loop to run forever. Fix this by changing the pre-decrement check to a zero check on i followed by a decrement of i. Addresses-Coverity: ("Unsigned compared against 0") Fixes: bfed6708d6c9 ("drm/i915: use vmap in shmem_pin_map") Signed-off-by: Colin Ian King Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20201002170354.94627-1-colin.king@canonical.com --- drivers/gpu/drm/i915/gt/shmem_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c index 463af675fadd..5982b62f913d 100644 --- a/drivers/gpu/drm/i915/gt/shmem_utils.c +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c @@ -73,7 +73,7 @@ void *shmem_pin_map(struct file *file) mapping_set_unevictable(file->f_mapping); return vaddr; err_page: - while (--i >= 0) + while (i--) put_page(pages[i]); kvfree(pages); return NULL; From 98cda4b5f246c86ddbd7c4c084a15829da6c8f81 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 4 Dec 2020 09:19:48 +0100 Subject: [PATCH 0194/5577] dt-bindings: panel-simple-dsi: add Khadas TS050 panel bindings This add the bindings for the Khadas TS050 1080x1920 5" LCD DSI panel designed to work with the Khadas Edge-V, Captain, VIM3 and VIM3L Single Board Computers. Signed-off-by: Neil Armstrong Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201204081949.38418-2-narmstrong@baylibre.com --- .../devicetree/bindings/display/panel/panel-simple-dsi.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml index 72e4b6d4d5e1..fbd71669248f 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml @@ -35,6 +35,8 @@ properties: - boe,tv080wum-nl0 # Innolux P079ZCA 7.85" 768x1024 TFT LCD panel - innolux,p079zca + # Khadas TS050 5" 1080x1920 LCD panel + - khadas,ts050 # Kingdisplay KD097D04 9.7" 1536x2048 TFT LCD panel - kingdisplay,kd097d04 # LG ACX467AKM-7 4.95" 1080×1920 LCD Panel From b215212117f73bc6426d71ee344ef6cc88947916 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 4 Dec 2020 09:19:49 +0100 Subject: [PATCH 0195/5577] drm: panel: add Khadas TS050 panel driver This add support for the Khadas TS050 1080x1920 5" LCD DSI panel designed to work with the Khadas Edge-V, Captain, VIM3 and VIM3L Single Board Computers. It provides a MIPI DSI interface to the host, a built-in LED backlight and touch controller. The init values was taken from the vendor source tree, comments were added to the know values but most of the init table is undocumented. Signed-off-by: Neil Armstrong Reviewed-by: Sam Ravnborg [narmstrong: call drm_panel_remove if mipi_dsi_attach fails] Link: https://patchwork.freedesktop.org/patch/msgid/20201204081949.38418-3-narmstrong@baylibre.com --- drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-khadas-ts050.c | 870 +++++++++++++++++++++ 3 files changed, 882 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-khadas-ts050.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index b4e021ea30f9..8fec45b2ce02 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -145,6 +145,17 @@ config DRM_PANEL_JDI_LT070ME05000 The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses 24 bit per pixel. +config DRM_PANEL_KHADAS_TS050 + tristate "Khadas TS050 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for Khadas TS050 TFT-LCD + panel module. The panel has a 1080x1920 resolution and uses + 24 bit RGB per pixel. It provides a MIPI DSI interface to + the host, a built-in LED backlight and touch controller. + config DRM_PANEL_KINGDISPLAY_KD097D04 tristate "Kingdisplay kd097d04 panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index ebbf488c7eac..03496695e03f 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o +obj-$(CONFIG_DRM_PANEL_KHADAS_TS050) += panel-khadas-ts050.o obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c b/drivers/gpu/drm/panel/panel-khadas-ts050.c new file mode 100644 index 000000000000..87aa2cc8ec2a --- /dev/null +++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c @@ -0,0 +1,870 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 BayLibre, SAS + * Author: Neil Armstrong + */ + +#include +#include +#include +#include +#include + +#include