mirror of https://gitee.com/openkylin/linux.git
Merge branches 'acpica', 'acpi-tpm' and 'acpi-processor'
* acpica: ACPICA: Tables: Restore old behavor to favor 32-bit FADT addresses. ACPICA: Tables: Fix invalid pointer accesses in acpi_tb_parse_root_table(). * acpi-tpm: ACPI / TPM: Fix resume regression on Chromebooks * acpi-processor: ACPI / processor: do not mark present at boot but not onlined CPU as onlined
This commit is contained in:
commit
7d18aecd39
|
@ -4,11 +4,15 @@ Required properties:
|
|||
- compatible: Should be "snps,arc-emac"
|
||||
- reg: Address and length of the register set for the device
|
||||
- interrupts: Should contain the EMAC interrupts
|
||||
- clock-frequency: CPU frequency. It is needed to calculate and set polling
|
||||
period of EMAC.
|
||||
- max-speed: see ethernet.txt file in the same directory.
|
||||
- phy: see ethernet.txt file in the same directory.
|
||||
|
||||
Clock handling:
|
||||
The clock frequency is needed to calculate and set polling period of EMAC.
|
||||
It must be provided by one of:
|
||||
- clock-frequency: CPU frequency.
|
||||
- clocks: reference to the clock supplying the EMAC.
|
||||
|
||||
Child nodes of the driver are the individual PHY devices connected to the
|
||||
MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus.
|
||||
|
||||
|
@ -19,7 +23,11 @@ Examples:
|
|||
reg = <0xc0fc2000 0x3c>;
|
||||
interrupts = <6>;
|
||||
mac-address = [ 00 11 22 33 44 55 ];
|
||||
|
||||
clock-frequency = <80000000>;
|
||||
/* or */
|
||||
clocks = <&emac_clock>;
|
||||
|
||||
max-speed = <100>;
|
||||
phy = <&phy0>;
|
||||
|
||||
|
|
|
@ -504,9 +504,12 @@ byte 5:
|
|||
* reg_10
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 0 0 0 0 0 0 A
|
||||
0 0 0 0 R F T A
|
||||
|
||||
A: 1 = enable absolute tracking
|
||||
T: 1 = enable two finger mode auto correct
|
||||
F: 1 = disable ABS Position Filter
|
||||
R: 1 = enable real hardware resolution
|
||||
|
||||
6.2 Native absolute mode 6 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -429,7 +429,7 @@ RPS and RFS were introduced in kernel 2.6.35. XPS was incorporated into
|
|||
(therbert@google.com)
|
||||
|
||||
Accelerated RFS was introduced in 2.6.35. Original patches were
|
||||
submitted by Ben Hutchings (bhutchings@solarflare.com)
|
||||
submitted by Ben Hutchings (bwh@kernel.org)
|
||||
|
||||
Authors:
|
||||
Tom Herbert (therbert@google.com)
|
||||
|
|
|
@ -7288,7 +7288,6 @@ F: drivers/video/aty/aty128fb.c
|
|||
RALINK RT2X00 WIRELESS LAN DRIVER
|
||||
P: rt2x00 project
|
||||
M: Ivo van Doorn <IvDoorn@gmail.com>
|
||||
M: Gertjan van Wingerde <gwingerde@gmail.com>
|
||||
M: Helmut Schaa <helmut.schaa@googlemail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: users@rt2x00.serialmonkey.com (moderated for non-subscribers)
|
||||
|
@ -7304,7 +7303,7 @@ F: Documentation/blockdev/ramdisk.txt
|
|||
F: drivers/block/brd.c
|
||||
|
||||
RANDOM NUMBER DRIVER
|
||||
M: Theodore Ts'o" <tytso@mit.edu>
|
||||
M: "Theodore Ts'o" <tytso@mit.edu>
|
||||
S: Maintained
|
||||
F: drivers/char/random.c
|
||||
|
||||
|
@ -7685,7 +7684,6 @@ F: drivers/clk/samsung/
|
|||
SAMSUNG SXGBE DRIVERS
|
||||
M: Byungho An <bh74.an@samsung.com>
|
||||
M: Girish K S <ks.giri@samsung.com>
|
||||
M: Siva Reddy Kallam <siva.kallam@samsung.com>
|
||||
M: Vipul Pandya <vipul.pandya@samsung.com>
|
||||
S: Supported
|
||||
L: netdev@vger.kernel.org
|
||||
|
@ -9962,7 +9960,7 @@ F: drivers/net/hamradio/*scc.c
|
|||
F: drivers/net/hamradio/z8530.h
|
||||
|
||||
ZBUD COMPRESSED PAGE ALLOCATOR
|
||||
M: Seth Jennings <sjenning@linux.vnet.ibm.com>
|
||||
M: Seth Jennings <sjennings@variantweb.net>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: mm/zbud.c
|
||||
|
@ -10007,7 +10005,7 @@ F: mm/zsmalloc.c
|
|||
F: include/linux/zsmalloc.h
|
||||
|
||||
ZSWAP COMPRESSED SWAP CACHING
|
||||
M: Seth Jennings <sjenning@linux.vnet.ibm.com>
|
||||
M: Seth Jennings <sjennings@variantweb.net>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: mm/zswap.c
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Shuffling Zombie Juror
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -71,6 +71,23 @@
|
|||
|
||||
#include <linux/sched.h>
|
||||
|
||||
extern unsigned long sparc64_valid_addr_bitmap[];
|
||||
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
static inline bool __kern_addr_valid(unsigned long paddr)
|
||||
{
|
||||
if ((paddr >> MAX_PHYS_ADDRESS_BITS) != 0UL)
|
||||
return false;
|
||||
return test_bit(paddr >> ILOG2_4MB, sparc64_valid_addr_bitmap);
|
||||
}
|
||||
|
||||
static inline bool kern_addr_valid(unsigned long addr)
|
||||
{
|
||||
unsigned long paddr = __pa(addr);
|
||||
|
||||
return __kern_addr_valid(paddr);
|
||||
}
|
||||
|
||||
/* Entries per page directory level. */
|
||||
#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3))
|
||||
#define PTRS_PER_PMD (1UL << PMD_BITS)
|
||||
|
@ -79,9 +96,12 @@
|
|||
/* Kernel has a separate 44bit address space. */
|
||||
#define FIRST_USER_ADDRESS 0
|
||||
|
||||
#define pte_ERROR(e) __builtin_trap()
|
||||
#define pmd_ERROR(e) __builtin_trap()
|
||||
#define pgd_ERROR(e) __builtin_trap()
|
||||
#define pmd_ERROR(e) \
|
||||
pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \
|
||||
__FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0))
|
||||
#define pgd_ERROR(e) \
|
||||
pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \
|
||||
__FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0))
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
|
@ -258,8 +278,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
|
|||
{
|
||||
unsigned long mask, tmp;
|
||||
|
||||
/* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347)
|
||||
* SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8)
|
||||
/* SUN4U: 0x630107ffffffec38 (negated == 0x9cfef800000013c7)
|
||||
* SUN4V: 0x33ffffffffffee07 (negated == 0xcc000000000011f8)
|
||||
*
|
||||
* Even if we use negation tricks the result is still a 6
|
||||
* instruction sequence, so don't try to play fancy and just
|
||||
|
@ -289,10 +309,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
|
|||
" .previous\n"
|
||||
: "=r" (mask), "=r" (tmp)
|
||||
: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
|
||||
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
|
||||
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
|
||||
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
|
||||
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
|
||||
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
|
||||
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V |
|
||||
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));
|
||||
|
||||
return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
|
||||
|
@ -633,7 +653,7 @@ static inline unsigned long pmd_large(pmd_t pmd)
|
|||
{
|
||||
pte_t pte = __pte(pmd_val(pmd));
|
||||
|
||||
return (pte_val(pte) & _PAGE_PMD_HUGE) && pte_present(pte);
|
||||
return pte_val(pte) & _PAGE_PMD_HUGE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
|
@ -719,20 +739,6 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd)
|
|||
return __pmd(pte_val(pte));
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
||||
{
|
||||
unsigned long mask;
|
||||
|
||||
if (tlb_type == hypervisor)
|
||||
mask = _PAGE_PRESENT_4V;
|
||||
else
|
||||
mask = _PAGE_PRESENT_4U;
|
||||
|
||||
pmd_val(pmd) &= ~mask;
|
||||
|
||||
return pmd;
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_mksplitting(pmd_t pmd)
|
||||
{
|
||||
pte_t pte = __pte(pmd_val(pmd));
|
||||
|
@ -757,6 +763,20 @@ static inline int pmd_present(pmd_t pmd)
|
|||
|
||||
#define pmd_none(pmd) (!pmd_val(pmd))
|
||||
|
||||
/* pmd_bad() is only called on non-trans-huge PMDs. Our encoding is
|
||||
* very simple, it's just the physical address. PTE tables are of
|
||||
* size PAGE_SIZE so make sure the sub-PAGE_SIZE bits are clear and
|
||||
* the top bits outside of the range of any physical address size we
|
||||
* support are clear as well. We also validate the physical itself.
|
||||
*/
|
||||
#define pmd_bad(pmd) ((pmd_val(pmd) & ~PAGE_MASK) || \
|
||||
!__kern_addr_valid(pmd_val(pmd)))
|
||||
|
||||
#define pud_none(pud) (!pud_val(pud))
|
||||
|
||||
#define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \
|
||||
!__kern_addr_valid(pud_val(pud)))
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
||||
pmd_t *pmdp, pmd_t pmd);
|
||||
|
@ -790,10 +810,7 @@ static inline unsigned long __pmd_page(pmd_t pmd)
|
|||
#define pud_page_vaddr(pud) \
|
||||
((unsigned long) __va(pud_val(pud)))
|
||||
#define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud))
|
||||
#define pmd_bad(pmd) (0)
|
||||
#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
|
||||
#define pud_none(pud) (!pud_val(pud))
|
||||
#define pud_bad(pud) (0)
|
||||
#define pud_present(pud) (pud_val(pud) != 0U)
|
||||
#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
|
||||
|
||||
|
@ -893,6 +910,10 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
|
|||
extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
|
||||
pmd_t *pmd);
|
||||
|
||||
#define __HAVE_ARCH_PMDP_INVALIDATE
|
||||
extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
|
||||
pmd_t *pmdp);
|
||||
|
||||
#define __HAVE_ARCH_PGTABLE_DEPOSIT
|
||||
extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
|
||||
pgtable_t pgtable);
|
||||
|
@ -919,18 +940,6 @@ extern unsigned long pte_file(pte_t);
|
|||
extern pte_t pgoff_to_pte(unsigned long);
|
||||
#define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL)
|
||||
|
||||
extern unsigned long sparc64_valid_addr_bitmap[];
|
||||
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
static inline bool kern_addr_valid(unsigned long addr)
|
||||
{
|
||||
unsigned long paddr = __pa(addr);
|
||||
|
||||
if ((paddr >> 41UL) != 0UL)
|
||||
return false;
|
||||
return test_bit(paddr >> 22, sparc64_valid_addr_bitmap);
|
||||
}
|
||||
|
||||
extern int page_in_phys_avail(unsigned long paddr);
|
||||
|
||||
/*
|
||||
|
|
|
@ -171,7 +171,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
|
|||
andcc REG1, REG2, %g0; \
|
||||
be,pt %xcc, 700f; \
|
||||
sethi %hi(4 * 1024 * 1024), REG2; \
|
||||
andn REG1, REG2, REG1; \
|
||||
brgez,pn REG1, FAIL_LABEL; \
|
||||
andn REG1, REG2, REG1; \
|
||||
and VADDR, REG2, REG2; \
|
||||
brlz,pt REG1, PTE_LABEL; \
|
||||
or REG1, REG2, REG1; \
|
||||
|
|
|
@ -282,8 +282,8 @@ sun4v_chip_type:
|
|||
stx %l2, [%l4 + 0x0]
|
||||
ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low
|
||||
/* 4MB align */
|
||||
srlx %l3, 22, %l3
|
||||
sllx %l3, 22, %l3
|
||||
srlx %l3, ILOG2_4MB, %l3
|
||||
sllx %l3, ILOG2_4MB, %l3
|
||||
stx %l3, [%l4 + 0x8]
|
||||
|
||||
/* Leave service as-is, "call-method" */
|
||||
|
|
|
@ -277,7 +277,7 @@ kvmap_dtlb_load:
|
|||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||
kvmap_vmemmap:
|
||||
sub %g4, %g5, %g5
|
||||
srlx %g5, 22, %g5
|
||||
srlx %g5, ILOG2_4MB, %g5
|
||||
sethi %hi(vmemmap_table), %g1
|
||||
sllx %g5, 3, %g5
|
||||
or %g1, %lo(vmemmap_table), %g1
|
||||
|
|
|
@ -68,27 +68,16 @@ EXPORT_SYMBOL(touch_nmi_watchdog);
|
|||
|
||||
static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
|
||||
{
|
||||
int this_cpu = smp_processor_id();
|
||||
|
||||
if (notify_die(DIE_NMIWATCHDOG, str, regs, 0,
|
||||
pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
|
||||
return;
|
||||
|
||||
console_verbose();
|
||||
bust_spinlocks(1);
|
||||
|
||||
printk(KERN_EMERG "%s", str);
|
||||
printk(" on CPU%d, ip %08lx, registers:\n",
|
||||
smp_processor_id(), regs->tpc);
|
||||
show_regs(regs);
|
||||
dump_stack();
|
||||
|
||||
bust_spinlocks(0);
|
||||
|
||||
if (do_panic || panic_on_oops)
|
||||
panic("Non maskable interrupt");
|
||||
|
||||
nmi_exit();
|
||||
local_irq_enable();
|
||||
do_exit(SIGBUS);
|
||||
panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu);
|
||||
else
|
||||
WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu);
|
||||
}
|
||||
|
||||
notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
||||
|
|
|
@ -149,7 +149,7 @@ void cpu_panic(void)
|
|||
#define NUM_ROUNDS 64 /* magic value */
|
||||
#define NUM_ITERS 5 /* likewise */
|
||||
|
||||
static DEFINE_SPINLOCK(itc_sync_lock);
|
||||
static DEFINE_RAW_SPINLOCK(itc_sync_lock);
|
||||
static unsigned long go[SLAVE + 1];
|
||||
|
||||
#define DEBUG_TICK_SYNC 0
|
||||
|
@ -257,7 +257,7 @@ static void smp_synchronize_one_tick(int cpu)
|
|||
go[MASTER] = 0;
|
||||
membar_safe("#StoreLoad");
|
||||
|
||||
spin_lock_irqsave(&itc_sync_lock, flags);
|
||||
raw_spin_lock_irqsave(&itc_sync_lock, flags);
|
||||
{
|
||||
for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) {
|
||||
while (!go[MASTER])
|
||||
|
@ -268,7 +268,7 @@ static void smp_synchronize_one_tick(int cpu)
|
|||
membar_safe("#StoreLoad");
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&itc_sync_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&itc_sync_lock, flags);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
|
||||
|
|
|
@ -44,7 +44,7 @@ SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1)
|
|||
SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
|
||||
SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
|
||||
SIGN1(sys32_select, compat_sys_select, %o0)
|
||||
SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
|
||||
SIGN1(sys32_futex, compat_sys_futex, %o1)
|
||||
SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
|
||||
SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0)
|
||||
SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0)
|
||||
|
|
|
@ -166,17 +166,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
|
|||
unsigned long compute_effective_address(struct pt_regs *regs,
|
||||
unsigned int insn, unsigned int rd)
|
||||
{
|
||||
int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
|
||||
unsigned int rs1 = (insn >> 14) & 0x1f;
|
||||
unsigned int rs2 = insn & 0x1f;
|
||||
int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
|
||||
unsigned long addr;
|
||||
|
||||
if (insn & 0x2000) {
|
||||
maybe_flush_windows(rs1, 0, rd, from_kernel);
|
||||
return (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
|
||||
addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
|
||||
} else {
|
||||
maybe_flush_windows(rs1, rs2, rd, from_kernel);
|
||||
return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
|
||||
addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
|
||||
}
|
||||
|
||||
if (!from_kernel && test_thread_flag(TIF_32BIT))
|
||||
addr &= 0xffffffff;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* This is just to make gcc think die_if_kernel does return... */
|
||||
|
|
|
@ -96,38 +96,51 @@ static unsigned int get_user_insn(unsigned long tpc)
|
|||
pte_t *ptep, pte;
|
||||
unsigned long pa;
|
||||
u32 insn = 0;
|
||||
unsigned long pstate;
|
||||
|
||||
if (pgd_none(*pgdp))
|
||||
goto outret;
|
||||
if (pgd_none(*pgdp) || unlikely(pgd_bad(*pgdp)))
|
||||
goto out;
|
||||
pudp = pud_offset(pgdp, tpc);
|
||||
if (pud_none(*pudp))
|
||||
goto outret;
|
||||
pmdp = pmd_offset(pudp, tpc);
|
||||
if (pmd_none(*pmdp))
|
||||
goto outret;
|
||||
|
||||
/* This disables preemption for us as well. */
|
||||
__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
|
||||
__asm__ __volatile__("wrpr %0, %1, %%pstate"
|
||||
: : "r" (pstate), "i" (PSTATE_IE));
|
||||
ptep = pte_offset_map(pmdp, tpc);
|
||||
pte = *ptep;
|
||||
if (!pte_present(pte))
|
||||
if (pud_none(*pudp) || unlikely(pud_bad(*pudp)))
|
||||
goto out;
|
||||
|
||||
pa = (pte_pfn(pte) << PAGE_SHIFT);
|
||||
pa += (tpc & ~PAGE_MASK);
|
||||
/* This disables preemption for us as well. */
|
||||
local_irq_disable();
|
||||
|
||||
/* Use phys bypass so we don't pollute dtlb/dcache. */
|
||||
__asm__ __volatile__("lduwa [%1] %2, %0"
|
||||
: "=r" (insn)
|
||||
: "r" (pa), "i" (ASI_PHYS_USE_EC));
|
||||
pmdp = pmd_offset(pudp, tpc);
|
||||
if (pmd_none(*pmdp) || unlikely(pmd_bad(*pmdp)))
|
||||
goto out_irq_enable;
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
if (pmd_trans_huge(*pmdp)) {
|
||||
if (pmd_trans_splitting(*pmdp))
|
||||
goto out_irq_enable;
|
||||
|
||||
pa = pmd_pfn(*pmdp) << PAGE_SHIFT;
|
||||
pa += tpc & ~HPAGE_MASK;
|
||||
|
||||
/* Use phys bypass so we don't pollute dtlb/dcache. */
|
||||
__asm__ __volatile__("lduwa [%1] %2, %0"
|
||||
: "=r" (insn)
|
||||
: "r" (pa), "i" (ASI_PHYS_USE_EC));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ptep = pte_offset_map(pmdp, tpc);
|
||||
pte = *ptep;
|
||||
if (pte_present(pte)) {
|
||||
pa = (pte_pfn(pte) << PAGE_SHIFT);
|
||||
pa += (tpc & ~PAGE_MASK);
|
||||
|
||||
/* Use phys bypass so we don't pollute dtlb/dcache. */
|
||||
__asm__ __volatile__("lduwa [%1] %2, %0"
|
||||
: "=r" (insn)
|
||||
: "r" (pa), "i" (ASI_PHYS_USE_EC));
|
||||
}
|
||||
pte_unmap(ptep);
|
||||
}
|
||||
out_irq_enable:
|
||||
local_irq_enable();
|
||||
out:
|
||||
pte_unmap(ptep);
|
||||
__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
|
||||
outret:
|
||||
return insn;
|
||||
}
|
||||
|
||||
|
@ -153,7 +166,8 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
|
|||
}
|
||||
|
||||
static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
|
||||
unsigned int insn, int fault_code)
|
||||
unsigned long fault_addr, unsigned int insn,
|
||||
int fault_code)
|
||||
{
|
||||
unsigned long addr;
|
||||
siginfo_t info;
|
||||
|
@ -161,10 +175,18 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
|
|||
info.si_code = code;
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
if (fault_code & FAULT_CODE_ITLB)
|
||||
if (fault_code & FAULT_CODE_ITLB) {
|
||||
addr = regs->tpc;
|
||||
else
|
||||
addr = compute_effective_address(regs, insn, 0);
|
||||
} else {
|
||||
/* If we were able to probe the faulting instruction, use it
|
||||
* to compute a precise fault address. Otherwise use the fault
|
||||
* time provided address which may only have page granularity.
|
||||
*/
|
||||
if (insn)
|
||||
addr = compute_effective_address(regs, insn, 0);
|
||||
else
|
||||
addr = fault_addr;
|
||||
}
|
||||
info.si_addr = (void __user *) addr;
|
||||
info.si_trapno = 0;
|
||||
|
||||
|
@ -239,7 +261,7 @@ static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code,
|
|||
/* The si_code was set to make clear whether
|
||||
* this was a SEGV_MAPERR or SEGV_ACCERR fault.
|
||||
*/
|
||||
do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code);
|
||||
do_fault_siginfo(si_code, SIGSEGV, regs, address, insn, fault_code);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -525,7 +547,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
|
|||
* Send a sigbus, regardless of whether we were in kernel
|
||||
* or user mode.
|
||||
*/
|
||||
do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code);
|
||||
do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, address, insn, fault_code);
|
||||
|
||||
/* Kernel mode? Handle exceptions or die */
|
||||
if (regs->tstate & TSTATE_PRIV)
|
||||
|
|
|
@ -73,7 +73,7 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
|
|||
struct page *head, *page, *tail;
|
||||
int refs;
|
||||
|
||||
if (!pmd_large(pmd))
|
||||
if (!(pmd_val(pmd) & _PAGE_VALID))
|
||||
return 0;
|
||||
|
||||
if (write && !pmd_write(pmd))
|
||||
|
|
|
@ -588,7 +588,7 @@ static void __init remap_kernel(void)
|
|||
int i, tlb_ent = sparc64_highest_locked_tlbent();
|
||||
|
||||
tte_vaddr = (unsigned long) KERNBASE;
|
||||
phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
|
||||
phys_page = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB;
|
||||
tte_data = kern_large_tte(phys_page);
|
||||
|
||||
kern_locked_tte_data = tte_data;
|
||||
|
@ -1881,7 +1881,7 @@ void __init paging_init(void)
|
|||
|
||||
BUILD_BUG_ON(NR_CPUS > 4096);
|
||||
|
||||
kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
|
||||
kern_base = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB;
|
||||
kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
|
||||
|
||||
/* Invalidate both kernel TSBs. */
|
||||
|
@ -1937,7 +1937,7 @@ void __init paging_init(void)
|
|||
shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE);
|
||||
|
||||
real_end = (unsigned long)_end;
|
||||
num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << 22);
|
||||
num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << ILOG2_4MB);
|
||||
printk("Kernel: Using %d locked TLB entries for main kernel image.\n",
|
||||
num_kernel_image_mappings);
|
||||
|
||||
|
@ -2094,7 +2094,7 @@ static void __init setup_valid_addr_bitmap_from_pavail(unsigned long *bitmap)
|
|||
|
||||
if (new_start <= old_start &&
|
||||
new_end >= (old_start + PAGE_SIZE)) {
|
||||
set_bit(old_start >> 22, bitmap);
|
||||
set_bit(old_start >> ILOG2_4MB, bitmap);
|
||||
goto do_next_page;
|
||||
}
|
||||
}
|
||||
|
@ -2143,7 +2143,7 @@ void __init mem_init(void)
|
|||
addr = PAGE_OFFSET + kern_base;
|
||||
last = PAGE_ALIGN(kern_size) + addr;
|
||||
while (addr < last) {
|
||||
set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap);
|
||||
set_bit(__pa(addr) >> ILOG2_4MB, sparc64_valid_addr_bitmap);
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
@ -2267,7 +2267,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
|
|||
void *block;
|
||||
|
||||
if (!(*vmem_pp & _PAGE_VALID)) {
|
||||
block = vmemmap_alloc_block(1UL << 22, node);
|
||||
block = vmemmap_alloc_block(1UL << ILOG2_4MB, node);
|
||||
if (!block)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
|
|||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
|
||||
pmd_t pmd, bool exec)
|
||||
pmd_t pmd)
|
||||
{
|
||||
unsigned long end;
|
||||
pte_t *pte;
|
||||
|
@ -142,8 +142,11 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
|
|||
pte = pte_offset_map(&pmd, vaddr);
|
||||
end = vaddr + HPAGE_SIZE;
|
||||
while (vaddr < end) {
|
||||
if (pte_val(*pte) & _PAGE_VALID)
|
||||
if (pte_val(*pte) & _PAGE_VALID) {
|
||||
bool exec = pte_exec(*pte);
|
||||
|
||||
tlb_batch_add_one(mm, vaddr, exec);
|
||||
}
|
||||
pte++;
|
||||
vaddr += PAGE_SIZE;
|
||||
}
|
||||
|
@ -177,19 +180,30 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
|||
}
|
||||
|
||||
if (!pmd_none(orig)) {
|
||||
pte_t orig_pte = __pte(pmd_val(orig));
|
||||
bool exec = pte_exec(orig_pte);
|
||||
|
||||
addr &= HPAGE_MASK;
|
||||
if (pmd_trans_huge(orig)) {
|
||||
pte_t orig_pte = __pte(pmd_val(orig));
|
||||
bool exec = pte_exec(orig_pte);
|
||||
|
||||
tlb_batch_add_one(mm, addr, exec);
|
||||
tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
|
||||
} else {
|
||||
tlb_batch_pmd_scan(mm, addr, orig, exec);
|
||||
tlb_batch_pmd_scan(mm, addr, orig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
|
||||
pmd_t *pmdp)
|
||||
{
|
||||
pmd_t entry = *pmdp;
|
||||
|
||||
pmd_val(entry) &= ~_PAGE_VALID;
|
||||
|
||||
set_pmd_at(vma->vm_mm, address, pmdp, entry);
|
||||
flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
|
||||
}
|
||||
|
||||
void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
|
||||
pgtable_t pgtable)
|
||||
{
|
||||
|
|
|
@ -79,6 +79,7 @@ else
|
|||
UTS_MACHINE := x86_64
|
||||
CHECKFLAGS += -D__x86_64__ -m64
|
||||
|
||||
biarch := -m64
|
||||
KBUILD_AFLAGS += -m64
|
||||
KBUILD_CFLAGS += -m64
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
|
|||
|
||||
SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
|
||||
|
||||
sed-voffset := -e 's/^\([0-9a-fA-F]*\) . \(_text\|_end\)$$/\#define VO_\2 0x\1/p'
|
||||
sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|_end\)$$/\#define VO_\2 0x\1/p'
|
||||
|
||||
quiet_cmd_voffset = VOFFSET $@
|
||||
cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@
|
||||
|
@ -80,7 +80,7 @@ targets += voffset.h
|
|||
$(obj)/voffset.h: vmlinux FORCE
|
||||
$(call if_changed,voffset)
|
||||
|
||||
sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
|
||||
sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
|
||||
|
||||
quiet_cmd_zoffset = ZOFFSET $@
|
||||
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
|
||||
|
|
|
@ -354,7 +354,7 @@ static void parse_elf(void *output)
|
|||
free(phdrs);
|
||||
}
|
||||
|
||||
asmlinkage void *decompress_kernel(void *rmode, memptr heap,
|
||||
asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
|
||||
unsigned char *input_data,
|
||||
unsigned long input_len,
|
||||
unsigned char *output,
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
/* hpet memory map physical address */
|
||||
extern unsigned long hpet_address;
|
||||
extern unsigned long force_hpet_address;
|
||||
extern int boot_hpet_disable;
|
||||
extern u8 hpet_blockid;
|
||||
extern int hpet_force_user;
|
||||
extern u8 hpet_msi_disable;
|
||||
|
|
|
@ -384,7 +384,7 @@
|
|||
#define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18
|
||||
#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT)
|
||||
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22
|
||||
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT);
|
||||
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT)
|
||||
#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23
|
||||
#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT)
|
||||
#define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34
|
||||
|
|
|
@ -31,7 +31,7 @@ static char temp_stack[4096];
|
|||
*
|
||||
* Wrapper around acpi_enter_sleep_state() to be called by assmebly.
|
||||
*/
|
||||
acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state)
|
||||
acpi_status asmlinkage __visible x86_acpi_enter_sleep_state(u8 state)
|
||||
{
|
||||
return acpi_enter_sleep_state(state);
|
||||
}
|
||||
|
|
|
@ -2189,7 +2189,7 @@ void send_cleanup_vector(struct irq_cfg *cfg)
|
|||
cfg->move_in_progress = 0;
|
||||
}
|
||||
|
||||
asmlinkage void smp_irq_move_cleanup_interrupt(void)
|
||||
asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
|
||||
{
|
||||
unsigned vector, me;
|
||||
|
||||
|
|
|
@ -429,14 +429,14 @@ static inline void __smp_thermal_interrupt(void)
|
|||
smp_thermal_vector();
|
||||
}
|
||||
|
||||
asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
|
||||
asmlinkage __visible void smp_thermal_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
entering_irq();
|
||||
__smp_thermal_interrupt();
|
||||
exiting_ack_irq();
|
||||
}
|
||||
|
||||
asmlinkage void smp_trace_thermal_interrupt(struct pt_regs *regs)
|
||||
asmlinkage __visible void smp_trace_thermal_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
entering_irq();
|
||||
trace_thermal_apic_entry(THERMAL_APIC_VECTOR);
|
||||
|
|
|
@ -24,14 +24,14 @@ static inline void __smp_threshold_interrupt(void)
|
|||
mce_threshold_vector();
|
||||
}
|
||||
|
||||
asmlinkage void smp_threshold_interrupt(void)
|
||||
asmlinkage __visible void smp_threshold_interrupt(void)
|
||||
{
|
||||
entering_irq();
|
||||
__smp_threshold_interrupt();
|
||||
exiting_ack_irq();
|
||||
}
|
||||
|
||||
asmlinkage void smp_trace_threshold_interrupt(void)
|
||||
asmlinkage __visible void smp_trace_threshold_interrupt(void)
|
||||
{
|
||||
entering_irq();
|
||||
trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <asm/dma.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/hpet.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/gart.h>
|
||||
#include <asm/irq_remapping.h>
|
||||
|
@ -530,6 +531,15 @@ static void __init intel_graphics_stolen(int num, int slot, int func)
|
|||
}
|
||||
}
|
||||
|
||||
static void __init force_disable_hpet(int num, int slot, int func)
|
||||
{
|
||||
#ifdef CONFIG_HPET_TIMER
|
||||
boot_hpet_disable = 1;
|
||||
pr_info("x86/hpet: Will disable the HPET for this platform because it's not reliable\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define QFLAG_APPLY_ONCE 0x1
|
||||
#define QFLAG_APPLIED 0x2
|
||||
#define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
|
||||
|
@ -567,6 +577,12 @@ static struct chipset early_qrk[] __initdata = {
|
|||
PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID,
|
||||
QFLAG_APPLY_ONCE, intel_graphics_stolen },
|
||||
/*
|
||||
* HPET on current version of Baytrail platform has accuracy
|
||||
* problems, disable it for now:
|
||||
*/
|
||||
{ PCI_VENDOR_ID_INTEL, 0x0f00,
|
||||
PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ static void __init i386_default_early_setup(void)
|
|||
reserve_ebda_region();
|
||||
}
|
||||
|
||||
asmlinkage void __init i386_start_kernel(void)
|
||||
asmlinkage __visible void __init i386_start_kernel(void)
|
||||
{
|
||||
sanitize_boot_params(&boot_params);
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ static void __init copy_bootdata(char *real_mode_data)
|
|||
}
|
||||
}
|
||||
|
||||
asmlinkage void __init x86_64_start_kernel(char * real_mode_data)
|
||||
asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ static inline void hpet_clear_mapping(void)
|
|||
/*
|
||||
* HPET command line enable / disable
|
||||
*/
|
||||
static int boot_hpet_disable;
|
||||
int boot_hpet_disable;
|
||||
int hpet_force_user;
|
||||
static int hpet_verbose;
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
asmlinkage extern void ret_from_fork(void);
|
||||
|
||||
asmlinkage DEFINE_PER_CPU(unsigned long, old_rsp);
|
||||
__visible DEFINE_PER_CPU(unsigned long, old_rsp);
|
||||
|
||||
/* Prints also some state that isn't saved in the pt_regs */
|
||||
void __show_regs(struct pt_regs *regs, int all)
|
||||
|
|
|
@ -191,6 +191,16 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
|
|||
},
|
||||
},
|
||||
|
||||
/* Certec */
|
||||
{ /* Handle problems with rebooting on Certec BPC600 */
|
||||
.callback = set_pci_reboot,
|
||||
.ident = "Certec BPC600",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Certec"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "BPC600"),
|
||||
},
|
||||
},
|
||||
|
||||
/* Dell */
|
||||
{ /* Handle problems with rebooting on Dell DXP061 */
|
||||
.callback = set_bios_reboot,
|
||||
|
|
|
@ -168,7 +168,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs)
|
|||
* this function calls the 'stop' function on all other CPUs in the system.
|
||||
*/
|
||||
|
||||
asmlinkage void smp_reboot_interrupt(void)
|
||||
asmlinkage __visible void smp_reboot_interrupt(void)
|
||||
{
|
||||
ack_APIC_irq();
|
||||
irq_enter();
|
||||
|
|
|
@ -357,7 +357,7 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co
|
|||
* for scheduling or signal handling. The actual stack switch is done in
|
||||
* entry.S
|
||||
*/
|
||||
asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
|
||||
asmlinkage __visible __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
|
||||
{
|
||||
struct pt_regs *regs = eregs;
|
||||
/* Did already sync */
|
||||
|
@ -601,11 +601,11 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
|
|||
#endif
|
||||
}
|
||||
|
||||
asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
|
||||
asmlinkage __visible void __attribute__((weak)) smp_thermal_interrupt(void)
|
||||
{
|
||||
}
|
||||
|
||||
asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
|
||||
asmlinkage __visible void __attribute__((weak)) smp_threshold_interrupt(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ static int irq_routing_comply = 1;
|
|||
* and vice versa.
|
||||
*/
|
||||
|
||||
asmlinkage unsigned long vsmp_save_fl(void)
|
||||
asmlinkage __visible unsigned long vsmp_save_fl(void)
|
||||
{
|
||||
unsigned long flags = native_save_fl();
|
||||
|
||||
|
@ -56,7 +56,7 @@ __visible void vsmp_restore_fl(unsigned long flags)
|
|||
}
|
||||
PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl);
|
||||
|
||||
asmlinkage void vsmp_irq_disable(void)
|
||||
asmlinkage __visible void vsmp_irq_disable(void)
|
||||
{
|
||||
unsigned long flags = native_save_fl();
|
||||
|
||||
|
@ -64,7 +64,7 @@ asmlinkage void vsmp_irq_disable(void)
|
|||
}
|
||||
PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable);
|
||||
|
||||
asmlinkage void vsmp_irq_enable(void)
|
||||
asmlinkage __visible void vsmp_irq_enable(void)
|
||||
{
|
||||
unsigned long flags = native_save_fl();
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ void update_vsyscall(struct timekeeper *tk)
|
|||
vdata->monotonic_time_sec = tk->xtime_sec
|
||||
+ tk->wall_to_monotonic.tv_sec;
|
||||
vdata->monotonic_time_snsec = tk->xtime_nsec
|
||||
+ (tk->wall_to_monotonic.tv_nsec
|
||||
+ ((u64)tk->wall_to_monotonic.tv_nsec
|
||||
<< tk->shift);
|
||||
while (vdata->monotonic_time_snsec >=
|
||||
(((u64)NSEC_PER_SEC) << tk->shift)) {
|
||||
|
|
|
@ -280,7 +280,7 @@ int kvm_set_apic_base(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_set_apic_base);
|
||||
|
||||
asmlinkage void kvm_spurious_fault(void)
|
||||
asmlinkage __visible void kvm_spurious_fault(void)
|
||||
{
|
||||
/* Fault while not rebooting. We want the trace. */
|
||||
BUG();
|
||||
|
|
|
@ -233,13 +233,13 @@ static void lguest_end_context_switch(struct task_struct *next)
|
|||
* flags word contains all kind of stuff, but in practice Linux only cares
|
||||
* about the interrupt flag. Our "save_flags()" just returns that.
|
||||
*/
|
||||
asmlinkage unsigned long lguest_save_fl(void)
|
||||
asmlinkage __visible unsigned long lguest_save_fl(void)
|
||||
{
|
||||
return lguest_data.irq_enabled;
|
||||
}
|
||||
|
||||
/* Interrupts go off... */
|
||||
asmlinkage void lguest_irq_disable(void)
|
||||
asmlinkage __visible void lguest_irq_disable(void)
|
||||
{
|
||||
lguest_data.irq_enabled = 0;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ static inline int __flip_bit(u32 msr, u8 bit, bool set)
|
|||
if (m1.q == m.q)
|
||||
return 0;
|
||||
|
||||
err = msr_write(msr, &m);
|
||||
err = msr_write(msr, &m1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ static struct {
|
|||
0x242 in div_Xsig.S
|
||||
*/
|
||||
|
||||
asmlinkage void FPU_exception(int n)
|
||||
asmlinkage __visible void FPU_exception(int n)
|
||||
{
|
||||
int i, int_type;
|
||||
|
||||
|
@ -492,7 +492,7 @@ int real_2op_NaN(FPU_REG const *b, u_char tagb,
|
|||
|
||||
/* Invalid arith operation on Valid registers */
|
||||
/* Returns < 0 if the exception is unmasked */
|
||||
asmlinkage int arith_invalid(int deststnr)
|
||||
asmlinkage __visible int arith_invalid(int deststnr)
|
||||
{
|
||||
|
||||
EXCEPTION(EX_Invalid);
|
||||
|
@ -507,7 +507,7 @@ asmlinkage int arith_invalid(int deststnr)
|
|||
}
|
||||
|
||||
/* Divide a finite number by zero */
|
||||
asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign)
|
||||
asmlinkage __visible int FPU_divide_by_zero(int deststnr, u_char sign)
|
||||
{
|
||||
FPU_REG *dest = &st(deststnr);
|
||||
int tag = TAG_Valid;
|
||||
|
@ -539,7 +539,7 @@ int set_precision_flag(int flags)
|
|||
}
|
||||
|
||||
/* This may be called often, so keep it lean */
|
||||
asmlinkage void set_precision_flag_up(void)
|
||||
asmlinkage __visible void set_precision_flag_up(void)
|
||||
{
|
||||
if (control_word & CW_Precision)
|
||||
partial_status |= (SW_Precision | SW_C1); /* The masked response */
|
||||
|
@ -548,7 +548,7 @@ asmlinkage void set_precision_flag_up(void)
|
|||
}
|
||||
|
||||
/* This may be called often, so keep it lean */
|
||||
asmlinkage void set_precision_flag_down(void)
|
||||
asmlinkage __visible void set_precision_flag_down(void)
|
||||
{
|
||||
if (control_word & CW_Precision) { /* The masked response */
|
||||
partial_status &= ~SW_C1;
|
||||
|
@ -557,7 +557,7 @@ asmlinkage void set_precision_flag_down(void)
|
|||
EXCEPTION(EX_Precision);
|
||||
}
|
||||
|
||||
asmlinkage int denormal_operand(void)
|
||||
asmlinkage __visible int denormal_operand(void)
|
||||
{
|
||||
if (control_word & CW_Denormal) { /* The masked response */
|
||||
partial_status |= SW_Denorm_Op;
|
||||
|
@ -568,7 +568,7 @@ asmlinkage int denormal_operand(void)
|
|||
}
|
||||
}
|
||||
|
||||
asmlinkage int arith_overflow(FPU_REG *dest)
|
||||
asmlinkage __visible int arith_overflow(FPU_REG *dest)
|
||||
{
|
||||
int tag = TAG_Valid;
|
||||
|
||||
|
@ -596,7 +596,7 @@ asmlinkage int arith_overflow(FPU_REG *dest)
|
|||
|
||||
}
|
||||
|
||||
asmlinkage int arith_underflow(FPU_REG *dest)
|
||||
asmlinkage __visible int arith_underflow(FPU_REG *dest)
|
||||
{
|
||||
int tag = TAG_Valid;
|
||||
|
||||
|
|
|
@ -14,48 +14,92 @@
|
|||
|
||||
static const struct font_desc *font;
|
||||
static u32 efi_x, efi_y;
|
||||
static void *efi_fb;
|
||||
static bool early_efi_keep;
|
||||
|
||||
static __init void early_efi_clear_scanline(unsigned int y)
|
||||
/*
|
||||
* efi earlyprintk need use early_ioremap to map the framebuffer.
|
||||
* But early_ioremap is not usable for earlyprintk=efi,keep, ioremap should
|
||||
* be used instead. ioremap will be available after paging_init() which is
|
||||
* earlier than initcall callbacks. Thus adding this early initcall function
|
||||
* early_efi_map_fb to map the whole efi framebuffer.
|
||||
*/
|
||||
static __init int early_efi_map_fb(void)
|
||||
{
|
||||
unsigned long base, *dst;
|
||||
u16 len;
|
||||
unsigned long base, size;
|
||||
|
||||
if (!early_efi_keep)
|
||||
return 0;
|
||||
|
||||
base = boot_params.screen_info.lfb_base;
|
||||
len = boot_params.screen_info.lfb_linelength;
|
||||
size = boot_params.screen_info.lfb_size;
|
||||
efi_fb = ioremap(base, size);
|
||||
|
||||
dst = early_ioremap(base + y*len, len);
|
||||
return efi_fb ? 0 : -ENOMEM;
|
||||
}
|
||||
early_initcall(early_efi_map_fb);
|
||||
|
||||
/*
|
||||
* early_efi_map maps efi framebuffer region [start, start + len -1]
|
||||
* In case earlyprintk=efi,keep we have the whole framebuffer mapped already
|
||||
* so just return the offset efi_fb + start.
|
||||
*/
|
||||
static __init_refok void *early_efi_map(unsigned long start, unsigned long len)
|
||||
{
|
||||
unsigned long base;
|
||||
|
||||
base = boot_params.screen_info.lfb_base;
|
||||
|
||||
if (efi_fb)
|
||||
return (efi_fb + start);
|
||||
else
|
||||
return early_ioremap(base + start, len);
|
||||
}
|
||||
|
||||
static __init_refok void early_efi_unmap(void *addr, unsigned long len)
|
||||
{
|
||||
if (!efi_fb)
|
||||
early_iounmap(addr, len);
|
||||
}
|
||||
|
||||
static void early_efi_clear_scanline(unsigned int y)
|
||||
{
|
||||
unsigned long *dst;
|
||||
u16 len;
|
||||
|
||||
len = boot_params.screen_info.lfb_linelength;
|
||||
dst = early_efi_map(y*len, len);
|
||||
if (!dst)
|
||||
return;
|
||||
|
||||
memset(dst, 0, len);
|
||||
early_iounmap(dst, len);
|
||||
early_efi_unmap(dst, len);
|
||||
}
|
||||
|
||||
static __init void early_efi_scroll_up(void)
|
||||
static void early_efi_scroll_up(void)
|
||||
{
|
||||
unsigned long base, *dst, *src;
|
||||
unsigned long *dst, *src;
|
||||
u16 len;
|
||||
u32 i, height;
|
||||
|
||||
base = boot_params.screen_info.lfb_base;
|
||||
len = boot_params.screen_info.lfb_linelength;
|
||||
height = boot_params.screen_info.lfb_height;
|
||||
|
||||
for (i = 0; i < height - font->height; i++) {
|
||||
dst = early_ioremap(base + i*len, len);
|
||||
dst = early_efi_map(i*len, len);
|
||||
if (!dst)
|
||||
return;
|
||||
|
||||
src = early_ioremap(base + (i + font->height) * len, len);
|
||||
src = early_efi_map((i + font->height) * len, len);
|
||||
if (!src) {
|
||||
early_iounmap(dst, len);
|
||||
early_efi_unmap(dst, len);
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(dst, src, len);
|
||||
|
||||
early_iounmap(src, len);
|
||||
early_iounmap(dst, len);
|
||||
early_efi_unmap(src, len);
|
||||
early_efi_unmap(dst, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,16 +123,14 @@ static void early_efi_write_char(u32 *dst, unsigned char c, unsigned int h)
|
|||
}
|
||||
}
|
||||
|
||||
static __init void
|
||||
static void
|
||||
early_efi_write(struct console *con, const char *str, unsigned int num)
|
||||
{
|
||||
struct screen_info *si;
|
||||
unsigned long base;
|
||||
unsigned int len;
|
||||
const char *s;
|
||||
void *dst;
|
||||
|
||||
base = boot_params.screen_info.lfb_base;
|
||||
si = &boot_params.screen_info;
|
||||
len = si->lfb_linelength;
|
||||
|
||||
|
@ -109,7 +151,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num)
|
|||
for (h = 0; h < font->height; h++) {
|
||||
unsigned int n, x;
|
||||
|
||||
dst = early_ioremap(base + (efi_y + h) * len, len);
|
||||
dst = early_efi_map((efi_y + h) * len, len);
|
||||
if (!dst)
|
||||
return;
|
||||
|
||||
|
@ -123,7 +165,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num)
|
|||
s++;
|
||||
}
|
||||
|
||||
early_iounmap(dst, len);
|
||||
early_efi_unmap(dst, len);
|
||||
}
|
||||
|
||||
num -= count;
|
||||
|
@ -179,6 +221,9 @@ static __init int early_efi_setup(struct console *con, char *options)
|
|||
for (i = 0; i < (yres - efi_y) / font->height; i++)
|
||||
early_efi_scroll_up();
|
||||
|
||||
/* early_console_register will unset CON_BOOT in case ,keep */
|
||||
if (!(con->flags & CON_BOOT))
|
||||
early_efi_keep = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ static int xo1_power_state_enter(suspend_state_t pm_state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage int xo1_do_sleep(u8 sleep_state)
|
||||
asmlinkage __visible int xo1_do_sleep(u8 sleep_state)
|
||||
{
|
||||
void *pgd_addr = __va(read_cr3());
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
extern __visible const void __nosave_begin, __nosave_end;
|
||||
|
||||
/* Defined in hibernate_asm_64.S */
|
||||
extern asmlinkage int restore_image(void);
|
||||
extern asmlinkage __visible int restore_image(void);
|
||||
|
||||
/*
|
||||
* Address to jump to in the last phase of restore in order to get to the image
|
||||
|
|
|
@ -1515,7 +1515,7 @@ static void __init xen_pvh_early_guest_init(void)
|
|||
}
|
||||
|
||||
/* First C function to be called on Xen boot */
|
||||
asmlinkage void __init xen_start_kernel(void)
|
||||
asmlinkage __visible void __init xen_start_kernel(void)
|
||||
{
|
||||
struct physdev_set_iopl set_iopl;
|
||||
int rc;
|
||||
|
|
|
@ -23,7 +23,7 @@ void xen_force_evtchn_callback(void)
|
|||
(void)HYPERVISOR_xen_version(0, NULL);
|
||||
}
|
||||
|
||||
asmlinkage unsigned long xen_save_fl(void)
|
||||
asmlinkage __visible unsigned long xen_save_fl(void)
|
||||
{
|
||||
struct vcpu_info *vcpu;
|
||||
unsigned long flags;
|
||||
|
@ -63,7 +63,7 @@ __visible void xen_restore_fl(unsigned long flags)
|
|||
}
|
||||
PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl);
|
||||
|
||||
asmlinkage void xen_irq_disable(void)
|
||||
asmlinkage __visible void xen_irq_disable(void)
|
||||
{
|
||||
/* There's a one instruction preempt window here. We need to
|
||||
make sure we're don't switch CPUs between getting the vcpu
|
||||
|
@ -74,7 +74,7 @@ asmlinkage void xen_irq_disable(void)
|
|||
}
|
||||
PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
|
||||
|
||||
asmlinkage void xen_irq_enable(void)
|
||||
asmlinkage __visible void xen_irq_enable(void)
|
||||
{
|
||||
struct vcpu_info *vcpu;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ config XTENSA
|
|||
select GENERIC_PCI_IOMAP
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select BUILDTIME_EXTABLE_SORT
|
||||
select CLONE_BACKWARDS
|
||||
select IRQ_DOMAIN
|
||||
select HAVE_OPROFILE
|
||||
|
@ -189,6 +190,24 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
|
|||
|
||||
If in doubt, say Y.
|
||||
|
||||
config HIGHMEM
|
||||
bool "High Memory Support"
|
||||
help
|
||||
Linux can use the full amount of RAM in the system by
|
||||
default. However, the default MMUv2 setup only maps the
|
||||
lowermost 128 MB of memory linearly to the areas starting
|
||||
at 0xd0000000 (cached) and 0xd8000000 (uncached).
|
||||
When there are more than 128 MB memory in the system not
|
||||
all of it can be "permanently mapped" by the kernel.
|
||||
The physical memory that's not permanently mapped is called
|
||||
"high memory".
|
||||
|
||||
If you are compiling a kernel which will never run on a
|
||||
machine with more than 128 MB total physical RAM, answer
|
||||
N here.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
endmenu
|
||||
|
||||
config XTENSA_CALIBRATE_CCOUNT
|
||||
|
@ -224,7 +243,6 @@ choice
|
|||
|
||||
config XTENSA_PLATFORM_ISS
|
||||
bool "ISS"
|
||||
depends on TTY
|
||||
select XTENSA_CALIBRATE_CCOUNT
|
||||
select SERIAL_CONSOLE
|
||||
help
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/dts-v1/;
|
||||
/include/ "xtfpga.dtsi"
|
||||
/include/ "xtfpga-flash-128m.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "cdns,xtensa-kc705";
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x08000000>;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
/ {
|
||||
soc {
|
||||
flash: flash@00000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x00000000 0x08000000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
label = "data";
|
||||
reg = <0x00000000 0x06000000>;
|
||||
};
|
||||
partition@0x6000000 {
|
||||
label = "boot loader area";
|
||||
reg = <0x06000000 0x00800000>;
|
||||
};
|
||||
partition@0x6800000 {
|
||||
label = "kernel image";
|
||||
reg = <0x06800000 0x017e0000>;
|
||||
};
|
||||
partition@0x7fe0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x07fe0000 0x00020000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,26 +1,28 @@
|
|||
/ {
|
||||
flash: flash@f8000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "cfi-flash";
|
||||
reg = <0xf8000000 0x01000000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
label = "boot loader area";
|
||||
reg = <0x00000000 0x00400000>;
|
||||
soc {
|
||||
flash: flash@08000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x08000000 0x01000000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
label = "boot loader area";
|
||||
reg = <0x00000000 0x00400000>;
|
||||
};
|
||||
partition@0x400000 {
|
||||
label = "kernel image";
|
||||
reg = <0x00400000 0x00600000>;
|
||||
};
|
||||
partition@0xa00000 {
|
||||
label = "data";
|
||||
reg = <0x00a00000 0x005e0000>;
|
||||
};
|
||||
partition@0xfe0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x00fe0000 0x00020000>;
|
||||
};
|
||||
};
|
||||
partition@0x400000 {
|
||||
label = "kernel image";
|
||||
reg = <0x00400000 0x00600000>;
|
||||
};
|
||||
partition@0xa00000 {
|
||||
label = "data";
|
||||
reg = <0x00a00000 0x005e0000>;
|
||||
};
|
||||
partition@0xfe0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x00fe0000 0x00020000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
/ {
|
||||
flash: flash@f8000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "cfi-flash";
|
||||
reg = <0xf8000000 0x00400000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
label = "boot loader area";
|
||||
reg = <0x00000000 0x003f0000>;
|
||||
soc {
|
||||
flash: flash@08000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x08000000 0x00400000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
label = "boot loader area";
|
||||
reg = <0x00000000 0x003f0000>;
|
||||
};
|
||||
partition@0x3f0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x003f0000 0x00010000>;
|
||||
};
|
||||
};
|
||||
partition@0x3f0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x003f0000 0x00010000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -42,21 +42,28 @@ osc: main-oscillator {
|
|||
};
|
||||
};
|
||||
|
||||
serial0: serial@fd050020 {
|
||||
device_type = "serial";
|
||||
compatible = "ns16550a";
|
||||
no-loopback-test;
|
||||
reg = <0xfd050020 0x20>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <0 1>; /* external irq 0 */
|
||||
clocks = <&osc>;
|
||||
};
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
ranges = <0x00000000 0xf0000000 0x10000000>;
|
||||
|
||||
enet0: ethoc@fd030000 {
|
||||
compatible = "opencores,ethoc";
|
||||
reg = <0xfd030000 0x4000 0xfd800000 0x4000>;
|
||||
interrupts = <1 1>; /* external irq 1 */
|
||||
local-mac-address = [00 50 c2 13 6f 00];
|
||||
clocks = <&osc>;
|
||||
serial0: serial@0d050020 {
|
||||
device_type = "serial";
|
||||
compatible = "ns16550a";
|
||||
no-loopback-test;
|
||||
reg = <0x0d050020 0x20>;
|
||||
reg-shift = <2>;
|
||||
interrupts = <0 1>; /* external irq 0 */
|
||||
clocks = <&osc>;
|
||||
};
|
||||
|
||||
enet0: ethoc@0d030000 {
|
||||
compatible = "opencores,ethoc";
|
||||
reg = <0x0d030000 0x4000 0x0d800000 0x4000>;
|
||||
interrupts = <1 1>; /* external irq 1 */
|
||||
local-mac-address = [00 50 c2 13 6f 00];
|
||||
clocks = <&osc>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -37,23 +37,14 @@ typedef struct bp_tag {
|
|||
unsigned long data[0]; /* data */
|
||||
} bp_tag_t;
|
||||
|
||||
typedef struct meminfo {
|
||||
struct bp_meminfo {
|
||||
unsigned long type;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
} meminfo_t;
|
||||
|
||||
#define SYSMEM_BANKS_MAX 5
|
||||
};
|
||||
|
||||
#define MEMORY_TYPE_CONVENTIONAL 0x1000
|
||||
#define MEMORY_TYPE_NONE 0x2000
|
||||
|
||||
typedef struct sysmem_info {
|
||||
int nr_banks;
|
||||
meminfo_t bank[SYSMEM_BANKS_MAX];
|
||||
} sysmem_info_t;
|
||||
|
||||
extern sysmem_info_t sysmem;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* fixmap.h: compile-time virtual memory allocation
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1998 Ingo Molnar
|
||||
*
|
||||
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
|
||||
*/
|
||||
|
||||
#ifndef _ASM_FIXMAP_H
|
||||
#define _ASM_FIXMAP_H
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#include <linux/threads.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Here we define all the compile-time 'special' virtual
|
||||
* addresses. The point is to have a constant address at
|
||||
* compile time, but to set the physical address only
|
||||
* in the boot process. We allocate these special addresses
|
||||
* from the end of the consistent memory region backwards.
|
||||
* Also this lets us do fail-safe vmalloc(), we
|
||||
* can guarantee that these special addresses and
|
||||
* vmalloc()-ed addresses never overlap.
|
||||
*
|
||||
* these 'compile-time allocated' memory buffers are
|
||||
* fixed-size 4k pages. (or larger if used with an increment
|
||||
* higher than 1) use fixmap_set(idx,phys) to associate
|
||||
* physical memory with fixmap indices.
|
||||
*/
|
||||
enum fixed_addresses {
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/* reserved pte's for temporary kernel mappings */
|
||||
FIX_KMAP_BEGIN,
|
||||
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
|
||||
#endif
|
||||
__end_of_fixed_addresses
|
||||
};
|
||||
|
||||
#define FIXADDR_TOP (VMALLOC_START - PAGE_SIZE)
|
||||
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||
#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)
|
||||
|
||||
#include <asm-generic/fixmap.h>
|
||||
|
||||
#define kmap_get_fixmap_pte(vaddr) \
|
||||
pte_offset_kernel( \
|
||||
pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \
|
||||
(vaddr) \
|
||||
)
|
||||
|
||||
#endif
|
|
@ -6,11 +6,54 @@
|
|||
* this archive for more details.
|
||||
*
|
||||
* Copyright (C) 2003 - 2005 Tensilica Inc.
|
||||
* Copyright (C) 2014 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
#ifndef _XTENSA_HIGHMEM_H
|
||||
#define _XTENSA_HIGHMEM_H
|
||||
|
||||
extern void flush_cache_kmaps(void);
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#define PKMAP_BASE (FIXADDR_START - PMD_SIZE)
|
||||
#define LAST_PKMAP PTRS_PER_PTE
|
||||
#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
|
||||
#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
|
||||
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
|
||||
|
||||
#define kmap_prot PAGE_KERNEL
|
||||
|
||||
extern pte_t *pkmap_page_table;
|
||||
|
||||
void *kmap_high(struct page *page);
|
||||
void kunmap_high(struct page *page);
|
||||
|
||||
static inline void *kmap(struct page *page)
|
||||
{
|
||||
BUG_ON(in_interrupt());
|
||||
if (!PageHighMem(page))
|
||||
return page_address(page);
|
||||
return kmap_high(page);
|
||||
}
|
||||
|
||||
static inline void kunmap(struct page *page)
|
||||
{
|
||||
BUG_ON(in_interrupt());
|
||||
if (!PageHighMem(page))
|
||||
return;
|
||||
kunmap_high(page);
|
||||
}
|
||||
|
||||
static inline void flush_cache_kmaps(void)
|
||||
{
|
||||
flush_cache_all();
|
||||
}
|
||||
|
||||
void *kmap_atomic(struct page *page);
|
||||
void __kunmap_atomic(void *kvaddr);
|
||||
|
||||
void kmap_init(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -310,6 +310,10 @@ set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
|
|||
update_pte(ptep, pteval);
|
||||
}
|
||||
|
||||
static inline void set_pte(pte_t *ptep, pte_t pteval)
|
||||
{
|
||||
update_pte(ptep, pteval);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_pmd(pmd_t *pmdp, pmd_t pmdval)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* sysmem-related prototypes.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2014 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
#ifndef _XTENSA_SYSMEM_H
|
||||
#define _XTENSA_SYSMEM_H
|
||||
|
||||
#define SYSMEM_BANKS_MAX 31
|
||||
|
||||
struct meminfo {
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
};
|
||||
|
||||
/*
|
||||
* Bank array is sorted by .start.
|
||||
* Banks don't overlap and there's at least one page gap
|
||||
* between adjacent bank entries.
|
||||
*/
|
||||
struct sysmem_info {
|
||||
int nr_banks;
|
||||
struct meminfo bank[SYSMEM_BANKS_MAX];
|
||||
};
|
||||
|
||||
extern struct sysmem_info sysmem;
|
||||
|
||||
int add_sysmem_bank(unsigned long start, unsigned long end);
|
||||
int mem_reserve(unsigned long, unsigned long, int);
|
||||
void bootmem_init(void);
|
||||
void zones_init(void);
|
||||
|
||||
#endif /* _XTENSA_SYSMEM_H */
|
|
@ -36,6 +36,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma,
|
|||
unsigned long page);
|
||||
void local_flush_tlb_range(struct vm_area_struct *vma,
|
||||
unsigned long start, unsigned long end);
|
||||
void local_flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
|
@ -44,12 +45,7 @@ void flush_tlb_mm(struct mm_struct *);
|
|||
void flush_tlb_page(struct vm_area_struct *, unsigned long);
|
||||
void flush_tlb_range(struct vm_area_struct *, unsigned long,
|
||||
unsigned long);
|
||||
|
||||
static inline void flush_tlb_kernel_range(unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
flush_tlb_all();
|
||||
}
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
|
||||
#else /* !CONFIG_SMP */
|
||||
|
||||
|
@ -58,7 +54,8 @@ static inline void flush_tlb_kernel_range(unsigned long start,
|
|||
#define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page)
|
||||
#define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \
|
||||
end)
|
||||
#define flush_tlb_kernel_range(start, end) local_flush_tlb_all()
|
||||
#define flush_tlb_kernel_range(start, end) local_flush_tlb_kernel_range(start, \
|
||||
end)
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <asm/param.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/sysmem.h>
|
||||
|
||||
#include <platform/hardware.h>
|
||||
|
||||
|
@ -88,12 +89,6 @@ static char __initdata command_line[COMMAND_LINE_SIZE];
|
|||
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
|
||||
#endif
|
||||
|
||||
sysmem_info_t __initdata sysmem;
|
||||
|
||||
extern int mem_reserve(unsigned long, unsigned long, int);
|
||||
extern void bootmem_init(void);
|
||||
extern void zones_init(void);
|
||||
|
||||
/*
|
||||
* Boot parameter parsing.
|
||||
*
|
||||
|
@ -113,31 +108,14 @@ typedef struct tagtable {
|
|||
|
||||
/* parse current tag */
|
||||
|
||||
static int __init add_sysmem_bank(unsigned long type, unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) {
|
||||
printk(KERN_WARNING
|
||||
"Ignoring memory bank 0x%08lx size %ldKB\n",
|
||||
start, end - start);
|
||||
return -EINVAL;
|
||||
}
|
||||
sysmem.bank[sysmem.nr_banks].type = type;
|
||||
sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start);
|
||||
sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK;
|
||||
sysmem.nr_banks++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init parse_tag_mem(const bp_tag_t *tag)
|
||||
{
|
||||
meminfo_t *mi = (meminfo_t *)(tag->data);
|
||||
struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data);
|
||||
|
||||
if (mi->type != MEMORY_TYPE_CONVENTIONAL)
|
||||
return -1;
|
||||
|
||||
return add_sysmem_bank(mi->type, mi->start, mi->end);
|
||||
return add_sysmem_bank(mi->start, mi->end);
|
||||
}
|
||||
|
||||
__tagtable(BP_TAG_MEMORY, parse_tag_mem);
|
||||
|
@ -146,8 +124,8 @@ __tagtable(BP_TAG_MEMORY, parse_tag_mem);
|
|||
|
||||
static int __init parse_tag_initrd(const bp_tag_t* tag)
|
||||
{
|
||||
meminfo_t* mi;
|
||||
mi = (meminfo_t*)(tag->data);
|
||||
struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data);
|
||||
|
||||
initrd_start = (unsigned long)__va(mi->start);
|
||||
initrd_end = (unsigned long)__va(mi->end);
|
||||
|
||||
|
@ -255,7 +233,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
|||
return;
|
||||
|
||||
size &= PAGE_MASK;
|
||||
add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size);
|
||||
add_sysmem_bank(base, base + size);
|
||||
}
|
||||
|
||||
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
|
||||
|
@ -292,8 +270,6 @@ device_initcall(xtensa_device_probe);
|
|||
|
||||
void __init init_arch(bp_tag_t *bp_start)
|
||||
{
|
||||
sysmem.nr_banks = 0;
|
||||
|
||||
/* Parse boot parameters */
|
||||
|
||||
if (bp_start)
|
||||
|
@ -304,10 +280,9 @@ void __init init_arch(bp_tag_t *bp_start)
|
|||
#endif
|
||||
|
||||
if (sysmem.nr_banks == 0) {
|
||||
sysmem.nr_banks = 1;
|
||||
sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START;
|
||||
sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START
|
||||
+ PLATFORM_DEFAULT_MEM_SIZE;
|
||||
add_sysmem_bank(PLATFORM_DEFAULT_MEM_START,
|
||||
PLATFORM_DEFAULT_MEM_START +
|
||||
PLATFORM_DEFAULT_MEM_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMDLINE_BOOL
|
||||
|
@ -487,7 +462,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
if (initrd_start < initrd_end) {
|
||||
initrd_is_mapped = mem_reserve(__pa(initrd_start),
|
||||
__pa(initrd_end), 0);
|
||||
__pa(initrd_end), 0) == 0;
|
||||
initrd_below_start_ok = 1;
|
||||
} else {
|
||||
initrd_start = 0;
|
||||
|
@ -532,6 +507,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
__pa(&_Level6InterruptVector_text_end), 0);
|
||||
#endif
|
||||
|
||||
parse_early_param();
|
||||
bootmem_init();
|
||||
|
||||
unflatten_and_copy_device_tree();
|
||||
|
|
|
@ -496,6 +496,21 @@ void flush_tlb_range(struct vm_area_struct *vma,
|
|||
on_each_cpu(ipi_flush_tlb_range, &fd, 1);
|
||||
}
|
||||
|
||||
static void ipi_flush_tlb_kernel_range(void *arg)
|
||||
{
|
||||
struct flush_data *fd = arg;
|
||||
local_flush_tlb_kernel_range(fd->addr1, fd->addr2);
|
||||
}
|
||||
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
struct flush_data fd = {
|
||||
.addr1 = start,
|
||||
.addr2 = end,
|
||||
};
|
||||
on_each_cpu(ipi_flush_tlb_kernel_range, &fd, 1);
|
||||
}
|
||||
|
||||
/* Cache flush functions */
|
||||
|
||||
static void ipi_flush_cache_all(void *arg)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/in6.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -105,6 +106,7 @@ EXPORT_SYMBOL(csum_partial_copy_generic);
|
|||
* Architecture-specific symbols
|
||||
*/
|
||||
EXPORT_SYMBOL(__xtensa_copy_user);
|
||||
EXPORT_SYMBOL(__invalidate_icache_range);
|
||||
|
||||
/*
|
||||
* Kernel hacking ...
|
||||
|
@ -127,3 +129,8 @@ EXPORT_SYMBOL(common_exception_return);
|
|||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
EXPORT_SYMBOL(_mcount);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(__invalidate_dcache_range);
|
||||
#if XCHAL_DCACHE_IS_WRITEBACK
|
||||
EXPORT_SYMBOL(__flush_dcache_range);
|
||||
#endif
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
|
||||
obj-y := init.o cache.o misc.o
|
||||
obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o
|
||||
obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||
|
|
|
@ -59,6 +59,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE) && defined(CONFIG_HIGHMEM)
|
||||
#error "HIGHMEM is not supported on cores with aliasing cache."
|
||||
#endif
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
|
||||
|
||||
/*
|
||||
|
@ -179,10 +183,11 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
|
|||
#else
|
||||
if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)
|
||||
&& (vma->vm_flags & VM_EXEC) != 0) {
|
||||
unsigned long paddr = (unsigned long) page_address(page);
|
||||
unsigned long paddr = (unsigned long)kmap_atomic(page);
|
||||
__flush_dcache_page(paddr);
|
||||
__invalidate_icache_page(paddr);
|
||||
set_bit(PG_arch_1, &page->flags);
|
||||
kunmap_atomic((void *)paddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* High memory support for Xtensa architecture
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file "COPYING" in the main directory of
|
||||
* this archive for more details.
|
||||
*
|
||||
* Copyright (C) 2014 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
static pte_t *kmap_pte;
|
||||
|
||||
void *kmap_atomic(struct page *page)
|
||||
{
|
||||
enum fixed_addresses idx;
|
||||
unsigned long vaddr;
|
||||
int type;
|
||||
|
||||
pagefault_disable();
|
||||
if (!PageHighMem(page))
|
||||
return page_address(page);
|
||||
|
||||
type = kmap_atomic_idx_push();
|
||||
idx = type + KM_TYPE_NR * smp_processor_id();
|
||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||
BUG_ON(!pte_none(*(kmap_pte - idx)));
|
||||
#endif
|
||||
set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC));
|
||||
|
||||
return (void *)vaddr;
|
||||
}
|
||||
EXPORT_SYMBOL(kmap_atomic);
|
||||
|
||||
void __kunmap_atomic(void *kvaddr)
|
||||
{
|
||||
int idx, type;
|
||||
|
||||
if (kvaddr >= (void *)FIXADDR_START &&
|
||||
kvaddr < (void *)FIXADDR_TOP) {
|
||||
type = kmap_atomic_idx();
|
||||
idx = type + KM_TYPE_NR * smp_processor_id();
|
||||
|
||||
/*
|
||||
* Force other mappings to Oops if they'll try to access this
|
||||
* pte without first remap it. Keeping stale mappings around
|
||||
* is a bad idea also, in case the page changes cacheability
|
||||
* attributes or becomes a protected page in a hypervisor.
|
||||
*/
|
||||
pte_clear(&init_mm, kvaddr, kmap_pte - idx);
|
||||
local_flush_tlb_kernel_range((unsigned long)kvaddr,
|
||||
(unsigned long)kvaddr + PAGE_SIZE);
|
||||
|
||||
kmap_atomic_idx_pop();
|
||||
}
|
||||
|
||||
pagefault_enable();
|
||||
}
|
||||
EXPORT_SYMBOL(__kunmap_atomic);
|
||||
|
||||
void __init kmap_init(void)
|
||||
{
|
||||
unsigned long kmap_vstart;
|
||||
|
||||
/* cache the first kmap pte */
|
||||
kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
|
||||
kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001 - 2005 Tensilica Inc.
|
||||
* Copyright (C) 2014 Cadence Design Systems Inc.
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
* Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
|
||||
|
@ -19,6 +20,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/nodemask.h>
|
||||
|
@ -27,11 +29,133 @@
|
|||
#include <asm/bootparam.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/sysmem.h>
|
||||
|
||||
struct sysmem_info sysmem __initdata;
|
||||
|
||||
static void __init sysmem_dump(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
pr_debug("Sysmem:\n");
|
||||
for (i = 0; i < sysmem.nr_banks; ++i)
|
||||
pr_debug(" 0x%08lx - 0x%08lx (%ldK)\n",
|
||||
sysmem.bank[i].start, sysmem.bank[i].end,
|
||||
(sysmem.bank[i].end - sysmem.bank[i].start) >> 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find bank with maximal .start such that bank.start <= start
|
||||
*/
|
||||
static inline struct meminfo * __init find_bank(unsigned long start)
|
||||
{
|
||||
unsigned i;
|
||||
struct meminfo *it = NULL;
|
||||
|
||||
for (i = 0; i < sysmem.nr_banks; ++i)
|
||||
if (sysmem.bank[i].start <= start)
|
||||
it = sysmem.bank + i;
|
||||
else
|
||||
break;
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move all memory banks starting at 'from' to a new place at 'to',
|
||||
* adjust nr_banks accordingly.
|
||||
* Both 'from' and 'to' must be inside the sysmem.bank.
|
||||
*
|
||||
* Returns: 0 (success), -ENOMEM (not enough space in the sysmem.bank).
|
||||
*/
|
||||
static int __init move_banks(struct meminfo *to, struct meminfo *from)
|
||||
{
|
||||
unsigned n = sysmem.nr_banks - (from - sysmem.bank);
|
||||
|
||||
if (to > from && to - from + sysmem.nr_banks > SYSMEM_BANKS_MAX)
|
||||
return -ENOMEM;
|
||||
if (to != from)
|
||||
memmove(to, from, n * sizeof(struct meminfo));
|
||||
sysmem.nr_banks += to - from;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add new bank to sysmem. Resulting sysmem is the union of bytes of the
|
||||
* original sysmem and the new bank.
|
||||
*
|
||||
* Returns: 0 (success), < 0 (error)
|
||||
*/
|
||||
int __init add_sysmem_bank(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned i;
|
||||
struct meminfo *it = NULL;
|
||||
unsigned long sz;
|
||||
unsigned long bank_sz = 0;
|
||||
|
||||
if (start == end ||
|
||||
(start < end) != (PAGE_ALIGN(start) < (end & PAGE_MASK))) {
|
||||
pr_warn("Ignoring small memory bank 0x%08lx size: %ld bytes\n",
|
||||
start, end - start);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
start = PAGE_ALIGN(start);
|
||||
end &= PAGE_MASK;
|
||||
sz = end - start;
|
||||
|
||||
it = find_bank(start);
|
||||
|
||||
if (it)
|
||||
bank_sz = it->end - it->start;
|
||||
|
||||
if (it && bank_sz >= start - it->start) {
|
||||
if (end - it->start > bank_sz)
|
||||
it->end = end;
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
if (!it)
|
||||
it = sysmem.bank;
|
||||
else
|
||||
++it;
|
||||
|
||||
if (it - sysmem.bank < sysmem.nr_banks &&
|
||||
it->start - start <= sz) {
|
||||
it->start = start;
|
||||
if (it->end - it->start < sz)
|
||||
it->end = end;
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
if (move_banks(it + 1, it) < 0) {
|
||||
pr_warn("Ignoring memory bank 0x%08lx size %ld bytes\n",
|
||||
start, end - start);
|
||||
return -EINVAL;
|
||||
}
|
||||
it->start = start;
|
||||
it->end = end;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sz = it->end - it->start;
|
||||
for (i = it + 1 - sysmem.bank; i < sysmem.nr_banks; ++i)
|
||||
if (sysmem.bank[i].start - it->start <= sz) {
|
||||
if (sz < sysmem.bank[i].end - it->start)
|
||||
it->end = sysmem.bank[i].end;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
move_banks(it + 1, sysmem.bank + i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mem_reserve(start, end, must_exist)
|
||||
*
|
||||
* Reserve some memory from the memory pool.
|
||||
* If must_exist is set and a part of the region being reserved does not exist
|
||||
* memory map is not altered.
|
||||
*
|
||||
* Parameters:
|
||||
* start Start of region,
|
||||
|
@ -39,53 +163,69 @@
|
|||
* must_exist Must exist in memory pool.
|
||||
*
|
||||
* Returns:
|
||||
* 0 (memory area couldn't be mapped)
|
||||
* -1 (success)
|
||||
* 0 (success)
|
||||
* < 0 (error)
|
||||
*/
|
||||
|
||||
int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (start == end)
|
||||
return 0;
|
||||
struct meminfo *it;
|
||||
struct meminfo *rm = NULL;
|
||||
unsigned long sz;
|
||||
unsigned long bank_sz = 0;
|
||||
|
||||
start = start & PAGE_MASK;
|
||||
end = PAGE_ALIGN(end);
|
||||
sz = end - start;
|
||||
if (!sz)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < sysmem.nr_banks; i++)
|
||||
if (start < sysmem.bank[i].end
|
||||
&& end >= sysmem.bank[i].start)
|
||||
break;
|
||||
it = find_bank(start);
|
||||
|
||||
if (i == sysmem.nr_banks) {
|
||||
if (must_exist)
|
||||
printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) "
|
||||
"not in any region!\n", start, end);
|
||||
return 0;
|
||||
if (it)
|
||||
bank_sz = it->end - it->start;
|
||||
|
||||
if ((!it || end - it->start > bank_sz) && must_exist) {
|
||||
pr_warn("mem_reserve: [0x%0lx, 0x%0lx) not in any region!\n",
|
||||
start, end);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (start > sysmem.bank[i].start) {
|
||||
if (end < sysmem.bank[i].end) {
|
||||
/* split entry */
|
||||
if (sysmem.nr_banks >= SYSMEM_BANKS_MAX)
|
||||
panic("meminfo overflow\n");
|
||||
sysmem.bank[sysmem.nr_banks].start = end;
|
||||
sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end;
|
||||
sysmem.nr_banks++;
|
||||
if (it && start - it->start < bank_sz) {
|
||||
if (start == it->start) {
|
||||
if (end - it->start < bank_sz) {
|
||||
it->start = end;
|
||||
return 0;
|
||||
} else {
|
||||
rm = it;
|
||||
}
|
||||
} else {
|
||||
it->end = start;
|
||||
if (end - it->start < bank_sz)
|
||||
return add_sysmem_bank(end,
|
||||
it->start + bank_sz);
|
||||
++it;
|
||||
}
|
||||
sysmem.bank[i].end = start;
|
||||
|
||||
} else if (end < sysmem.bank[i].end) {
|
||||
sysmem.bank[i].start = end;
|
||||
|
||||
} else {
|
||||
/* remove entry */
|
||||
sysmem.nr_banks--;
|
||||
sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start;
|
||||
sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end;
|
||||
}
|
||||
return -1;
|
||||
|
||||
if (!it)
|
||||
it = sysmem.bank;
|
||||
|
||||
for (; it < sysmem.bank + sysmem.nr_banks; ++it) {
|
||||
if (it->end - start <= sz) {
|
||||
if (!rm)
|
||||
rm = it;
|
||||
} else {
|
||||
if (it->start - start < sz)
|
||||
it->start = end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rm)
|
||||
move_banks(rm, it);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,6 +239,7 @@ void __init bootmem_init(void)
|
|||
unsigned long bootmap_start, bootmap_size;
|
||||
int i;
|
||||
|
||||
sysmem_dump();
|
||||
max_low_pfn = max_pfn = 0;
|
||||
min_low_pfn = ~0;
|
||||
|
||||
|
@ -156,19 +297,13 @@ void __init bootmem_init(void)
|
|||
|
||||
void __init zones_init(void)
|
||||
{
|
||||
unsigned long zones_size[MAX_NR_ZONES];
|
||||
int i;
|
||||
|
||||
/* All pages are DMA-able, so we put them all in the DMA zone. */
|
||||
|
||||
zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET;
|
||||
for (i = 1; i < MAX_NR_ZONES; i++)
|
||||
zones_size[i] = 0;
|
||||
|
||||
unsigned long zones_size[MAX_NR_ZONES] = {
|
||||
[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET,
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
|
||||
[ZONE_HIGHMEM] = max_pfn - max_low_pfn,
|
||||
#endif
|
||||
|
||||
};
|
||||
free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
|
||||
}
|
||||
|
||||
|
@ -178,16 +313,38 @@ void __init zones_init(void)
|
|||
|
||||
void __init mem_init(void)
|
||||
{
|
||||
max_mapnr = max_low_pfn - ARCH_PFN_OFFSET;
|
||||
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#error HIGHGMEM not implemented in init.c
|
||||
unsigned long tmp;
|
||||
|
||||
reset_all_zones_managed_pages();
|
||||
for (tmp = max_low_pfn; tmp < max_pfn; tmp++)
|
||||
free_highmem_page(pfn_to_page(tmp));
|
||||
#endif
|
||||
|
||||
max_mapnr = max_pfn - ARCH_PFN_OFFSET;
|
||||
high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
|
||||
|
||||
free_all_bootmem();
|
||||
|
||||
mem_init_print_info(NULL);
|
||||
pr_info("virtual kernel memory layout:\n"
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
" pkmap : 0x%08lx - 0x%08lx (%5lu kB)\n"
|
||||
" fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n"
|
||||
#endif
|
||||
" vmalloc : 0x%08x - 0x%08x (%5u MB)\n"
|
||||
" lowmem : 0x%08x - 0x%08lx (%5lu MB)\n",
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE,
|
||||
(LAST_PKMAP*PAGE_SIZE) >> 10,
|
||||
FIXADDR_START, FIXADDR_TOP,
|
||||
(FIXADDR_TOP - FIXADDR_START) >> 10,
|
||||
#endif
|
||||
VMALLOC_START, VMALLOC_END,
|
||||
(VMALLOC_END - VMALLOC_START) >> 20,
|
||||
PAGE_OFFSET, PAGE_OFFSET +
|
||||
(max_low_pfn - min_low_pfn) * PAGE_SIZE,
|
||||
((max_low_pfn - min_low_pfn) * PAGE_SIZE) >> 20);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
|
@ -204,3 +361,53 @@ void free_initmem(void)
|
|||
{
|
||||
free_initmem_default(-1);
|
||||
}
|
||||
|
||||
static void __init parse_memmap_one(char *p)
|
||||
{
|
||||
char *oldp;
|
||||
unsigned long start_at, mem_size;
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
oldp = p;
|
||||
mem_size = memparse(p, &p);
|
||||
if (p == oldp)
|
||||
return;
|
||||
|
||||
switch (*p) {
|
||||
case '@':
|
||||
start_at = memparse(p + 1, &p);
|
||||
add_sysmem_bank(start_at, start_at + mem_size);
|
||||
break;
|
||||
|
||||
case '$':
|
||||
start_at = memparse(p + 1, &p);
|
||||
mem_reserve(start_at, start_at + mem_size, 0);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
mem_reserve(mem_size, 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_warn("Unrecognized memmap syntax: %s\n", p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int __init parse_memmap_opt(char *str)
|
||||
{
|
||||
while (str) {
|
||||
char *k = strchr(str, ',');
|
||||
|
||||
if (k)
|
||||
*k++ = 0;
|
||||
|
||||
parse_memmap_one(str);
|
||||
str = k;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("memmap", parse_memmap_opt);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Extracted from init.c
|
||||
*/
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
|
@ -16,9 +17,44 @@
|
|||
#include <asm/initialize_mmu.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#if defined(CONFIG_HIGHMEM)
|
||||
static void * __init init_pmd(unsigned long vaddr)
|
||||
{
|
||||
pgd_t *pgd = pgd_offset_k(vaddr);
|
||||
pmd_t *pmd = pmd_offset(pgd, vaddr);
|
||||
|
||||
if (pmd_none(*pmd)) {
|
||||
unsigned i;
|
||||
pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
|
||||
for (i = 0; i < 1024; i++)
|
||||
pte_clear(NULL, 0, pte + i);
|
||||
|
||||
set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK));
|
||||
BUG_ON(pte != pte_offset_kernel(pmd, 0));
|
||||
pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n",
|
||||
__func__, vaddr, pmd, pte);
|
||||
return pte;
|
||||
} else {
|
||||
return pte_offset_kernel(pmd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init fixedrange_init(void)
|
||||
{
|
||||
BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE);
|
||||
init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init paging_init(void)
|
||||
{
|
||||
memset(swapper_pg_dir, 0, PAGE_SIZE);
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
fixedrange_init();
|
||||
pkmap_page_table = init_pmd(PKMAP_BASE);
|
||||
kmap_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -149,6 +149,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
|
|||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
if (end > start && start >= TASK_SIZE && end <= PAGE_OFFSET &&
|
||||
end - start < _TLB_ENTRIES << PAGE_SHIFT) {
|
||||
start &= PAGE_MASK;
|
||||
while (start < end) {
|
||||
invalidate_itlb_mapping(start);
|
||||
invalidate_dtlb_mapping(start);
|
||||
start += PAGE_SIZE;
|
||||
}
|
||||
} else {
|
||||
local_flush_tlb_all();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_TLB_SANITY
|
||||
|
||||
static unsigned get_pte_for_vaddr(unsigned vaddr)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# "prom monitor" library routines under Linux.
|
||||
#
|
||||
|
||||
obj-y = console.o setup.o
|
||||
obj-y = setup.o
|
||||
obj-$(CONFIG_TTY) += console.o
|
||||
obj-$(CONFIG_NET) += network.o
|
||||
obj-$(CONFIG_BLK_DEV_SIMDISK) += simdisk.o
|
||||
|
|
|
@ -92,18 +92,8 @@ void __init platform_setup(char** cmdline)
|
|||
|
||||
/* early initialization */
|
||||
|
||||
extern sysmem_info_t __initdata sysmem;
|
||||
|
||||
void platform_init(bp_tag_t* first)
|
||||
void __init platform_init(bp_tag_t *first)
|
||||
{
|
||||
/* Set default memory block if not provided by the bootloader. */
|
||||
|
||||
if (sysmem.nr_banks == 0) {
|
||||
sysmem.nr_banks = 1;
|
||||
sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START;
|
||||
sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START
|
||||
+ PLATFORM_DEFAULT_MEM_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Heartbeat. Let the LED blink. */
|
||||
|
|
|
@ -466,7 +466,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
|||
type -= CRYPTO_MSG_BASE;
|
||||
link = &crypto_dispatch[type];
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
if (!netlink_capable(skb, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
|
||||
|
|
|
@ -405,7 +405,6 @@ static int acpi_processor_add(struct acpi_device *device,
|
|||
goto err;
|
||||
|
||||
pr->dev = dev;
|
||||
dev->offline = pr->flags.need_hotplug_init;
|
||||
|
||||
/* Trigger the processor driver's .probe() if present. */
|
||||
if (device_attach(dev) >= 0)
|
||||
|
|
|
@ -3067,7 +3067,10 @@ static int raw_cmd_copyout(int cmd, void __user *param,
|
|||
int ret;
|
||||
|
||||
while (ptr) {
|
||||
ret = copy_to_user(param, ptr, sizeof(*ptr));
|
||||
struct floppy_raw_cmd cmd = *ptr;
|
||||
cmd.next = NULL;
|
||||
cmd.kernel_data = NULL;
|
||||
ret = copy_to_user(param, &cmd, sizeof(cmd));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
param += sizeof(struct floppy_raw_cmd);
|
||||
|
@ -3121,10 +3124,11 @@ static int raw_cmd_copyin(int cmd, void __user *param,
|
|||
return -ENOMEM;
|
||||
*rcmd = ptr;
|
||||
ret = copy_from_user(ptr, param, sizeof(*ptr));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
ptr->next = NULL;
|
||||
ptr->buffer_length = 0;
|
||||
ptr->kernel_data = NULL;
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
param += sizeof(struct floppy_raw_cmd);
|
||||
if (ptr->cmd_count > 33)
|
||||
/* the command may now also take up the space
|
||||
|
@ -3140,7 +3144,6 @@ static int raw_cmd_copyin(int cmd, void __user *param,
|
|||
for (i = 0; i < 16; i++)
|
||||
ptr->reply[i] = 0;
|
||||
ptr->resultcode = 0;
|
||||
ptr->kernel_data = NULL;
|
||||
|
||||
if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
|
||||
if (ptr->length <= 0)
|
||||
|
|
|
@ -82,6 +82,7 @@ static const struct usb_device_id ath3k_table[] = {
|
|||
{ USB_DEVICE(0x04CA, 0x3004) },
|
||||
{ USB_DEVICE(0x04CA, 0x3005) },
|
||||
{ USB_DEVICE(0x04CA, 0x3006) },
|
||||
{ USB_DEVICE(0x04CA, 0x3007) },
|
||||
{ USB_DEVICE(0x04CA, 0x3008) },
|
||||
{ USB_DEVICE(0x04CA, 0x300b) },
|
||||
{ USB_DEVICE(0x0930, 0x0219) },
|
||||
|
@ -131,6 +132,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
|
|||
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
|
|
|
@ -152,6 +152,7 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
|
@ -1485,10 +1486,8 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
if (id->driver_info & BTUSB_BCM92035)
|
||||
hdev->setup = btusb_setup_bcm92035;
|
||||
|
||||
if (id->driver_info & BTUSB_INTEL) {
|
||||
usb_enable_autosuspend(data->udev);
|
||||
if (id->driver_info & BTUSB_INTEL)
|
||||
hdev->setup = btusb_setup_intel;
|
||||
}
|
||||
|
||||
/* Interface numbers are hardcoded in the specification */
|
||||
data->isoc = usb_ifnum_to_if(data->udev, 1);
|
||||
|
|
|
@ -730,6 +730,7 @@ static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg)
|
|||
|
||||
agp_copy_info(agp_bridge, &kerninfo);
|
||||
|
||||
memset(&userinfo, 0, sizeof(userinfo));
|
||||
userinfo.version.major = kerninfo.version.major;
|
||||
userinfo.version.minor = kerninfo.version.minor;
|
||||
userinfo.bridge_id = kerninfo.device->vendor |
|
||||
|
|
|
@ -328,13 +328,11 @@ int tpm_add_ppi(struct kobject *parent)
|
|||
/* Cache TPM ACPI handle and version string */
|
||||
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
|
||||
ppi_callback, NULL, NULL, &tpm_ppi_handle);
|
||||
if (tpm_ppi_handle == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
return sysfs_create_group(parent, &ppi_attr_grp);
|
||||
return tpm_ppi_handle ? sysfs_create_group(parent, &ppi_attr_grp) : 0;
|
||||
}
|
||||
|
||||
void tpm_remove_ppi(struct kobject *parent)
|
||||
{
|
||||
sysfs_remove_group(parent, &ppi_attr_grp);
|
||||
if (tpm_ppi_handle)
|
||||
sysfs_remove_group(parent, &ppi_attr_grp);
|
||||
}
|
||||
|
|
|
@ -369,7 +369,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
|
|||
return;
|
||||
|
||||
/* Can only change if privileged. */
|
||||
if (!capable(CAP_NET_ADMIN)) {
|
||||
if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
|
||||
err = EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -1954,6 +1954,9 @@ struct drm_i915_cmd_table {
|
|||
#define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev))
|
||||
#define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \
|
||||
((dev)->pdev->device & 0x00F0) == 0x0020)
|
||||
/* ULX machines are also considered ULT. */
|
||||
#define IS_HSW_ULX(dev) ((dev)->pdev->device == 0x0A0E || \
|
||||
(dev)->pdev->device == 0x0A1E)
|
||||
#define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
|
||||
|
||||
/*
|
||||
|
|
|
@ -34,25 +34,35 @@ static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv);
|
|||
|
||||
bool intel_enable_ppgtt(struct drm_device *dev, bool full)
|
||||
{
|
||||
if (i915.enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev))
|
||||
if (i915.enable_ppgtt == 0)
|
||||
return false;
|
||||
|
||||
if (i915.enable_ppgtt == 1 && full)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
|
||||
{
|
||||
if (enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev))
|
||||
return 0;
|
||||
|
||||
if (enable_ppgtt == 1)
|
||||
return 1;
|
||||
|
||||
if (enable_ppgtt == 2 && HAS_PPGTT(dev))
|
||||
return 2;
|
||||
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
/* Disable ppgtt on SNB if VT-d is on. */
|
||||
if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) {
|
||||
DRM_INFO("Disabling PPGTT because VT-d is on\n");
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Full ppgtt disabled by default for now due to issues. */
|
||||
if (full)
|
||||
return HAS_PPGTT(dev) && (i915.enable_ppgtt == 2);
|
||||
else
|
||||
return HAS_ALIASING_PPGTT(dev);
|
||||
return HAS_ALIASING_PPGTT(dev) ? 1 : 0;
|
||||
}
|
||||
|
||||
#define GEN6_PPGTT_PD_ENTRIES 512
|
||||
|
@ -2031,6 +2041,14 @@ int i915_gem_gtt_init(struct drm_device *dev)
|
|||
gtt->base.total >> 20);
|
||||
DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20);
|
||||
DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20);
|
||||
/*
|
||||
* i915.enable_ppgtt is read-only, so do an early pass to validate the
|
||||
* user's requested state against the hardware/driver capabilities. We
|
||||
* do this now so that we can print out any log messages once rather
|
||||
* than every time we check intel_enable_ppgtt().
|
||||
*/
|
||||
i915.enable_ppgtt = sanitize_enable_ppgtt(dev, i915.enable_ppgtt);
|
||||
DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11395,15 +11395,6 @@ void intel_modeset_init(struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
intel_connector_break_all_links(struct intel_connector *connector)
|
||||
{
|
||||
connector->base.dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->base.encoder = NULL;
|
||||
connector->encoder->connectors_active = false;
|
||||
connector->encoder->base.crtc = NULL;
|
||||
}
|
||||
|
||||
static void intel_enable_pipe_a(struct drm_device *dev)
|
||||
{
|
||||
struct intel_connector *connector;
|
||||
|
@ -11485,8 +11476,17 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
|
|||
if (connector->encoder->base.crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
intel_connector_break_all_links(connector);
|
||||
connector->base.dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->base.encoder = NULL;
|
||||
}
|
||||
/* multiple connectors may have the same encoder:
|
||||
* handle them and break crtc link separately */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
||||
base.head)
|
||||
if (connector->encoder->base.crtc == &crtc->base) {
|
||||
connector->encoder->base.crtc = NULL;
|
||||
connector->encoder->connectors_active = false;
|
||||
}
|
||||
|
||||
WARN_ON(crtc->active);
|
||||
crtc->base.enabled = false;
|
||||
|
@ -11568,6 +11568,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
|
|||
drm_get_encoder_name(&encoder->base));
|
||||
encoder->disable(encoder);
|
||||
}
|
||||
encoder->base.crtc = NULL;
|
||||
encoder->connectors_active = false;
|
||||
|
||||
/* Inconsistent output/port/pipe state happens presumably due to
|
||||
* a bug in one of the get_hw_state functions. Or someplace else
|
||||
|
@ -11578,8 +11580,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
|
|||
base.head) {
|
||||
if (connector->encoder != encoder)
|
||||
continue;
|
||||
|
||||
intel_connector_break_all_links(connector);
|
||||
connector->base.dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->base.encoder = NULL;
|
||||
}
|
||||
}
|
||||
/* Enabled encoders without active connectors will be fixed in
|
||||
|
|
|
@ -105,7 +105,8 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp)
|
|||
case DP_LINK_BW_2_7:
|
||||
break;
|
||||
case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */
|
||||
if ((IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) &&
|
||||
if (((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) ||
|
||||
INTEL_INFO(dev)->gen >= 8) &&
|
||||
intel_dp->dpcd[DP_DPCD_REV] >= 0x12)
|
||||
max_link_bw = DP_LINK_BW_5_4;
|
||||
else
|
||||
|
|
|
@ -863,7 +863,7 @@ gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
|
|||
{
|
||||
mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
|
||||
mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
|
||||
mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
|
||||
mmio_data(0x200000, 0x1000, NV_MEM_ACCESS_RW);
|
||||
|
||||
mmio_list(0x40800c, 0x00000000, 8, 1);
|
||||
mmio_list(0x408010, 0x80000000, 0, 0);
|
||||
|
@ -877,6 +877,8 @@ gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
|
|||
mmio_list(0x418e24, 0x00000000, 8, 0);
|
||||
mmio_list(0x418e28, 0x80000030, 0, 0);
|
||||
|
||||
mmio_list(0x4064c8, 0x018002c0, 0, 0);
|
||||
|
||||
mmio_list(0x418810, 0x80000000, 12, 2);
|
||||
mmio_list(0x419848, 0x10000000, 12, 2);
|
||||
mmio_list(0x419c2c, 0x10000000, 12, 2);
|
||||
|
|
|
@ -168,7 +168,8 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
|
|||
*/
|
||||
i = 16;
|
||||
do {
|
||||
if ((nv_rd32(bios, 0x300000) & 0xffff) == 0xaa55)
|
||||
u32 data = le32_to_cpu(nv_rd32(bios, 0x300000)) & 0xffff;
|
||||
if (data == 0xaa55)
|
||||
break;
|
||||
} while (i--);
|
||||
|
||||
|
@ -176,14 +177,15 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
|
|||
goto out;
|
||||
|
||||
/* read entire bios image to system memory */
|
||||
bios->size = ((nv_rd32(bios, 0x300000) >> 16) & 0xff) * 512;
|
||||
bios->size = (le32_to_cpu(nv_rd32(bios, 0x300000)) >> 16) & 0xff;
|
||||
bios->size = bios->size * 512;
|
||||
if (!bios->size)
|
||||
goto out;
|
||||
|
||||
bios->data = kmalloc(bios->size, GFP_KERNEL);
|
||||
if (bios->data) {
|
||||
for (i = 0; i < bios->size; i+=4)
|
||||
nv_wo32(bios, i, nv_rd32(bios, 0x300000 + i));
|
||||
for (i = 0; i < bios->size; i += 4)
|
||||
((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i);
|
||||
}
|
||||
|
||||
/* check the PCI record header */
|
||||
|
|
|
@ -389,9 +389,6 @@ bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
|
|||
acpi_status status;
|
||||
acpi_handle dhandle, rom_handle;
|
||||
|
||||
if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected)
|
||||
return false;
|
||||
|
||||
dhandle = ACPI_HANDLE(&pdev->dev);
|
||||
if (!dhandle)
|
||||
return false;
|
||||
|
|
|
@ -764,9 +764,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|||
}
|
||||
|
||||
ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
|
||||
mutex_unlock(&chan->cli->mutex);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
mutex_unlock(&chan->cli->mutex);
|
||||
|
||||
/* Update the crtc struct and cleanup */
|
||||
crtc->primary->fb = fb;
|
||||
|
|
|
@ -1177,27 +1177,43 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
|
||||
/* Set NUM_BANKS. */
|
||||
if (rdev->family >= CHIP_TAHITI) {
|
||||
unsigned tileb, index, num_banks, tile_split_bytes;
|
||||
unsigned index, num_banks;
|
||||
|
||||
/* Calculate the macrotile mode index. */
|
||||
tile_split_bytes = 64 << tile_split;
|
||||
tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
|
||||
tileb = min(tile_split_bytes, tileb);
|
||||
if (rdev->family >= CHIP_BONAIRE) {
|
||||
unsigned tileb, tile_split_bytes;
|
||||
|
||||
for (index = 0; tileb > 64; index++) {
|
||||
tileb >>= 1;
|
||||
}
|
||||
/* Calculate the macrotile mode index. */
|
||||
tile_split_bytes = 64 << tile_split;
|
||||
tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
|
||||
tileb = min(tile_split_bytes, tileb);
|
||||
|
||||
if (index >= 16) {
|
||||
DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
|
||||
target_fb->bits_per_pixel, tile_split);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (index = 0; tileb > 64; index++)
|
||||
tileb >>= 1;
|
||||
|
||||
if (index >= 16) {
|
||||
DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
|
||||
target_fb->bits_per_pixel, tile_split);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rdev->family >= CHIP_BONAIRE)
|
||||
num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3;
|
||||
else
|
||||
} else {
|
||||
switch (target_fb->bits_per_pixel) {
|
||||
case 8:
|
||||
index = 10;
|
||||
break;
|
||||
case 16:
|
||||
index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
|
||||
break;
|
||||
default:
|
||||
case 32:
|
||||
index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
|
||||
break;
|
||||
}
|
||||
|
||||
num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3;
|
||||
}
|
||||
|
||||
fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks);
|
||||
} else {
|
||||
/* NI and older. */
|
||||
|
@ -1720,8 +1736,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||
}
|
||||
/* otherwise, pick one of the plls */
|
||||
if ((rdev->family == CHIP_KAVERI) ||
|
||||
(rdev->family == CHIP_KABINI)) {
|
||||
/* KB/KV has PPLL1 and PPLL2 */
|
||||
(rdev->family == CHIP_KABINI) ||
|
||||
(rdev->family == CHIP_MULLINS)) {
|
||||
/* KB/KV/ML has PPLL1 and PPLL2 */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
|
@ -1885,6 +1902,9 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
|
|||
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
|
||||
is_tvcv = true;
|
||||
|
||||
if (!radeon_crtc->adjusted_clock)
|
||||
return -EINVAL;
|
||||
|
||||
atombios_crtc_set_pll(crtc, adjusted_mode);
|
||||
|
||||
if (ASIC_IS_DCE4(rdev))
|
||||
|
|
|
@ -366,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
|
|||
if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
|
||||
return;
|
||||
|
||||
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3))
|
||||
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3)
|
||||
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
|
||||
buf[0], buf[1], buf[2]);
|
||||
|
||||
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3))
|
||||
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
|
||||
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
|
||||
buf[0], buf[1], buf[2]);
|
||||
}
|
||||
|
@ -419,21 +419,23 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
|
|||
|
||||
if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
|
||||
/* DP bridge chips */
|
||||
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
|
||||
DP_EDP_CONFIGURATION_CAP, &tmp);
|
||||
if (tmp & 1)
|
||||
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
|
||||
else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
|
||||
(dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
|
||||
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
|
||||
else
|
||||
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
|
||||
if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
|
||||
DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
|
||||
if (tmp & 1)
|
||||
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
|
||||
else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
|
||||
(dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
|
||||
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
|
||||
else
|
||||
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
|
||||
}
|
||||
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
|
||||
/* eDP */
|
||||
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
|
||||
DP_EDP_CONFIGURATION_CAP, &tmp);
|
||||
if (tmp & 1)
|
||||
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
|
||||
if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
|
||||
DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
|
||||
if (tmp & 1)
|
||||
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
return panel_mode;
|
||||
|
@ -809,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
|
|||
else
|
||||
dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
|
||||
|
||||
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp);
|
||||
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
|
||||
dp_info.tp3_supported = true;
|
||||
else
|
||||
if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp)
|
||||
== 1) {
|
||||
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
|
||||
dp_info.tp3_supported = true;
|
||||
else
|
||||
dp_info.tp3_supported = false;
|
||||
} else {
|
||||
dp_info.tp3_supported = false;
|
||||
}
|
||||
|
||||
memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
|
||||
dp_info.rdev = rdev;
|
||||
|
|
|
@ -63,6 +63,12 @@ MODULE_FIRMWARE("radeon/KABINI_ce.bin");
|
|||
MODULE_FIRMWARE("radeon/KABINI_mec.bin");
|
||||
MODULE_FIRMWARE("radeon/KABINI_rlc.bin");
|
||||
MODULE_FIRMWARE("radeon/KABINI_sdma.bin");
|
||||
MODULE_FIRMWARE("radeon/MULLINS_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/MULLINS_me.bin");
|
||||
MODULE_FIRMWARE("radeon/MULLINS_ce.bin");
|
||||
MODULE_FIRMWARE("radeon/MULLINS_mec.bin");
|
||||
MODULE_FIRMWARE("radeon/MULLINS_rlc.bin");
|
||||
MODULE_FIRMWARE("radeon/MULLINS_sdma.bin");
|
||||
|
||||
extern int r600_ih_ring_alloc(struct radeon_device *rdev);
|
||||
extern void r600_ih_ring_fini(struct radeon_device *rdev);
|
||||
|
@ -1473,6 +1479,43 @@ static const u32 hawaii_mgcg_cgcg_init[] =
|
|||
0xd80c, 0xff000ff0, 0x00000100
|
||||
};
|
||||
|
||||
static const u32 godavari_golden_registers[] =
|
||||
{
|
||||
0x55e4, 0xff607fff, 0xfc000100,
|
||||
0x6ed8, 0x00010101, 0x00010000,
|
||||
0x9830, 0xffffffff, 0x00000000,
|
||||
0x98302, 0xf00fffff, 0x00000400,
|
||||
0x6130, 0xffffffff, 0x00010000,
|
||||
0x5bb0, 0x000000f0, 0x00000070,
|
||||
0x5bc0, 0xf0311fff, 0x80300000,
|
||||
0x98f8, 0x73773777, 0x12010001,
|
||||
0x98fc, 0xffffffff, 0x00000010,
|
||||
0x8030, 0x00001f0f, 0x0000100a,
|
||||
0x2f48, 0x73773777, 0x12010001,
|
||||
0x2408, 0x000fffff, 0x000c007f,
|
||||
0x8a14, 0xf000003f, 0x00000007,
|
||||
0x8b24, 0xffffffff, 0x00ff0fff,
|
||||
0x30a04, 0x0000ff0f, 0x00000000,
|
||||
0x28a4c, 0x07ffffff, 0x06000000,
|
||||
0x4d8, 0x00000fff, 0x00000100,
|
||||
0xd014, 0x00010000, 0x00810001,
|
||||
0xd814, 0x00010000, 0x00810001,
|
||||
0x3e78, 0x00000001, 0x00000002,
|
||||
0xc768, 0x00000008, 0x00000008,
|
||||
0xc770, 0x00000f00, 0x00000800,
|
||||
0xc774, 0x00000f00, 0x00000800,
|
||||
0xc798, 0x00ffffff, 0x00ff7fbf,
|
||||
0xc79c, 0x00ffffff, 0x00ff7faf,
|
||||
0x8c00, 0x000000ff, 0x00000001,
|
||||
0x214f8, 0x01ff01ff, 0x00000002,
|
||||
0x21498, 0x007ff800, 0x00200000,
|
||||
0x2015c, 0xffffffff, 0x00000f40,
|
||||
0x88c4, 0x001f3ae3, 0x00000082,
|
||||
0x88d4, 0x0000001f, 0x00000010,
|
||||
0x30934, 0xffffffff, 0x00000000
|
||||
};
|
||||
|
||||
|
||||
static void cik_init_golden_registers(struct radeon_device *rdev)
|
||||
{
|
||||
switch (rdev->family) {
|
||||
|
@ -1504,6 +1547,20 @@ static void cik_init_golden_registers(struct radeon_device *rdev)
|
|||
kalindi_golden_spm_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
|
||||
break;
|
||||
case CHIP_MULLINS:
|
||||
radeon_program_register_sequence(rdev,
|
||||
kalindi_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init));
|
||||
radeon_program_register_sequence(rdev,
|
||||
godavari_golden_registers,
|
||||
(const u32)ARRAY_SIZE(godavari_golden_registers));
|
||||
radeon_program_register_sequence(rdev,
|
||||
kalindi_golden_common_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_common_registers));
|
||||
radeon_program_register_sequence(rdev,
|
||||
kalindi_golden_spm_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
|
||||
break;
|
||||
case CHIP_KAVERI:
|
||||
radeon_program_register_sequence(rdev,
|
||||
spectre_mgcg_cgcg_init,
|
||||
|
@ -1834,6 +1891,15 @@ static int cik_init_microcode(struct radeon_device *rdev)
|
|||
rlc_req_size = KB_RLC_UCODE_SIZE * 4;
|
||||
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
|
||||
break;
|
||||
case CHIP_MULLINS:
|
||||
chip_name = "MULLINS";
|
||||
pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
|
||||
me_req_size = CIK_ME_UCODE_SIZE * 4;
|
||||
ce_req_size = CIK_CE_UCODE_SIZE * 4;
|
||||
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
|
||||
rlc_req_size = ML_RLC_UCODE_SIZE * 4;
|
||||
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
|
||||
|
@ -3272,6 +3338,7 @@ static void cik_gpu_init(struct radeon_device *rdev)
|
|||
gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN;
|
||||
break;
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
default:
|
||||
rdev->config.cik.max_shader_engines = 1;
|
||||
rdev->config.cik.max_tile_pipes = 2;
|
||||
|
@ -3702,6 +3769,7 @@ int cik_copy_cpdma(struct radeon_device *rdev,
|
|||
r = radeon_fence_emit(rdev, fence, ring->idx);
|
||||
if (r) {
|
||||
radeon_ring_unlock_undo(rdev, ring);
|
||||
radeon_semaphore_free(rdev, &sem, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -5800,6 +5868,9 @@ static int cik_rlc_resume(struct radeon_device *rdev)
|
|||
case CHIP_KABINI:
|
||||
size = KB_RLC_UCODE_SIZE;
|
||||
break;
|
||||
case CHIP_MULLINS:
|
||||
size = ML_RLC_UCODE_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
cik_rlc_stop(rdev);
|
||||
|
@ -6548,6 +6619,7 @@ void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
|
|||
buffer[count++] = cpu_to_le32(0x00000000);
|
||||
break;
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
buffer[count++] = cpu_to_le32(0x00000000); /* XXX */
|
||||
buffer[count++] = cpu_to_le32(0x00000000);
|
||||
break;
|
||||
|
@ -6693,6 +6765,19 @@ static void cik_disable_interrupt_state(struct radeon_device *rdev)
|
|||
WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
||||
WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
/* pflip */
|
||||
if (rdev->num_crtc >= 2) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
||||
}
|
||||
if (rdev->num_crtc >= 4) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
||||
}
|
||||
if (rdev->num_crtc >= 6) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
|
||||
/* dac hotplug */
|
||||
WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
|
||||
|
@ -7049,6 +7134,25 @@ int cik_irq_set(struct radeon_device *rdev)
|
|||
WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
|
||||
}
|
||||
|
||||
if (rdev->num_crtc >= 2) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
}
|
||||
if (rdev->num_crtc >= 4) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
}
|
||||
if (rdev->num_crtc >= 6) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
}
|
||||
|
||||
WREG32(DC_HPD1_INT_CONTROL, hpd1);
|
||||
WREG32(DC_HPD2_INT_CONTROL, hpd2);
|
||||
WREG32(DC_HPD3_INT_CONTROL, hpd3);
|
||||
|
@ -7085,6 +7189,29 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
|
|||
rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
|
||||
rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6);
|
||||
|
||||
rdev->irq.stat_regs.cik.d1grph_int = RREG32(GRPH_INT_STATUS +
|
||||
EVERGREEN_CRTC0_REGISTER_OFFSET);
|
||||
rdev->irq.stat_regs.cik.d2grph_int = RREG32(GRPH_INT_STATUS +
|
||||
EVERGREEN_CRTC1_REGISTER_OFFSET);
|
||||
if (rdev->num_crtc >= 4) {
|
||||
rdev->irq.stat_regs.cik.d3grph_int = RREG32(GRPH_INT_STATUS +
|
||||
EVERGREEN_CRTC2_REGISTER_OFFSET);
|
||||
rdev->irq.stat_regs.cik.d4grph_int = RREG32(GRPH_INT_STATUS +
|
||||
EVERGREEN_CRTC3_REGISTER_OFFSET);
|
||||
}
|
||||
if (rdev->num_crtc >= 6) {
|
||||
rdev->irq.stat_regs.cik.d5grph_int = RREG32(GRPH_INT_STATUS +
|
||||
EVERGREEN_CRTC4_REGISTER_OFFSET);
|
||||
rdev->irq.stat_regs.cik.d6grph_int = RREG32(GRPH_INT_STATUS +
|
||||
EVERGREEN_CRTC5_REGISTER_OFFSET);
|
||||
}
|
||||
|
||||
if (rdev->irq.stat_regs.cik.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
|
||||
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_CLEAR);
|
||||
if (rdev->irq.stat_regs.cik.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
|
||||
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_CLEAR);
|
||||
if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)
|
||||
WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
|
||||
if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)
|
||||
|
@ -7095,6 +7222,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
|
|||
WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
|
||||
|
||||
if (rdev->num_crtc >= 4) {
|
||||
if (rdev->irq.stat_regs.cik.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
|
||||
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_CLEAR);
|
||||
if (rdev->irq.stat_regs.cik.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
|
||||
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_CLEAR);
|
||||
if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
|
||||
WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
|
||||
if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
|
||||
|
@ -7106,6 +7239,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev)
|
|||
}
|
||||
|
||||
if (rdev->num_crtc >= 6) {
|
||||
if (rdev->irq.stat_regs.cik.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
|
||||
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_CLEAR);
|
||||
if (rdev->irq.stat_regs.cik.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
|
||||
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_CLEAR);
|
||||
if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
|
||||
WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
|
||||
if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
|
||||
|
@ -7457,6 +7596,15 @@ int cik_irq_process(struct radeon_device *rdev)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 8: /* D1 page flip */
|
||||
case 10: /* D2 page flip */
|
||||
case 12: /* D3 page flip */
|
||||
case 14: /* D4 page flip */
|
||||
case 16: /* D5 page flip */
|
||||
case 18: /* D6 page flip */
|
||||
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
|
||||
radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
|
||||
break;
|
||||
case 42: /* HPD hotplug */
|
||||
switch (src_data) {
|
||||
case 0:
|
||||
|
|
|
@ -562,6 +562,7 @@ int cik_copy_dma(struct radeon_device *rdev,
|
|||
r = radeon_fence_emit(rdev, fence, ring->idx);
|
||||
if (r) {
|
||||
radeon_ring_unlock_undo(rdev, ring);
|
||||
radeon_semaphore_free(rdev, &sem, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -888,6 +888,15 @@
|
|||
# define DC_HPD6_RX_INTERRUPT (1 << 18)
|
||||
#define DISP_INTERRUPT_STATUS_CONTINUE6 0x6780
|
||||
|
||||
/* 0x6858, 0x7458, 0x10058, 0x10c58, 0x11858, 0x12458 */
|
||||
#define GRPH_INT_STATUS 0x6858
|
||||
# define GRPH_PFLIP_INT_OCCURRED (1 << 0)
|
||||
# define GRPH_PFLIP_INT_CLEAR (1 << 8)
|
||||
/* 0x685c, 0x745c, 0x1005c, 0x10c5c, 0x1185c, 0x1245c */
|
||||
#define GRPH_INT_CONTROL 0x685c
|
||||
# define GRPH_PFLIP_INT_MASK (1 << 0)
|
||||
# define GRPH_PFLIP_INT_TYPE (1 << 8)
|
||||
|
||||
#define DAC_AUTODETECT_INT_CONTROL 0x67c8
|
||||
|
||||
#define DC_HPD1_INT_STATUS 0x601c
|
||||
|
|
|
@ -4371,7 +4371,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
|
|||
u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
|
||||
u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
|
||||
u32 grbm_int_cntl = 0;
|
||||
u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
|
||||
u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0;
|
||||
u32 dma_cntl, dma_cntl1 = 0;
|
||||
u32 thermal_int = 0;
|
||||
|
@ -4554,15 +4553,21 @@ int evergreen_irq_set(struct radeon_device *rdev)
|
|||
WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
|
||||
}
|
||||
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
if (rdev->num_crtc >= 4) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
}
|
||||
if (rdev->num_crtc >= 6) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
||||
GRPH_PFLIP_INT_MASK);
|
||||
}
|
||||
|
||||
WREG32(DC_HPD1_INT_CONTROL, hpd1);
|
||||
|
@ -4951,6 +4956,15 @@ int evergreen_irq_process(struct radeon_device *rdev)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 8: /* D1 page flip */
|
||||
case 10: /* D2 page flip */
|
||||
case 12: /* D3 page flip */
|
||||
case 14: /* D4 page flip */
|
||||
case 16: /* D5 page flip */
|
||||
case 18: /* D6 page flip */
|
||||
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
|
||||
radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
|
||||
break;
|
||||
case 42: /* HPD hotplug */
|
||||
switch (src_data) {
|
||||
case 0:
|
||||
|
|
|
@ -151,6 +151,7 @@ int evergreen_copy_dma(struct radeon_device *rdev,
|
|||
r = radeon_fence_emit(rdev, fence, ring->idx);
|
||||
if (r) {
|
||||
radeon_ring_unlock_undo(rdev, ring);
|
||||
radeon_semaphore_free(rdev, &sem, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -546,6 +546,52 @@ static int kv_set_divider_value(struct radeon_device *rdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u32 kv_convert_vid2_to_vid7(struct radeon_device *rdev,
|
||||
struct sumo_vid_mapping_table *vid_mapping_table,
|
||||
u32 vid_2bit)
|
||||
{
|
||||
struct radeon_clock_voltage_dependency_table *vddc_sclk_table =
|
||||
&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
|
||||
u32 i;
|
||||
|
||||
if (vddc_sclk_table && vddc_sclk_table->count) {
|
||||
if (vid_2bit < vddc_sclk_table->count)
|
||||
return vddc_sclk_table->entries[vid_2bit].v;
|
||||
else
|
||||
return vddc_sclk_table->entries[vddc_sclk_table->count - 1].v;
|
||||
} else {
|
||||
for (i = 0; i < vid_mapping_table->num_entries; i++) {
|
||||
if (vid_mapping_table->entries[i].vid_2bit == vid_2bit)
|
||||
return vid_mapping_table->entries[i].vid_7bit;
|
||||
}
|
||||
return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 kv_convert_vid7_to_vid2(struct radeon_device *rdev,
|
||||
struct sumo_vid_mapping_table *vid_mapping_table,
|
||||
u32 vid_7bit)
|
||||
{
|
||||
struct radeon_clock_voltage_dependency_table *vddc_sclk_table =
|
||||
&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
|
||||
u32 i;
|
||||
|
||||
if (vddc_sclk_table && vddc_sclk_table->count) {
|
||||
for (i = 0; i < vddc_sclk_table->count; i++) {
|
||||
if (vddc_sclk_table->entries[i].v == vid_7bit)
|
||||
return i;
|
||||
}
|
||||
return vddc_sclk_table->count - 1;
|
||||
} else {
|
||||
for (i = 0; i < vid_mapping_table->num_entries; i++) {
|
||||
if (vid_mapping_table->entries[i].vid_7bit == vid_7bit)
|
||||
return vid_mapping_table->entries[i].vid_2bit;
|
||||
}
|
||||
|
||||
return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit;
|
||||
}
|
||||
}
|
||||
|
||||
static u16 kv_convert_8bit_index_to_voltage(struct radeon_device *rdev,
|
||||
u16 voltage)
|
||||
{
|
||||
|
@ -556,9 +602,9 @@ static u16 kv_convert_2bit_index_to_voltage(struct radeon_device *rdev,
|
|||
u32 vid_2bit)
|
||||
{
|
||||
struct kv_power_info *pi = kv_get_pi(rdev);
|
||||
u32 vid_8bit = sumo_convert_vid2_to_vid7(rdev,
|
||||
&pi->sys_info.vid_mapping_table,
|
||||
vid_2bit);
|
||||
u32 vid_8bit = kv_convert_vid2_to_vid7(rdev,
|
||||
&pi->sys_info.vid_mapping_table,
|
||||
vid_2bit);
|
||||
|
||||
return kv_convert_8bit_index_to_voltage(rdev, (u16)vid_8bit);
|
||||
}
|
||||
|
@ -639,7 +685,7 @@ static int kv_force_lowest_valid(struct radeon_device *rdev)
|
|||
|
||||
static int kv_unforce_levels(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->family == CHIP_KABINI)
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
|
||||
return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel);
|
||||
else
|
||||
return kv_set_enabled_levels(rdev);
|
||||
|
@ -1362,13 +1408,20 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate)
|
|||
struct radeon_uvd_clock_voltage_dependency_table *table =
|
||||
&rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
|
||||
int ret;
|
||||
u32 mask;
|
||||
|
||||
if (!gate) {
|
||||
if (!pi->caps_uvd_dpm || table->count || pi->caps_stable_p_state)
|
||||
if (table->count)
|
||||
pi->uvd_boot_level = table->count - 1;
|
||||
else
|
||||
pi->uvd_boot_level = 0;
|
||||
|
||||
if (!pi->caps_uvd_dpm || pi->caps_stable_p_state) {
|
||||
mask = 1 << pi->uvd_boot_level;
|
||||
} else {
|
||||
mask = 0x1f;
|
||||
}
|
||||
|
||||
ret = kv_copy_bytes_to_smc(rdev,
|
||||
pi->dpm_table_start +
|
||||
offsetof(SMU7_Fusion_DpmTable, UvdBootLevel),
|
||||
|
@ -1377,11 +1430,9 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!pi->caps_uvd_dpm ||
|
||||
pi->caps_stable_p_state)
|
||||
kv_send_msg_to_smc_with_parameter(rdev,
|
||||
PPSMC_MSG_UVDDPM_SetEnabledMask,
|
||||
(1 << pi->uvd_boot_level));
|
||||
kv_send_msg_to_smc_with_parameter(rdev,
|
||||
PPSMC_MSG_UVDDPM_SetEnabledMask,
|
||||
mask);
|
||||
}
|
||||
|
||||
return kv_enable_uvd_dpm(rdev, !gate);
|
||||
|
@ -1617,7 +1668,7 @@ static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate)
|
|||
if (pi->acp_power_gated == gate)
|
||||
return;
|
||||
|
||||
if (rdev->family == CHIP_KABINI)
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
|
||||
return;
|
||||
|
||||
pi->acp_power_gated = gate;
|
||||
|
@ -1786,7 +1837,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (rdev->family == CHIP_KABINI) {
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
|
||||
if (pi->enable_dpm) {
|
||||
kv_set_valid_clock_range(rdev, new_ps);
|
||||
kv_update_dfs_bypass_settings(rdev, new_ps);
|
||||
|
@ -1812,6 +1863,8 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
|
|||
return ret;
|
||||
}
|
||||
kv_update_sclk_t(rdev);
|
||||
if (rdev->family == CHIP_MULLINS)
|
||||
kv_enable_nb_dpm(rdev);
|
||||
}
|
||||
} else {
|
||||
if (pi->enable_dpm) {
|
||||
|
@ -1862,7 +1915,7 @@ void kv_dpm_reset_asic(struct radeon_device *rdev)
|
|||
{
|
||||
struct kv_power_info *pi = kv_get_pi(rdev);
|
||||
|
||||
if (rdev->family == CHIP_KABINI) {
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
|
||||
kv_force_lowest_valid(rdev);
|
||||
kv_init_graphics_levels(rdev);
|
||||
kv_program_bootup_state(rdev);
|
||||
|
@ -1901,14 +1954,41 @@ static void kv_construct_max_power_limits_table(struct radeon_device *rdev,
|
|||
static void kv_patch_voltage_values(struct radeon_device *rdev)
|
||||
{
|
||||
int i;
|
||||
struct radeon_uvd_clock_voltage_dependency_table *table =
|
||||
struct radeon_uvd_clock_voltage_dependency_table *uvd_table =
|
||||
&rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
|
||||
struct radeon_vce_clock_voltage_dependency_table *vce_table =
|
||||
&rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
|
||||
struct radeon_clock_voltage_dependency_table *samu_table =
|
||||
&rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table;
|
||||
struct radeon_clock_voltage_dependency_table *acp_table =
|
||||
&rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
|
||||
|
||||
if (table->count) {
|
||||
for (i = 0; i < table->count; i++)
|
||||
table->entries[i].v =
|
||||
if (uvd_table->count) {
|
||||
for (i = 0; i < uvd_table->count; i++)
|
||||
uvd_table->entries[i].v =
|
||||
kv_convert_8bit_index_to_voltage(rdev,
|
||||
table->entries[i].v);
|
||||
uvd_table->entries[i].v);
|
||||
}
|
||||
|
||||
if (vce_table->count) {
|
||||
for (i = 0; i < vce_table->count; i++)
|
||||
vce_table->entries[i].v =
|
||||
kv_convert_8bit_index_to_voltage(rdev,
|
||||
vce_table->entries[i].v);
|
||||
}
|
||||
|
||||
if (samu_table->count) {
|
||||
for (i = 0; i < samu_table->count; i++)
|
||||
samu_table->entries[i].v =
|
||||
kv_convert_8bit_index_to_voltage(rdev,
|
||||
samu_table->entries[i].v);
|
||||
}
|
||||
|
||||
if (acp_table->count) {
|
||||
for (i = 0; i < acp_table->count; i++)
|
||||
acp_table->entries[i].v =
|
||||
kv_convert_8bit_index_to_voltage(rdev,
|
||||
acp_table->entries[i].v);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1941,7 +2021,7 @@ static int kv_force_dpm_highest(struct radeon_device *rdev)
|
|||
break;
|
||||
}
|
||||
|
||||
if (rdev->family == CHIP_KABINI)
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
|
||||
return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i);
|
||||
else
|
||||
return kv_set_enabled_level(rdev, i);
|
||||
|
@ -1961,7 +2041,7 @@ static int kv_force_dpm_lowest(struct radeon_device *rdev)
|
|||
break;
|
||||
}
|
||||
|
||||
if (rdev->family == CHIP_KABINI)
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
|
||||
return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i);
|
||||
else
|
||||
return kv_set_enabled_level(rdev, i);
|
||||
|
@ -2118,7 +2198,7 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
|
|||
else
|
||||
pi->battery_state = false;
|
||||
|
||||
if (rdev->family == CHIP_KABINI) {
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
|
||||
ps->dpm0_pg_nb_ps_lo = 0x1;
|
||||
ps->dpm0_pg_nb_ps_hi = 0x0;
|
||||
ps->dpmx_nb_ps_lo = 0x1;
|
||||
|
@ -2179,7 +2259,7 @@ static int kv_calculate_nbps_level_settings(struct radeon_device *rdev)
|
|||
if (pi->lowest_valid > pi->highest_valid)
|
||||
return -EINVAL;
|
||||
|
||||
if (rdev->family == CHIP_KABINI) {
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
|
||||
for (i = pi->lowest_valid; i <= pi->highest_valid; i++) {
|
||||
pi->graphics_level[i].GnbSlow = 1;
|
||||
pi->graphics_level[i].ForceNbPs1 = 0;
|
||||
|
@ -2253,9 +2333,9 @@ static void kv_init_graphics_levels(struct radeon_device *rdev)
|
|||
break;
|
||||
|
||||
kv_set_divider_value(rdev, i, table->entries[i].clk);
|
||||
vid_2bit = sumo_convert_vid7_to_vid2(rdev,
|
||||
&pi->sys_info.vid_mapping_table,
|
||||
table->entries[i].v);
|
||||
vid_2bit = kv_convert_vid7_to_vid2(rdev,
|
||||
&pi->sys_info.vid_mapping_table,
|
||||
table->entries[i].v);
|
||||
kv_set_vid(rdev, i, vid_2bit);
|
||||
kv_set_at(rdev, i, pi->at[i]);
|
||||
kv_dpm_power_level_enabled_for_throttle(rdev, i, true);
|
||||
|
@ -2324,7 +2404,7 @@ static void kv_program_nbps_index_settings(struct radeon_device *rdev,
|
|||
struct kv_power_info *pi = kv_get_pi(rdev);
|
||||
u32 nbdpmconfig1;
|
||||
|
||||
if (rdev->family == CHIP_KABINI)
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
|
||||
return;
|
||||
|
||||
if (pi->sys_info.nb_dpm_enable) {
|
||||
|
@ -2631,9 +2711,6 @@ int kv_dpm_init(struct radeon_device *rdev)
|
|||
|
||||
pi->sram_end = SMC_RAM_END;
|
||||
|
||||
if (rdev->family == CHIP_KABINI)
|
||||
pi->high_voltage_t = 4001;
|
||||
|
||||
pi->enable_nb_dpm = true;
|
||||
|
||||
pi->caps_power_containment = true;
|
||||
|
|
|
@ -2839,6 +2839,7 @@ int r600_copy_cpdma(struct radeon_device *rdev,
|
|||
r = radeon_fence_emit(rdev, fence, ring->idx);
|
||||
if (r) {
|
||||
radeon_ring_unlock_undo(rdev, ring);
|
||||
radeon_semaphore_free(rdev, &sem, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -3505,7 +3506,6 @@ int r600_irq_set(struct radeon_device *rdev)
|
|||
u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
|
||||
u32 grbm_int_cntl = 0;
|
||||
u32 hdmi0, hdmi1;
|
||||
u32 d1grph = 0, d2grph = 0;
|
||||
u32 dma_cntl;
|
||||
u32 thermal_int = 0;
|
||||
|
||||
|
@ -3614,8 +3614,8 @@ int r600_irq_set(struct radeon_device *rdev)
|
|||
WREG32(CP_INT_CNTL, cp_int_cntl);
|
||||
WREG32(DMA_CNTL, dma_cntl);
|
||||
WREG32(DxMODE_INT_MASK, mode_int);
|
||||
WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph);
|
||||
WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph);
|
||||
WREG32(D1GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
|
||||
WREG32(D2GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
|
||||
WREG32(GRBM_INT_CNTL, grbm_int_cntl);
|
||||
if (ASIC_IS_DCE3(rdev)) {
|
||||
WREG32(DC_HPD1_INT_CONTROL, hpd1);
|
||||
|
@ -3918,6 +3918,14 @@ int r600_irq_process(struct radeon_device *rdev)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 9: /* D1 pflip */
|
||||
DRM_DEBUG("IH: D1 flip\n");
|
||||
radeon_crtc_handle_flip(rdev, 0);
|
||||
break;
|
||||
case 11: /* D2 pflip */
|
||||
DRM_DEBUG("IH: D2 flip\n");
|
||||
radeon_crtc_handle_flip(rdev, 1);
|
||||
break;
|
||||
case 19: /* HPD/DAC hotplug */
|
||||
switch (src_data) {
|
||||
case 0:
|
||||
|
|
|
@ -489,6 +489,7 @@ int r600_copy_dma(struct radeon_device *rdev,
|
|||
r = radeon_fence_emit(rdev, fence, ring->idx);
|
||||
if (r) {
|
||||
radeon_ring_unlock_undo(rdev, ring);
|
||||
radeon_semaphore_free(rdev, &sem, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -730,6 +730,12 @@ struct cik_irq_stat_regs {
|
|||
u32 disp_int_cont4;
|
||||
u32 disp_int_cont5;
|
||||
u32 disp_int_cont6;
|
||||
u32 d1grph_int;
|
||||
u32 d2grph_int;
|
||||
u32 d3grph_int;
|
||||
u32 d4grph_int;
|
||||
u32 d5grph_int;
|
||||
u32 d6grph_int;
|
||||
};
|
||||
|
||||
union radeon_irq_stat_regs {
|
||||
|
|
|
@ -2516,6 +2516,7 @@ int radeon_asic_init(struct radeon_device *rdev)
|
|||
break;
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
rdev->asic = &kv_asic;
|
||||
/* set num crtcs */
|
||||
if (rdev->family == CHIP_KAVERI) {
|
||||
|
|
|
@ -99,6 +99,7 @@ static const char radeon_family_name[][16] = {
|
|||
"KAVERI",
|
||||
"KABINI",
|
||||
"HAWAII",
|
||||
"MULLINS",
|
||||
"LAST",
|
||||
};
|
||||
|
||||
|
|
|
@ -284,6 +284,10 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
|
|||
u32 update_pending;
|
||||
int vpos, hpos;
|
||||
|
||||
/* can happen during initialization */
|
||||
if (radeon_crtc == NULL)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&rdev->ddev->event_lock, flags);
|
||||
work = radeon_crtc->unpin_work;
|
||||
if (work == NULL ||
|
||||
|
@ -826,14 +830,14 @@ static void avivo_reduce_ratio(unsigned *nom, unsigned *den,
|
|||
|
||||
/* make sure nominator is large enough */
|
||||
if (*nom < nom_min) {
|
||||
tmp = (nom_min + *nom - 1) / *nom;
|
||||
tmp = DIV_ROUND_UP(nom_min, *nom);
|
||||
*nom *= tmp;
|
||||
*den *= tmp;
|
||||
}
|
||||
|
||||
/* make sure the denominator is large enough */
|
||||
if (*den < den_min) {
|
||||
tmp = (den_min + *den - 1) / *den;
|
||||
tmp = DIV_ROUND_UP(den_min, *den);
|
||||
*nom *= tmp;
|
||||
*den *= tmp;
|
||||
}
|
||||
|
@ -858,7 +862,7 @@ static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div,
|
|||
unsigned *fb_div, unsigned *ref_div)
|
||||
{
|
||||
/* limit reference * post divider to a maximum */
|
||||
ref_div_max = min(210 / post_div, ref_div_max);
|
||||
ref_div_max = min(128 / post_div, ref_div_max);
|
||||
|
||||
/* get matching reference and feedback divider */
|
||||
*ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
|
||||
|
@ -993,6 +997,16 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
|
|||
/* this also makes sure that the reference divider is large enough */
|
||||
avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min);
|
||||
|
||||
/* avoid high jitter with small fractional dividers */
|
||||
if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
|
||||
fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 60);
|
||||
if (fb_div < fb_div_min) {
|
||||
unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
|
||||
fb_div *= tmp;
|
||||
ref_div *= tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* and finally save the result */
|
||||
if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
|
||||
*fb_div_p = fb_div / 10;
|
||||
|
|
|
@ -97,6 +97,7 @@ enum radeon_family {
|
|||
CHIP_KAVERI,
|
||||
CHIP_KABINI,
|
||||
CHIP_HAWAII,
|
||||
CHIP_MULLINS,
|
||||
CHIP_LAST,
|
||||
};
|
||||
|
||||
|
|
|
@ -1300,6 +1300,7 @@ int radeon_pm_init(struct radeon_device *rdev)
|
|||
case CHIP_KABINI:
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_MULLINS:
|
||||
/* DPM requires the RLC, RV770+ dGPU requires SMC */
|
||||
if (!rdev->rlc_fw)
|
||||
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue