mirror of https://gitee.com/openkylin/linux.git
Merge branch 'origin'
This commit is contained in:
commit
de9ea203d1
|
@ -104,4 +104,9 @@
|
|||
<title>Block IO</title>
|
||||
!Iinclude/trace/events/block.h
|
||||
</chapter>
|
||||
|
||||
<chapter id="workqueue">
|
||||
<title>Workqueue</title>
|
||||
!Iinclude/trace/events/workqueue.h
|
||||
</chapter>
|
||||
</book>
|
||||
|
|
|
@ -1974,15 +1974,18 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
force Enable ASPM even on devices that claim not to support it.
|
||||
WARNING: Forcing ASPM on may cause system lockups.
|
||||
|
||||
pcie_ports= [PCIE] PCIe ports handling:
|
||||
auto Ask the BIOS whether or not to use native PCIe services
|
||||
associated with PCIe ports (PME, hot-plug, AER). Use
|
||||
them only if that is allowed by the BIOS.
|
||||
native Use native PCIe services associated with PCIe ports
|
||||
unconditionally.
|
||||
compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe
|
||||
ports driver.
|
||||
|
||||
pcie_pme= [PCIE,PM] Native PCIe PME signaling options:
|
||||
Format: {auto|force}[,nomsi]
|
||||
auto Use native PCIe PME signaling if the BIOS allows the
|
||||
kernel to control PCIe config registers of root ports.
|
||||
force Use native PCIe PME signaling even if the BIOS refuses
|
||||
to allow the kernel to control the relevant PCIe config
|
||||
registers.
|
||||
nomsi Do not use MSI for native PCIe PME signaling (this makes
|
||||
all PCIe root ports use INTx for everything).
|
||||
all PCIe root ports use INTx for all services).
|
||||
|
||||
pcmv= [HW,PCMCIA] BadgePAD 4
|
||||
|
||||
|
|
11
MAINTAINERS
11
MAINTAINERS
|
@ -2201,6 +2201,12 @@ L: linux-rdma@vger.kernel.org
|
|||
S: Supported
|
||||
F: drivers/infiniband/hw/ehca/
|
||||
|
||||
EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
|
||||
M: Breno Leitao <leitao@linux.vnet.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ehea/
|
||||
|
||||
EMBEDDED LINUX
|
||||
M: Paul Gortmaker <paul.gortmaker@windriver.com>
|
||||
M: Matt Mackall <mpm@selenic.com>
|
||||
|
@ -3923,8 +3929,7 @@ F: Documentation/sound/oss/MultiSound
|
|||
F: sound/oss/msnd*
|
||||
|
||||
MULTITECH MULTIPORT CARD (ISICOM)
|
||||
M: Jiri Slaby <jirislaby@gmail.com>
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/char/isicom.c
|
||||
F: include/linux/isicom.h
|
||||
|
||||
|
@ -4604,7 +4609,7 @@ F: include/linux/preempt.h
|
|||
PRISM54 WIRELESS DRIVER
|
||||
M: "Luis R. Rodriguez" <mcgrof@gmail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://prism54.org
|
||||
W: http://wireless.kernel.org/en/users/Drivers/p54
|
||||
S: Obsolete
|
||||
F: drivers/net/wireless/prism54/
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
# define L1_CACHE_SHIFT 5
|
||||
#endif
|
||||
|
||||
#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
|
||||
#define SMP_CACHE_BYTES L1_CACHE_BYTES
|
||||
|
||||
#endif
|
||||
|
|
|
@ -109,7 +109,7 @@ marvel_print_err_cyc(u64 err_cyc)
|
|||
#define IO7__ERR_CYC__CYCLE__M (0x7)
|
||||
|
||||
printk("%s Packet In Error: %s\n"
|
||||
"%s Error in %s, cycle %ld%s%s\n",
|
||||
"%s Error in %s, cycle %lld%s%s\n",
|
||||
err_print_prefix,
|
||||
packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)],
|
||||
err_print_prefix,
|
||||
|
@ -313,7 +313,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym)
|
|||
}
|
||||
|
||||
printk("%s Up Hose Garbage Symptom:\n"
|
||||
"%s Source Port: %ld - Dest PID: %ld - OpCode: %s\n",
|
||||
"%s Source Port: %lld - Dest PID: %lld - OpCode: %s\n",
|
||||
err_print_prefix,
|
||||
err_print_prefix,
|
||||
EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT),
|
||||
|
@ -552,7 +552,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt)
|
|||
#define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff)
|
||||
|
||||
printk("%s Split Completion Error:\n"
|
||||
"%s Source (Bus:Dev:Func): %ld:%ld:%ld\n",
|
||||
"%s Source (Bus:Dev:Func): %lld:%lld:%lld\n",
|
||||
err_print_prefix,
|
||||
err_print_prefix,
|
||||
EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS),
|
||||
|
|
|
@ -241,20 +241,20 @@ static inline unsigned long alpha_read_pmc(int idx)
|
|||
static int alpha_perf_event_set_period(struct perf_event *event,
|
||||
struct hw_perf_event *hwc, int idx)
|
||||
{
|
||||
long left = atomic64_read(&hwc->period_left);
|
||||
long left = local64_read(&hwc->period_left);
|
||||
long period = hwc->sample_period;
|
||||
int ret = 0;
|
||||
|
||||
if (unlikely(left <= -period)) {
|
||||
left = period;
|
||||
atomic64_set(&hwc->period_left, left);
|
||||
local64_set(&hwc->period_left, left);
|
||||
hwc->last_period = period;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (unlikely(left <= 0)) {
|
||||
left += period;
|
||||
atomic64_set(&hwc->period_left, left);
|
||||
local64_set(&hwc->period_left, left);
|
||||
hwc->last_period = period;
|
||||
ret = 1;
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ static int alpha_perf_event_set_period(struct perf_event *event,
|
|||
if (left > (long)alpha_pmu->pmc_max_period[idx])
|
||||
left = alpha_pmu->pmc_max_period[idx];
|
||||
|
||||
atomic64_set(&hwc->prev_count, (unsigned long)(-left));
|
||||
local64_set(&hwc->prev_count, (unsigned long)(-left));
|
||||
|
||||
alpha_write_pmc(idx, (unsigned long)(-left));
|
||||
|
||||
|
@ -300,10 +300,10 @@ static unsigned long alpha_perf_event_update(struct perf_event *event,
|
|||
long delta;
|
||||
|
||||
again:
|
||||
prev_raw_count = atomic64_read(&hwc->prev_count);
|
||||
prev_raw_count = local64_read(&hwc->prev_count);
|
||||
new_raw_count = alpha_read_pmc(idx);
|
||||
|
||||
if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
|
||||
if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
|
||||
new_raw_count) != prev_raw_count)
|
||||
goto again;
|
||||
|
||||
|
@ -316,8 +316,8 @@ static unsigned long alpha_perf_event_update(struct perf_event *event,
|
|||
delta += alpha_pmu->pmc_max_period[idx] + 1;
|
||||
}
|
||||
|
||||
atomic64_add(delta, &event->count);
|
||||
atomic64_sub(delta, &hwc->period_left);
|
||||
local64_add(delta, &event->count);
|
||||
local64_sub(delta, &hwc->period_left);
|
||||
|
||||
return new_raw_count;
|
||||
}
|
||||
|
@ -636,7 +636,7 @@ static int __hw_perf_event_init(struct perf_event *event)
|
|||
if (!hwc->sample_period) {
|
||||
hwc->sample_period = alpha_pmu->pmc_max_period[0];
|
||||
hwc->last_period = hwc->sample_period;
|
||||
atomic64_set(&hwc->period_left, hwc->sample_period);
|
||||
local64_set(&hwc->period_left, hwc->sample_period);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -156,9 +156,6 @@ extern void SMC669_Init(int);
|
|||
/* es1888.c */
|
||||
extern void es1888_init(void);
|
||||
|
||||
/* ns87312.c */
|
||||
extern void ns87312_enable_ide(long ide_base);
|
||||
|
||||
/* ../lib/fpreg.c */
|
||||
extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
|
||||
extern unsigned long alpha_read_fp_reg (unsigned long reg);
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "irq_impl.h"
|
||||
#include "pci_impl.h"
|
||||
#include "machvec_impl.h"
|
||||
|
||||
#include "pc873xx.h"
|
||||
|
||||
/* Note mask bit is true for DISABLED irqs. */
|
||||
static unsigned long cached_irq_mask = ~0UL;
|
||||
|
@ -235,18 +235,31 @@ cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
|||
return COMMON_TABLE_LOOKUP;
|
||||
}
|
||||
|
||||
static inline void __init
|
||||
cabriolet_enable_ide(void)
|
||||
{
|
||||
if (pc873xx_probe() == -1) {
|
||||
printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n");
|
||||
} else {
|
||||
printk(KERN_INFO "Found %s Super IO chip at 0x%x\n",
|
||||
pc873xx_get_model(), pc873xx_get_base());
|
||||
|
||||
pc873xx_enable_ide();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __init
|
||||
cabriolet_init_pci(void)
|
||||
{
|
||||
common_init_pci();
|
||||
ns87312_enable_ide(0x398);
|
||||
cabriolet_enable_ide();
|
||||
}
|
||||
|
||||
static inline void __init
|
||||
cia_cab_init_pci(void)
|
||||
{
|
||||
cia_init_pci();
|
||||
ns87312_enable_ide(0x398);
|
||||
cabriolet_enable_ide();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "irq_impl.h"
|
||||
#include "pci_impl.h"
|
||||
#include "machvec_impl.h"
|
||||
|
||||
#include "pc873xx.h"
|
||||
|
||||
/* Note mask bit is true for DISABLED irqs. */
|
||||
static unsigned long cached_irq_mask[2] = { -1, -1 };
|
||||
|
@ -264,7 +264,14 @@ takara_init_pci(void)
|
|||
alpha_mv.pci_map_irq = takara_map_irq_srm;
|
||||
|
||||
cia_init_pci();
|
||||
ns87312_enable_ide(0x26e);
|
||||
|
||||
if (pc873xx_probe() == -1) {
|
||||
printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n");
|
||||
} else {
|
||||
printk(KERN_INFO "Found %s Super IO chip at 0x%x\n",
|
||||
pc873xx_get_model(), pc873xx_get_base());
|
||||
pc873xx_enable_ide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1601,6 +1601,7 @@ config ZRELADDR
|
|||
ARCH_ORION5X ||\
|
||||
ARCH_SPEAR3XX ||\
|
||||
ARCH_SPEAR6XX ||\
|
||||
ARCH_TEGRA ||\
|
||||
ARCH_U8500 ||\
|
||||
ARCH_VERSATILE ||\
|
||||
ARCH_W90X900
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
|
||||
static __inline__ int atomic_add_return(int i, atomic_t *v)
|
||||
{
|
||||
int ret,flags;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
local_irq_save(flags);
|
||||
ret = v->counter += i;
|
||||
local_irq_restore(flags);
|
||||
|
@ -30,7 +31,8 @@ static __inline__ int atomic_add_return(int i, atomic_t *v)
|
|||
|
||||
static __inline__ int atomic_sub_return(int i, atomic_t *v)
|
||||
{
|
||||
int ret,flags;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
local_irq_save(flags);
|
||||
ret = v->counter -= i;
|
||||
local_irq_restore(flags);
|
||||
|
@ -42,7 +44,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v)
|
|||
|
||||
static __inline__ int atomic_inc_return(atomic_t *v)
|
||||
{
|
||||
int ret,flags;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
local_irq_save(flags);
|
||||
v->counter++;
|
||||
ret = v->counter;
|
||||
|
@ -64,7 +67,8 @@ static __inline__ int atomic_inc_return(atomic_t *v)
|
|||
|
||||
static __inline__ int atomic_dec_return(atomic_t *v)
|
||||
{
|
||||
int ret,flags;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
local_irq_save(flags);
|
||||
--v->counter;
|
||||
ret = v->counter;
|
||||
|
@ -76,7 +80,8 @@ static __inline__ int atomic_dec_return(atomic_t *v)
|
|||
|
||||
static __inline__ int atomic_dec_and_test(atomic_t *v)
|
||||
{
|
||||
int ret,flags;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
local_irq_save(flags);
|
||||
--v->counter;
|
||||
ret = v->counter;
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
/*
|
||||
* switch_to(n) should switch tasks to task ptr, first checking that
|
||||
* ptr isn't the current task, in which case it does nothing. This
|
||||
|
@ -155,6 +157,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
|
|||
|
||||
#define arch_align_stack(x) (x)
|
||||
|
||||
void die(char *str, struct pt_regs *fp, unsigned long err);
|
||||
extern void die(const char *str, struct pt_regs *fp, unsigned long err);
|
||||
|
||||
#endif /* _H8300_SYSTEM_H */
|
||||
|
|
|
@ -56,8 +56,8 @@ int kernel_execve(const char *filename,
|
|||
const char *const envp[])
|
||||
{
|
||||
register long res __asm__("er0");
|
||||
register char *const *_c __asm__("er3") = envp;
|
||||
register char *const *_b __asm__("er2") = argv;
|
||||
register const char *const *_c __asm__("er3") = envp;
|
||||
register const char *const *_b __asm__("er2") = argv;
|
||||
register const char * _a __asm__("er1") = filename;
|
||||
__asm__ __volatile__ ("mov.l %1,er0\n\t"
|
||||
"trapa #0\n\t"
|
||||
|
|
|
@ -96,7 +96,7 @@ static void dump(struct pt_regs *fp)
|
|||
printk("\n\n");
|
||||
}
|
||||
|
||||
void die(char *str, struct pt_regs *fp, unsigned long err)
|
||||
void die(const char *str, struct pt_regs *fp, unsigned long err)
|
||||
{
|
||||
static int diecount;
|
||||
|
||||
|
|
|
@ -150,6 +150,8 @@ SECTIONS {
|
|||
_sdata = . ;
|
||||
DATA_DATA
|
||||
CACHELINE_ALIGNED_DATA(32)
|
||||
PAGE_ALIGNED_DATA(PAGE_SIZE)
|
||||
*(.data..shared_aligned)
|
||||
INIT_TASK_DATA(THREAD_SIZE)
|
||||
_edata = . ;
|
||||
} > DATA
|
||||
|
|
|
@ -575,13 +575,19 @@ __secondary_start:
|
|||
/* Initialize the kernel stack. Just a repeat for iSeries. */
|
||||
LOAD_REG_ADDR(r3, current_set)
|
||||
sldi r28,r24,3 /* get current_set[cpu#] */
|
||||
ldx r1,r3,r28
|
||||
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
|
||||
std r1,PACAKSAVE(r13)
|
||||
ldx r14,r3,r28
|
||||
addi r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD
|
||||
std r14,PACAKSAVE(r13)
|
||||
|
||||
/* Do early setup for that CPU (stab, slb, hash table pointer) */
|
||||
bl .early_setup_secondary
|
||||
|
||||
/*
|
||||
* setup the new stack pointer, but *don't* use this until
|
||||
* translation is on.
|
||||
*/
|
||||
mr r1, r14
|
||||
|
||||
/* Clear backchain so we get nice backtraces */
|
||||
li r7,0
|
||||
mtlr r7
|
||||
|
|
|
@ -810,6 +810,9 @@ relocate_new_kernel:
|
|||
isync
|
||||
sync
|
||||
|
||||
mfspr r3, SPRN_PIR /* current core we are running on */
|
||||
mr r4, r5 /* load physical address of chunk called */
|
||||
|
||||
/* jump to the entry point, usually the setup routine */
|
||||
mtlr r5
|
||||
blrl
|
||||
|
|
|
@ -577,20 +577,11 @@ void timer_interrupt(struct pt_regs * regs)
|
|||
* some CPUs will continuue to take decrementer exceptions */
|
||||
set_dec(DECREMENTER_MAX);
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
|
||||
if (atomic_read(&ppc_n_lost_interrupts) != 0)
|
||||
do_IRQ(regs);
|
||||
#endif
|
||||
|
||||
now = get_tb_or_rtc();
|
||||
if (now < decrementer->next_tb) {
|
||||
/* not time for this event yet */
|
||||
now = decrementer->next_tb - now;
|
||||
if (now <= DECREMENTER_MAX)
|
||||
set_dec((int)now);
|
||||
trace_timer_interrupt_exit(regs);
|
||||
return;
|
||||
}
|
||||
old_regs = set_irq_regs(regs);
|
||||
irq_enter();
|
||||
|
||||
|
@ -606,8 +597,16 @@ void timer_interrupt(struct pt_regs * regs)
|
|||
get_lppaca()->int_dword.fields.decr_int = 0;
|
||||
#endif
|
||||
|
||||
if (evt->event_handler)
|
||||
evt->event_handler(evt);
|
||||
now = get_tb_or_rtc();
|
||||
if (now >= decrementer->next_tb) {
|
||||
decrementer->next_tb = ~(u64)0;
|
||||
if (evt->event_handler)
|
||||
evt->event_handler(evt);
|
||||
} else {
|
||||
now = decrementer->next_tb - now;
|
||||
if (now <= DECREMENTER_MAX)
|
||||
set_dec((int)now);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
|
||||
|
|
|
@ -48,8 +48,10 @@ static int mpc837xmds_usb_cfg(void)
|
|||
return -1;
|
||||
|
||||
np = of_find_node_by_name(NULL, "usb");
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
if (!np) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
phy_type = of_get_property(np, "phy_type", NULL);
|
||||
if (phy_type && !strcmp(phy_type, "ulpi")) {
|
||||
clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN);
|
||||
|
@ -65,8 +67,9 @@ static int mpc837xmds_usb_cfg(void)
|
|||
}
|
||||
|
||||
of_node_put(np);
|
||||
out:
|
||||
iounmap(bcsr_regs);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ************************************************************************
|
||||
|
|
|
@ -357,6 +357,7 @@ static void __init mpc85xx_mds_setup_arch(void)
|
|||
{
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_controller *hose;
|
||||
struct device_node *np;
|
||||
#endif
|
||||
dma_addr_t max = 0xffffffff;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/lmb.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/swiotlb.h>
|
||||
|
@ -97,7 +97,7 @@ static void __init p1022_ds_setup_arch(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
if (lmb_end_of_DRAM() > max) {
|
||||
if (memblock_end_of_DRAM() > max) {
|
||||
ppc_swiotlb_enable = 1;
|
||||
set_pci_dma_ops(&swiotlb_dma_ops);
|
||||
ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
|
||||
|
|
|
@ -129,20 +129,35 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
|
|||
struct property *property;
|
||||
struct property *last_property = NULL;
|
||||
struct cc_workarea *ccwa;
|
||||
char *data_buf;
|
||||
int cc_token;
|
||||
int rc;
|
||||
int rc = -1;
|
||||
|
||||
cc_token = rtas_token("ibm,configure-connector");
|
||||
if (cc_token == RTAS_UNKNOWN_SERVICE)
|
||||
return NULL;
|
||||
|
||||
spin_lock(&rtas_data_buf_lock);
|
||||
ccwa = (struct cc_workarea *)&rtas_data_buf[0];
|
||||
data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
|
||||
if (!data_buf)
|
||||
return NULL;
|
||||
|
||||
ccwa = (struct cc_workarea *)&data_buf[0];
|
||||
ccwa->drc_index = drc_index;
|
||||
ccwa->zero = 0;
|
||||
|
||||
rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
|
||||
while (rc) {
|
||||
do {
|
||||
/* Since we release the rtas_data_buf lock between configure
|
||||
* connector calls we want to re-populate the rtas_data_buffer
|
||||
* with the contents of the previous call.
|
||||
*/
|
||||
spin_lock(&rtas_data_buf_lock);
|
||||
|
||||
memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE);
|
||||
rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
|
||||
memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
|
||||
|
||||
spin_unlock(&rtas_data_buf_lock);
|
||||
|
||||
switch (rc) {
|
||||
case NEXT_SIBLING:
|
||||
dn = dlpar_parse_cc_node(ccwa);
|
||||
|
@ -197,18 +212,19 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
|
|||
"returned from configure-connector\n", rc);
|
||||
goto cc_error;
|
||||
}
|
||||
|
||||
rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
|
||||
}
|
||||
|
||||
spin_unlock(&rtas_data_buf_lock);
|
||||
return first_dn;
|
||||
} while (rc);
|
||||
|
||||
cc_error:
|
||||
if (first_dn)
|
||||
dlpar_free_cc_nodes(first_dn);
|
||||
spin_unlock(&rtas_data_buf_lock);
|
||||
return NULL;
|
||||
kfree(data_buf);
|
||||
|
||||
if (rc) {
|
||||
if (first_dn)
|
||||
dlpar_free_cc_nodes(first_dn);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return first_dn;
|
||||
}
|
||||
|
||||
static struct device_node *derive_parent(const char *path)
|
||||
|
|
|
@ -399,6 +399,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013E, quirk_fsl_pcie_header);
|
|||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021E, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header);
|
||||
|
|
|
@ -240,12 +240,13 @@ struct rio_priv {
|
|||
|
||||
static void __iomem *rio_regs_win;
|
||||
|
||||
#ifdef CONFIG_E500
|
||||
static int (*saved_mcheck_exception)(struct pt_regs *regs);
|
||||
|
||||
static int fsl_rio_mcheck_exception(struct pt_regs *regs)
|
||||
{
|
||||
const struct exception_table_entry *entry = NULL;
|
||||
unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK);
|
||||
unsigned long reason = mfspr(SPRN_MCSR);
|
||||
|
||||
if (reason & MCSR_BUS_RBERR) {
|
||||
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
|
||||
|
@ -269,6 +270,7 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs)
|
|||
else
|
||||
return cur_cpu_spec->machine_check(regs);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* fsl_rio_doorbell_send - Send a MPC85xx doorbell message
|
||||
|
@ -1517,8 +1519,10 @@ int fsl_rio_setup(struct platform_device *dev)
|
|||
fsl_rio_doorbell_init(port);
|
||||
fsl_rio_port_write_init(port);
|
||||
|
||||
#ifdef CONFIG_E500
|
||||
saved_mcheck_exception = ppc_md.machine_check_exception;
|
||||
ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
|
||||
#endif
|
||||
/* Ensure that RFXE is set */
|
||||
mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
|
||||
|
||||
|
|
|
@ -640,6 +640,7 @@ unsigned int qe_get_num_of_snums(void)
|
|||
if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
|
||||
/* No QE ever has fewer than 28 SNUMs */
|
||||
pr_err("QE: number of snum is invalid\n");
|
||||
of_node_put(qe);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops,
|
|||
int node);
|
||||
extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
#ifdef CONFIG_PCI_DOMAINS
|
||||
static inline int pci_domain_nr(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_sysdata *sd = bus->sysdata;
|
||||
|
@ -37,13 +40,12 @@ static inline int pci_proc_domain(struct pci_bus *bus)
|
|||
{
|
||||
return pci_domain_nr(bus);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Can be used to override the logic in pci_scan_bus for skipping
|
||||
already-configured bus numbers - to be used for buggy BIOSes
|
||||
or architectures with incomplete PCI setup by the loader */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern unsigned int pcibios_assign_all_busses(void);
|
||||
extern int pci_legacy_init(void);
|
||||
# ifdef CONFIG_ACPI
|
||||
|
|
|
@ -101,13 +101,13 @@ config CRYPTO_MANAGER2
|
|||
select CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_PCOMP2
|
||||
|
||||
config CRYPTO_MANAGER_TESTS
|
||||
bool "Run algolithms' self-tests"
|
||||
config CRYPTO_MANAGER_DISABLE_TESTS
|
||||
bool "Disable run-time self tests"
|
||||
default y
|
||||
depends on CRYPTO_MANAGER2
|
||||
help
|
||||
Run cryptomanager's tests for the new crypto algorithms being
|
||||
registered.
|
||||
Disable run-time self tests that normally take place at
|
||||
algorithm registration.
|
||||
|
||||
config CRYPTO_GF128MUL
|
||||
tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
|
||||
|
|
|
@ -47,8 +47,11 @@ static int hash_walk_next(struct crypto_hash_walk *walk)
|
|||
walk->data = crypto_kmap(walk->pg, 0);
|
||||
walk->data += offset;
|
||||
|
||||
if (offset & alignmask)
|
||||
nbytes = alignmask + 1 - (offset & alignmask);
|
||||
if (offset & alignmask) {
|
||||
unsigned int unaligned = alignmask + 1 - (offset & alignmask);
|
||||
if (nbytes > unaligned)
|
||||
nbytes = unaligned;
|
||||
}
|
||||
|
||||
walk->entrylen -= nbytes;
|
||||
return nbytes;
|
||||
|
|
|
@ -206,13 +206,16 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
|
|||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_TESTS
|
||||
static int cryptomgr_test(void *data)
|
||||
{
|
||||
struct crypto_test_param *param = data;
|
||||
u32 type = param->type;
|
||||
int err = 0;
|
||||
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
|
||||
goto skiptest;
|
||||
#endif
|
||||
|
||||
if (type & CRYPTO_ALG_TESTED)
|
||||
goto skiptest;
|
||||
|
||||
|
@ -267,7 +270,6 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg)
|
|||
err:
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
#endif /* CONFIG_CRYPTO_MANAGER_TESTS */
|
||||
|
||||
static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
|
||||
void *data)
|
||||
|
@ -275,10 +277,8 @@ static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
|
|||
switch (msg) {
|
||||
case CRYPTO_MSG_ALG_REQUEST:
|
||||
return cryptomgr_schedule_probe(data);
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_TESTS
|
||||
case CRYPTO_MSG_ALG_REGISTER:
|
||||
return cryptomgr_schedule_test(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef CONFIG_CRYPTO_MANAGER_TESTS
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
|
||||
|
||||
/* a perfect nop */
|
||||
int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
|
||||
|
@ -2542,6 +2542,6 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CRYPTO_MANAGER_TESTS */
|
||||
#endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
|
||||
|
||||
EXPORT_SYMBOL_GPL(alg_test);
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pci-aspm.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
|
@ -226,22 +225,31 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle,
|
|||
return status;
|
||||
}
|
||||
|
||||
static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
|
||||
static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
|
||||
u32 support,
|
||||
u32 *control)
|
||||
{
|
||||
acpi_status status;
|
||||
u32 support_set, result, capbuf[3];
|
||||
u32 result, capbuf[3];
|
||||
|
||||
support &= OSC_PCI_SUPPORT_MASKS;
|
||||
support |= root->osc_support_set;
|
||||
|
||||
/* do _OSC query for all possible controls */
|
||||
support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS);
|
||||
capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
|
||||
capbuf[OSC_SUPPORT_TYPE] = support_set;
|
||||
capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
|
||||
capbuf[OSC_SUPPORT_TYPE] = support;
|
||||
if (control) {
|
||||
*control &= OSC_PCI_CONTROL_MASKS;
|
||||
capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
|
||||
} else {
|
||||
/* Run _OSC query for all possible controls. */
|
||||
capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
|
||||
}
|
||||
|
||||
status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
root->osc_support_set = support_set;
|
||||
root->osc_control_qry = result;
|
||||
root->osc_queried = 1;
|
||||
root->osc_support_set = support;
|
||||
if (control)
|
||||
*control = result;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -255,7 +263,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
|
|||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
mutex_lock(&osc_lock);
|
||||
status = acpi_pci_query_osc(root, flags);
|
||||
status = acpi_pci_query_osc(root, flags, NULL);
|
||||
mutex_unlock(&osc_lock);
|
||||
return status;
|
||||
}
|
||||
|
@ -365,55 +373,70 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
|
|||
EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
|
||||
|
||||
/**
|
||||
* acpi_pci_osc_control_set - commit requested control to Firmware
|
||||
* @handle: acpi_handle for the target ACPI object
|
||||
* @flags: driver's requested control bits
|
||||
* acpi_pci_osc_control_set - Request control of PCI root _OSC features.
|
||||
* @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex).
|
||||
* @mask: Mask of _OSC bits to request control of, place to store control mask.
|
||||
* @req: Mask of _OSC bits the control of is essential to the caller.
|
||||
*
|
||||
* Attempt to take control from Firmware on requested control bits.
|
||||
* Run _OSC query for @mask and if that is successful, compare the returned
|
||||
* mask of control bits with @req. If all of the @req bits are set in the
|
||||
* returned mask, run _OSC request for it.
|
||||
*
|
||||
* The variable at the @mask address may be modified regardless of whether or
|
||||
* not the function returns success. On success it will contain the mask of
|
||||
* _OSC bits the BIOS has granted control of, but its contents are meaningless
|
||||
* on failure.
|
||||
**/
|
||||
acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
|
||||
acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
|
||||
{
|
||||
acpi_status status;
|
||||
u32 control_req, result, capbuf[3];
|
||||
acpi_handle tmp;
|
||||
struct acpi_pci_root *root;
|
||||
acpi_status status;
|
||||
u32 ctrl, capbuf[3];
|
||||
acpi_handle tmp;
|
||||
|
||||
status = acpi_get_handle(handle, "_OSC", &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
if (!mask)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
control_req = (flags & OSC_PCI_CONTROL_MASKS);
|
||||
if (!control_req)
|
||||
ctrl = *mask & OSC_PCI_CONTROL_MASKS;
|
||||
if ((ctrl & req) != req)
|
||||
return AE_TYPE;
|
||||
|
||||
root = acpi_pci_find_root(handle);
|
||||
if (!root)
|
||||
return AE_NOT_EXIST;
|
||||
|
||||
status = acpi_get_handle(handle, "_OSC", &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
mutex_lock(&osc_lock);
|
||||
|
||||
*mask = ctrl | root->osc_control_set;
|
||||
/* No need to evaluate _OSC if the control was already granted. */
|
||||
if ((root->osc_control_set & control_req) == control_req)
|
||||
if ((root->osc_control_set & ctrl) == ctrl)
|
||||
goto out;
|
||||
|
||||
/* Need to query controls first before requesting them */
|
||||
if (!root->osc_queried) {
|
||||
status = acpi_pci_query_osc(root, root->osc_support_set);
|
||||
/* Need to check the available controls bits before requesting them. */
|
||||
while (*mask) {
|
||||
status = acpi_pci_query_osc(root, root->osc_support_set, mask);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto out;
|
||||
if (ctrl == *mask)
|
||||
break;
|
||||
ctrl = *mask;
|
||||
}
|
||||
if ((root->osc_control_qry & control_req) != control_req) {
|
||||
printk(KERN_DEBUG
|
||||
"Firmware did not grant requested _OSC control\n");
|
||||
|
||||
if ((ctrl & req) != req) {
|
||||
status = AE_SUPPORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
capbuf[OSC_QUERY_TYPE] = 0;
|
||||
capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
|
||||
capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req;
|
||||
status = acpi_pci_run_osc(handle, capbuf, &result);
|
||||
capbuf[OSC_CONTROL_TYPE] = ctrl;
|
||||
status = acpi_pci_run_osc(handle, capbuf, mask);
|
||||
if (ACPI_SUCCESS(status))
|
||||
root->osc_control_set = result;
|
||||
root->osc_control_set = *mask;
|
||||
out:
|
||||
mutex_unlock(&osc_lock);
|
||||
return status;
|
||||
|
@ -544,14 +567,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
|||
if (flags != base_flags)
|
||||
acpi_pci_osc_support(root, flags);
|
||||
|
||||
status = acpi_pci_osc_control_set(root->device->handle,
|
||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n");
|
||||
pcie_no_aspm();
|
||||
}
|
||||
|
||||
pci_acpi_add_bus_pm_notifier(device, root->bus);
|
||||
if (device->wakeup.flags.run_wake)
|
||||
device_set_run_wake(root->bus->bridge, true);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <asm/smp.h>
|
||||
#include "agp.h"
|
||||
#include "intel-agp.h"
|
||||
#include <linux/intel-gtt.h>
|
||||
|
||||
#include "intel-gtt.c"
|
||||
|
||||
|
@ -815,11 +816,19 @@ static const struct intel_driver_description {
|
|||
"HD Graphics", NULL, &intel_i965_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG,
|
||||
"HD Graphics", NULL, &intel_i965_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG,
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG,
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG,
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG,
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG,
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG,
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG,
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG,
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG,
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG,
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
@ -1044,6 +1053,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
|
|||
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* Common Intel AGPGART and GTT definitions.
|
||||
*/
|
||||
#ifndef _INTEL_AGP_H
|
||||
#define _INTEL_AGP_H
|
||||
|
||||
/* Intel registers */
|
||||
#define INTEL_APSIZE 0xb4
|
||||
|
@ -200,11 +202,16 @@
|
|||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062
|
||||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a
|
||||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG 0x0126
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 /* Desktop */
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG 0x0102
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG 0x0112
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG 0x0122
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 /* Mobile */
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG 0x0106
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG 0x0116
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG 0x0126
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */
|
||||
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A
|
||||
|
||||
/* cover 915 and 945 variants */
|
||||
#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
|
||||
|
@ -231,7 +238,8 @@
|
|||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
|
||||
|
||||
#define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB)
|
||||
|
||||
#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
|
||||
|
@ -244,3 +252,5 @@
|
|||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \
|
||||
IS_SNB)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,26 @@ static struct gatt_mask intel_i810_masks[] =
|
|||
.type = INTEL_AGP_CACHED_MEMORY}
|
||||
};
|
||||
|
||||
#define INTEL_AGP_UNCACHED_MEMORY 0
|
||||
#define INTEL_AGP_CACHED_MEMORY_LLC 1
|
||||
#define INTEL_AGP_CACHED_MEMORY_LLC_GFDT 2
|
||||
#define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3
|
||||
#define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4
|
||||
|
||||
static struct gatt_mask intel_gen6_masks[] =
|
||||
{
|
||||
{.mask = I810_PTE_VALID | GEN6_PTE_UNCACHED,
|
||||
.type = INTEL_AGP_UNCACHED_MEMORY },
|
||||
{.mask = I810_PTE_VALID | GEN6_PTE_LLC,
|
||||
.type = INTEL_AGP_CACHED_MEMORY_LLC },
|
||||
{.mask = I810_PTE_VALID | GEN6_PTE_LLC | GEN6_PTE_GFDT,
|
||||
.type = INTEL_AGP_CACHED_MEMORY_LLC_GFDT },
|
||||
{.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC,
|
||||
.type = INTEL_AGP_CACHED_MEMORY_LLC_MLC },
|
||||
{.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC | GEN6_PTE_GFDT,
|
||||
.type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT },
|
||||
};
|
||||
|
||||
static struct _intel_private {
|
||||
struct pci_dev *pcidev; /* device one */
|
||||
u8 __iomem *registers;
|
||||
|
@ -178,13 +198,6 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
|
|||
off_t pg_start, int mask_type)
|
||||
{
|
||||
int i, j;
|
||||
u32 cache_bits = 0;
|
||||
|
||||
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
|
||||
{
|
||||
cache_bits = GEN6_PTE_LLC_MLC;
|
||||
}
|
||||
|
||||
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
|
||||
writel(agp_bridge->driver->mask_memory(agp_bridge,
|
||||
|
@ -317,6 +330,23 @@ static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int intel_gen6_type_to_mask_type(struct agp_bridge_data *bridge,
|
||||
int type)
|
||||
{
|
||||
unsigned int type_mask = type & ~AGP_USER_CACHED_MEMORY_GFDT;
|
||||
unsigned int gfdt = type & AGP_USER_CACHED_MEMORY_GFDT;
|
||||
|
||||
if (type_mask == AGP_USER_UNCACHED_MEMORY)
|
||||
return INTEL_AGP_UNCACHED_MEMORY;
|
||||
else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
|
||||
return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT :
|
||||
INTEL_AGP_CACHED_MEMORY_LLC_MLC;
|
||||
else /* set 'normal'/'cached' to LLC by default */
|
||||
return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_GFDT :
|
||||
INTEL_AGP_CACHED_MEMORY_LLC;
|
||||
}
|
||||
|
||||
|
||||
static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
|
||||
int type)
|
||||
{
|
||||
|
@ -588,8 +618,7 @@ static void intel_i830_init_gtt_entries(void)
|
|||
gtt_entries = 0;
|
||||
break;
|
||||
}
|
||||
} else if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) {
|
||||
} else if (IS_SNB) {
|
||||
/*
|
||||
* SandyBridge has new memory control reg at 0x50.w
|
||||
*/
|
||||
|
@ -1068,11 +1097,11 @@ static void intel_i9xx_setup_flush(void)
|
|||
intel_i915_setup_chipset_flush();
|
||||
}
|
||||
|
||||
if (intel_private.ifp_resource.start) {
|
||||
if (intel_private.ifp_resource.start)
|
||||
intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE);
|
||||
if (!intel_private.i9xx_flush_page)
|
||||
dev_info(&intel_private.pcidev->dev, "can't ioremap flush page - no chipset flushing");
|
||||
}
|
||||
if (!intel_private.i9xx_flush_page)
|
||||
dev_err(&intel_private.pcidev->dev,
|
||||
"can't ioremap flush page - no chipset flushing\n");
|
||||
}
|
||||
|
||||
static int intel_i9xx_configure(void)
|
||||
|
@ -1163,7 +1192,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
|
|||
|
||||
mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
|
||||
|
||||
if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
|
||||
if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
|
||||
mask_type != INTEL_AGP_CACHED_MEMORY)
|
||||
goto out_err;
|
||||
|
||||
|
@ -1333,8 +1362,8 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
|
|||
static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge,
|
||||
dma_addr_t addr, int type)
|
||||
{
|
||||
/* Shift high bits down */
|
||||
addr |= (addr >> 28) & 0xff;
|
||||
/* gen6 has bit11-4 for physical addr bit39-32 */
|
||||
addr |= (addr >> 28) & 0xff0;
|
||||
|
||||
/* Type checking must be done elsewhere */
|
||||
return addr | bridge->driver->masks[type].mask;
|
||||
|
@ -1359,6 +1388,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
|
|||
break;
|
||||
case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB:
|
||||
case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB:
|
||||
case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB:
|
||||
*gtt_offset = MB(2);
|
||||
|
||||
pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);
|
||||
|
@ -1563,7 +1593,7 @@ static const struct agp_bridge_driver intel_gen6_driver = {
|
|||
.fetch_size = intel_i9xx_fetch_size,
|
||||
.cleanup = intel_i915_cleanup,
|
||||
.mask_memory = intel_gen6_mask_memory,
|
||||
.masks = intel_i810_masks,
|
||||
.masks = intel_gen6_masks,
|
||||
.agp_enable = intel_i810_agp_enable,
|
||||
.cache_flush = global_cache_flush,
|
||||
.create_gatt_table = intel_i965_create_gatt_table,
|
||||
|
@ -1576,7 +1606,7 @@ static const struct agp_bridge_driver intel_gen6_driver = {
|
|||
.agp_alloc_pages = agp_generic_alloc_pages,
|
||||
.agp_destroy_page = agp_generic_destroy_page,
|
||||
.agp_destroy_pages = agp_generic_destroy_pages,
|
||||
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
|
||||
.agp_type_to_mask_type = intel_gen6_type_to_mask_type,
|
||||
.chipset_flush = intel_i915_chipset_flush,
|
||||
#ifdef USE_PCI_DMA_API
|
||||
.agp_map_page = intel_agp_map_page,
|
||||
|
|
|
@ -387,7 +387,7 @@ static int n2rng_init_control(struct n2rng *np)
|
|||
|
||||
static int n2rng_data_read(struct hwrng *rng, u32 *data)
|
||||
{
|
||||
struct n2rng *np = rng->priv;
|
||||
struct n2rng *np = (struct n2rng *) rng->priv;
|
||||
unsigned long ra = __pa(&np->test_data);
|
||||
int len;
|
||||
|
||||
|
|
|
@ -355,7 +355,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
|||
if (*stp == '\0')
|
||||
stp = NULL;
|
||||
|
||||
if (tty_line >= 0 && tty_line <= p->num && p->ops &&
|
||||
if (tty_line >= 0 && tty_line < p->num && p->ops &&
|
||||
p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
|
||||
res = tty_driver_kref_get(p);
|
||||
*line = tty_line;
|
||||
|
|
|
@ -906,22 +906,16 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
|
|||
* bottom of buffer
|
||||
*/
|
||||
old_origin += (old_rows - new_rows) * old_row_size;
|
||||
end = vc->vc_scr_end;
|
||||
} else {
|
||||
/*
|
||||
* Cursor is in no man's land, copy 1/2 screenful
|
||||
* from the top and bottom of cursor position
|
||||
*/
|
||||
old_origin += (vc->vc_y - new_rows/2) * old_row_size;
|
||||
end = old_origin + (old_row_size * new_rows);
|
||||
}
|
||||
} else
|
||||
/*
|
||||
* Cursor near the top, copy contents from the top of buffer
|
||||
*/
|
||||
end = (old_rows > new_rows) ? old_origin +
|
||||
(old_row_size * new_rows) :
|
||||
vc->vc_scr_end;
|
||||
}
|
||||
|
||||
end = old_origin + old_row_size * min(old_rows, new_rows);
|
||||
|
||||
update_attr(vc);
|
||||
|
||||
|
@ -3075,8 +3069,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
|
|||
|
||||
old_was_color = vc->vc_can_do_color;
|
||||
vc->vc_sw->con_deinit(vc);
|
||||
if (!vc->vc_origin)
|
||||
vc->vc_origin = (unsigned long)vc->vc_screenbuf;
|
||||
vc->vc_origin = (unsigned long)vc->vc_screenbuf;
|
||||
visual_init(vc, i, 0);
|
||||
set_origin(vc);
|
||||
update_attr(vc);
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#include "drm_crtc_helper.h"
|
||||
#include "drm_fb_helper.h"
|
||||
|
||||
static bool drm_kms_helper_poll = true;
|
||||
module_param_named(poll, drm_kms_helper_poll, bool, 0600);
|
||||
|
||||
static void drm_mode_validate_flag(struct drm_connector *connector,
|
||||
int flags)
|
||||
{
|
||||
|
@ -99,8 +102,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|||
connector->status = connector_status_disconnected;
|
||||
if (connector->funcs->force)
|
||||
connector->funcs->force(connector);
|
||||
} else
|
||||
} else {
|
||||
connector->status = connector->funcs->detect(connector);
|
||||
drm_helper_hpd_irq_event(dev);
|
||||
}
|
||||
|
||||
if (connector->status == connector_status_disconnected) {
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
|
||||
|
@ -110,11 +115,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|||
}
|
||||
|
||||
count = (*connector_funcs->get_modes)(connector);
|
||||
if (!count) {
|
||||
if (count == 0 && connector->status == connector_status_connected)
|
||||
count = drm_add_modes_noedid(connector, 1024, 768);
|
||||
if (!count)
|
||||
return 0;
|
||||
}
|
||||
if (count == 0)
|
||||
goto prune;
|
||||
|
||||
drm_mode_connector_list_update(connector);
|
||||
|
||||
|
@ -840,6 +844,9 @@ static void output_poll_execute(struct work_struct *work)
|
|||
enum drm_connector_status old_status, status;
|
||||
bool repoll = false, changed = false;
|
||||
|
||||
if (!drm_kms_helper_poll)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
|
||||
|
@ -890,6 +897,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
|
|||
bool poll = false;
|
||||
struct drm_connector *connector;
|
||||
|
||||
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
|
||||
return;
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->polled)
|
||||
poll = true;
|
||||
|
@ -919,8 +929,10 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
|
|||
{
|
||||
if (!dev->mode_config.poll_enabled)
|
||||
return;
|
||||
|
||||
/* kill timer and schedule immediate execution, this doesn't block */
|
||||
cancel_delayed_work(&dev->mode_config.output_poll_work);
|
||||
queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
|
||||
if (drm_kms_helper_poll)
|
||||
queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "intel_drv.h"
|
||||
#include "i915_drm.h"
|
||||
#include "i915_drv.h"
|
||||
|
||||
|
@ -121,6 +122,54 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int i915_gem_pageflip_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
unsigned long flags;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
|
||||
const char *pipe = crtc->pipe ? "B" : "A";
|
||||
const char *plane = crtc->plane ? "B" : "A";
|
||||
struct intel_unpin_work *work;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
work = crtc->unpin_work;
|
||||
if (work == NULL) {
|
||||
seq_printf(m, "No flip due on pipe %s (plane %s)\n",
|
||||
pipe, plane);
|
||||
} else {
|
||||
if (!work->pending) {
|
||||
seq_printf(m, "Flip queued on pipe %s (plane %s)\n",
|
||||
pipe, plane);
|
||||
} else {
|
||||
seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n",
|
||||
pipe, plane);
|
||||
}
|
||||
if (work->enable_stall_check)
|
||||
seq_printf(m, "Stall check enabled, ");
|
||||
else
|
||||
seq_printf(m, "Stall check waiting for page flip ioctl, ");
|
||||
seq_printf(m, "%d prepares\n", work->pending);
|
||||
|
||||
if (work->old_fb_obj) {
|
||||
struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj);
|
||||
if(obj_priv)
|
||||
seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset );
|
||||
}
|
||||
if (work->pending_flip_obj) {
|
||||
struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj);
|
||||
if(obj_priv)
|
||||
seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset );
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_gem_request_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
|
@ -777,6 +826,7 @@ static struct drm_info_list i915_debugfs_list[] = {
|
|||
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
|
||||
{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
|
||||
{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
|
||||
{"i915_gem_pageflip", i915_gem_pageflip_info, 0},
|
||||
{"i915_gem_request", i915_gem_request_info, 0},
|
||||
{"i915_gem_seqno", i915_gem_seqno_info, 0},
|
||||
{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
|
||||
|
|
|
@ -620,8 +620,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
|
|||
ret = copy_from_user(cliprects, batch->cliprects,
|
||||
batch->num_cliprects *
|
||||
sizeof(struct drm_clip_rect));
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
ret = -EFAULT;
|
||||
goto fail_free;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
@ -662,8 +664,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
|
|||
return -ENOMEM;
|
||||
|
||||
ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz);
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
ret = -EFAULT;
|
||||
goto fail_batch_free;
|
||||
}
|
||||
|
||||
if (cmdbuf->num_cliprects) {
|
||||
cliprects = kcalloc(cmdbuf->num_cliprects,
|
||||
|
@ -676,8 +680,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
|
|||
ret = copy_from_user(cliprects, cmdbuf->cliprects,
|
||||
cmdbuf->num_cliprects *
|
||||
sizeof(struct drm_clip_rect));
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
ret = -EFAULT;
|
||||
goto fail_clip_free;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
@ -885,7 +891,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
|
|||
int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
|
||||
u32 temp_lo, temp_hi = 0;
|
||||
u64 mchbar_addr;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (IS_I965G(dev))
|
||||
pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
|
||||
|
@ -895,22 +901,23 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
|
|||
/* If ACPI doesn't have it, assume we need to allocate it ourselves */
|
||||
#ifdef CONFIG_PNP
|
||||
if (mchbar_addr &&
|
||||
pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* Get some space for it */
|
||||
ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
|
||||
dev_priv->mch_res.name = "i915 MCHBAR";
|
||||
dev_priv->mch_res.flags = IORESOURCE_MEM;
|
||||
ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus,
|
||||
&dev_priv->mch_res,
|
||||
MCHBAR_SIZE, MCHBAR_SIZE,
|
||||
PCIBIOS_MIN_MEM,
|
||||
0, pcibios_align_resource,
|
||||
0, pcibios_align_resource,
|
||||
dev_priv->bridge_dev);
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
|
||||
dev_priv->mch_res.start = 0;
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (IS_I965G(dev))
|
||||
|
@ -919,8 +926,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
|
|||
|
||||
pci_write_config_dword(dev_priv->bridge_dev, reg,
|
||||
lower_32_bits(dev_priv->mch_res.start));
|
||||
out:
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Setup MCHBAR if possible, return true if we should disable it again */
|
||||
|
@ -2082,6 +2088,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
goto free_priv;
|
||||
}
|
||||
|
||||
/* overlay on gen2 is broken and can't address above 1G */
|
||||
if (IS_GEN2(dev))
|
||||
dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
|
||||
|
||||
dev_priv->regs = ioremap(base, size);
|
||||
if (!dev_priv->regs) {
|
||||
DRM_ERROR("failed to map registers\n");
|
||||
|
|
|
@ -61,91 +61,86 @@ extern int intel_agp_enabled;
|
|||
.driver_data = (unsigned long) info }
|
||||
|
||||
static const struct intel_device_info intel_i830_info = {
|
||||
.is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
|
||||
.gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_845g_info = {
|
||||
.is_i8xx = 1,
|
||||
.gen = 2, .is_i8xx = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i85x_info = {
|
||||
.is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
|
||||
.gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
|
||||
.cursor_needs_physical = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i865g_info = {
|
||||
.is_i8xx = 1,
|
||||
.gen = 2, .is_i8xx = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i915g_info = {
|
||||
.is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
|
||||
.gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
|
||||
};
|
||||
static const struct intel_device_info intel_i915gm_info = {
|
||||
.is_i9xx = 1, .is_mobile = 1,
|
||||
.gen = 3, .is_i9xx = 1, .is_mobile = 1,
|
||||
.cursor_needs_physical = 1,
|
||||
};
|
||||
static const struct intel_device_info intel_i945g_info = {
|
||||
.is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
|
||||
.gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
|
||||
};
|
||||
static const struct intel_device_info intel_i945gm_info = {
|
||||
.is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
|
||||
.gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
|
||||
.has_hotplug = 1, .cursor_needs_physical = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i965g_info = {
|
||||
.is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
|
||||
.gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1,
|
||||
.has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i965gm_info = {
|
||||
.is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1,
|
||||
.is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
|
||||
.has_hotplug = 1,
|
||||
.gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1,
|
||||
.is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_g33_info = {
|
||||
.is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1,
|
||||
.has_hotplug = 1,
|
||||
.gen = 3, .is_g33 = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_g45_info = {
|
||||
.is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
|
||||
.has_pipe_cxsr = 1,
|
||||
.has_hotplug = 1,
|
||||
.gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
|
||||
.has_pipe_cxsr = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_gm45_info = {
|
||||
.is_i965g = 1, .is_g4x = 1, .is_i9xx = 1,
|
||||
.gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1,
|
||||
.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
|
||||
.has_pipe_cxsr = 1,
|
||||
.has_hotplug = 1,
|
||||
.has_pipe_cxsr = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_pineview_info = {
|
||||
.is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1,
|
||||
.has_hotplug = 1,
|
||||
.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ironlake_d_info = {
|
||||
.is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
|
||||
.has_pipe_cxsr = 1,
|
||||
.has_hotplug = 1,
|
||||
.gen = 5, .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ironlake_m_info = {
|
||||
.is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
|
||||
.has_hotplug = 1,
|
||||
.gen = 5, .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_sandybridge_d_info = {
|
||||
.is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
|
||||
.has_hotplug = 1, .is_gen6 = 1,
|
||||
.gen = 6, .is_i965g = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_sandybridge_m_info = {
|
||||
.is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
|
||||
.has_hotplug = 1, .is_gen6 = 1,
|
||||
.gen = 6, .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1,
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct pci_device_id pciidlist[] = { /* aka */
|
||||
|
@ -180,8 +175,12 @@ static const struct pci_device_id pciidlist[] = { /* aka */
|
|||
INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
|
||||
INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
|
||||
INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
|
||||
INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info),
|
||||
INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info),
|
||||
INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
|
||||
INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
|
||||
INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
|
||||
INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -191,6 +191,7 @@ struct drm_i915_display_funcs {
|
|||
};
|
||||
|
||||
struct intel_device_info {
|
||||
u8 gen;
|
||||
u8 is_mobile : 1;
|
||||
u8 is_i8xx : 1;
|
||||
u8 is_i85x : 1;
|
||||
|
@ -206,7 +207,6 @@ struct intel_device_info {
|
|||
u8 is_broadwater : 1;
|
||||
u8 is_crestline : 1;
|
||||
u8 is_ironlake : 1;
|
||||
u8 is_gen6 : 1;
|
||||
u8 has_fbc : 1;
|
||||
u8 has_rc6 : 1;
|
||||
u8 has_pipe_cxsr : 1;
|
||||
|
@ -1162,7 +1162,6 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove
|
|||
#define IS_845G(dev) ((dev)->pci_device == 0x2562)
|
||||
#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x)
|
||||
#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
|
||||
#define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx)
|
||||
#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g)
|
||||
#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
|
||||
#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
|
||||
|
@ -1181,27 +1180,13 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove
|
|||
#define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046)
|
||||
#define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake)
|
||||
#define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx)
|
||||
#define IS_GEN6(dev) (INTEL_INFO(dev)->is_gen6)
|
||||
#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile)
|
||||
|
||||
#define IS_GEN3(dev) (IS_I915G(dev) || \
|
||||
IS_I915GM(dev) || \
|
||||
IS_I945G(dev) || \
|
||||
IS_I945GM(dev) || \
|
||||
IS_G33(dev) || \
|
||||
IS_PINEVIEW(dev))
|
||||
#define IS_GEN4(dev) ((dev)->pci_device == 0x2972 || \
|
||||
(dev)->pci_device == 0x2982 || \
|
||||
(dev)->pci_device == 0x2992 || \
|
||||
(dev)->pci_device == 0x29A2 || \
|
||||
(dev)->pci_device == 0x2A02 || \
|
||||
(dev)->pci_device == 0x2A12 || \
|
||||
(dev)->pci_device == 0x2E02 || \
|
||||
(dev)->pci_device == 0x2E12 || \
|
||||
(dev)->pci_device == 0x2E22 || \
|
||||
(dev)->pci_device == 0x2E32 || \
|
||||
(dev)->pci_device == 0x2A42 || \
|
||||
(dev)->pci_device == 0x2E42)
|
||||
#define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2)
|
||||
#define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3)
|
||||
#define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4)
|
||||
#define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5)
|
||||
#define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6)
|
||||
|
||||
#define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev))
|
||||
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/intel-gtt.h>
|
||||
|
||||
static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
|
||||
static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
|
||||
|
@ -135,12 +136,15 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
return -ENOMEM;
|
||||
|
||||
ret = drm_gem_handle_create(file_priv, obj, &handle);
|
||||
drm_gem_object_unreference_unlocked(obj);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
drm_gem_object_unreference_unlocked(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Sink the floating reference from kref_init(handlecount) */
|
||||
drm_gem_object_handle_unreference_unlocked(obj);
|
||||
|
||||
args->handle = handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3585,6 +3589,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
|||
if (ret != 0) {
|
||||
DRM_ERROR("copy %d cliprects failed: %d\n",
|
||||
args->num_cliprects, ret);
|
||||
ret = -EFAULT;
|
||||
goto pre_mutex_err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -887,6 +887,49 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
|
|||
queue_work(dev_priv->wq, &dev_priv->error_work);
|
||||
}
|
||||
|
||||
static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct drm_i915_gem_object *obj_priv;
|
||||
struct intel_unpin_work *work;
|
||||
unsigned long flags;
|
||||
bool stall_detected;
|
||||
|
||||
/* Ignore early vblank irqs */
|
||||
if (intel_crtc == NULL)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
work = intel_crtc->unpin_work;
|
||||
|
||||
if (work == NULL || work->pending || !work->enable_stall_check) {
|
||||
/* Either the pending flip IRQ arrived, or we're too early. Don't check */
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Potential stall - if we see that the flip has happened, assume a missed interrupt */
|
||||
obj_priv = to_intel_bo(work->pending_flip_obj);
|
||||
if(IS_I965G(dev)) {
|
||||
int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF;
|
||||
stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset;
|
||||
} else {
|
||||
int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR;
|
||||
stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset +
|
||||
crtc->y * crtc->fb->pitch +
|
||||
crtc->x * crtc->fb->bits_per_pixel/8);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
||||
if (stall_detected) {
|
||||
DRM_DEBUG_DRIVER("Pageflip stall detected\n");
|
||||
intel_prepare_page_flip(dev, intel_crtc->plane);
|
||||
}
|
||||
}
|
||||
|
||||
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *) arg;
|
||||
|
@ -1004,15 +1047,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
if (pipea_stats & vblank_status) {
|
||||
vblank++;
|
||||
drm_handle_vblank(dev, 0);
|
||||
if (!dev_priv->flip_pending_is_done)
|
||||
if (!dev_priv->flip_pending_is_done) {
|
||||
i915_pageflip_stall_check(dev, 0);
|
||||
intel_finish_page_flip(dev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (pipeb_stats & vblank_status) {
|
||||
vblank++;
|
||||
drm_handle_vblank(dev, 1);
|
||||
if (!dev_priv->flip_pending_is_done)
|
||||
if (!dev_priv->flip_pending_is_done) {
|
||||
i915_pageflip_stall_check(dev, 1);
|
||||
intel_finish_page_flip(dev, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
|
||||
|
|
|
@ -319,6 +319,7 @@
|
|||
|
||||
#define MI_MODE 0x0209c
|
||||
# define VS_TIMER_DISPATCH (1 << 6)
|
||||
# define MI_FLUSH_ENABLE (1 << 11)
|
||||
|
||||
#define SCPD0 0x0209c /* 915+ only */
|
||||
#define IER 0x020a0
|
||||
|
|
|
@ -990,6 +990,22 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
|
||||
|
||||
/* Clear existing vblank status. Note this will clear any other
|
||||
* sticky status fields as well.
|
||||
*
|
||||
* This races with i915_driver_irq_handler() with the result
|
||||
* that either function could miss a vblank event. Here it is not
|
||||
* fatal, as we will either wait upon the next vblank interrupt or
|
||||
* timeout. Generally speaking intel_wait_for_vblank() is only
|
||||
* called during modeset at which time the GPU should be idle and
|
||||
* should *not* be performing page flips and thus not waiting on
|
||||
* vblanks...
|
||||
* Currently, the result of us stealing a vblank from the irq
|
||||
* handler is that a single frame will be skipped during swapbuffers.
|
||||
*/
|
||||
I915_WRITE(pipestat_reg,
|
||||
I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS);
|
||||
|
||||
/* Wait for vblank interrupt bit to set */
|
||||
if (wait_for((I915_READ(pipestat_reg) &
|
||||
PIPE_VBLANK_INTERRUPT_STATUS),
|
||||
|
@ -1486,7 +1502,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|||
dspcntr &= ~DISPPLANE_TILED;
|
||||
}
|
||||
|
||||
if (IS_IRONLAKE(dev))
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
/* must disable */
|
||||
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
|
||||
|
||||
|
@ -1495,20 +1511,19 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|||
Start = obj_priv->gtt_offset;
|
||||
Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
|
||||
|
||||
DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
|
||||
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
|
||||
Start, Offset, x, y, fb->pitch);
|
||||
I915_WRITE(dspstride, fb->pitch);
|
||||
if (IS_I965G(dev)) {
|
||||
I915_WRITE(dspbase, Offset);
|
||||
I915_READ(dspbase);
|
||||
I915_WRITE(dspsurf, Start);
|
||||
I915_READ(dspsurf);
|
||||
I915_WRITE(dsptileoff, (y << 16) | x);
|
||||
I915_WRITE(dspbase, Offset);
|
||||
} else {
|
||||
I915_WRITE(dspbase, Start + Offset);
|
||||
I915_READ(dspbase);
|
||||
}
|
||||
POSTING_READ(dspbase);
|
||||
|
||||
if ((IS_I965G(dev) || plane == 0))
|
||||
if (IS_I965G(dev) || plane == 0)
|
||||
intel_update_fbc(crtc, &crtc->mode);
|
||||
|
||||
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
||||
|
@ -1522,7 +1537,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|||
struct drm_framebuffer *old_fb)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_i915_master_private *master_priv;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_framebuffer *intel_fb;
|
||||
|
@ -1530,13 +1544,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|||
struct drm_gem_object *obj;
|
||||
int pipe = intel_crtc->pipe;
|
||||
int plane = intel_crtc->plane;
|
||||
unsigned long Start, Offset;
|
||||
int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR);
|
||||
int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
|
||||
int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
|
||||
int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
|
||||
int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
|
||||
u32 dspcntr;
|
||||
int ret;
|
||||
|
||||
/* no fb bound */
|
||||
|
@ -1572,71 +1579,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|||
return ret;
|
||||
}
|
||||
|
||||
dspcntr = I915_READ(dspcntr_reg);
|
||||
/* Mask out pixel format bits in case we change it */
|
||||
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
|
||||
switch (crtc->fb->bits_per_pixel) {
|
||||
case 8:
|
||||
dspcntr |= DISPPLANE_8BPP;
|
||||
break;
|
||||
case 16:
|
||||
if (crtc->fb->depth == 15)
|
||||
dspcntr |= DISPPLANE_15_16BPP;
|
||||
else
|
||||
dspcntr |= DISPPLANE_16BPP;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
if (crtc->fb->depth == 30)
|
||||
dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA;
|
||||
else
|
||||
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown color depth\n");
|
||||
ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y);
|
||||
if (ret) {
|
||||
i915_gem_object_unpin(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
if (IS_I965G(dev)) {
|
||||
if (obj_priv->tiling_mode != I915_TILING_NONE)
|
||||
dspcntr |= DISPPLANE_TILED;
|
||||
else
|
||||
dspcntr &= ~DISPPLANE_TILED;
|
||||
}
|
||||
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
/* must disable */
|
||||
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
|
||||
|
||||
I915_WRITE(dspcntr_reg, dspcntr);
|
||||
|
||||
Start = obj_priv->gtt_offset;
|
||||
Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
|
||||
|
||||
DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
|
||||
Start, Offset, x, y, crtc->fb->pitch);
|
||||
I915_WRITE(dspstride, crtc->fb->pitch);
|
||||
if (IS_I965G(dev)) {
|
||||
I915_WRITE(dspsurf, Start);
|
||||
I915_WRITE(dsptileoff, (y << 16) | x);
|
||||
I915_WRITE(dspbase, Offset);
|
||||
} else {
|
||||
I915_WRITE(dspbase, Start + Offset);
|
||||
}
|
||||
POSTING_READ(dspbase);
|
||||
|
||||
if ((IS_I965G(dev) || plane == 0))
|
||||
intel_update_fbc(crtc, &crtc->mode);
|
||||
|
||||
intel_wait_for_vblank(dev, pipe);
|
||||
|
||||
if (old_fb) {
|
||||
intel_fb = to_intel_framebuffer(old_fb);
|
||||
obj_priv = to_intel_bo(intel_fb->obj);
|
||||
i915_gem_object_unpin(intel_fb->obj);
|
||||
}
|
||||
intel_increase_pllclock(crtc, true);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
|
@ -1911,9 +1865,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL;
|
||||
int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL;
|
||||
int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF;
|
||||
int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1;
|
||||
int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ;
|
||||
int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS;
|
||||
int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
|
||||
int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
|
||||
int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
|
||||
|
@ -1982,15 +1933,19 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
}
|
||||
|
||||
/* Enable panel fitting for LVDS */
|
||||
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
|
||||
|| HAS_eDP || intel_pch_has_edp(crtc)) {
|
||||
if (dev_priv->pch_pf_size) {
|
||||
temp = I915_READ(pf_ctl_reg);
|
||||
I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);
|
||||
I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos);
|
||||
I915_WRITE(pf_win_size, dev_priv->pch_pf_size);
|
||||
} else
|
||||
I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
|
||||
if (dev_priv->pch_pf_size &&
|
||||
(intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
|
||||
|| HAS_eDP || intel_pch_has_edp(crtc))) {
|
||||
/* Force use of hard-coded filter coefficients
|
||||
* as some pre-programmed values are broken,
|
||||
* e.g. x201.
|
||||
*/
|
||||
I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1,
|
||||
PF_ENABLE | PF_FILTER_MED_3x3);
|
||||
I915_WRITE(pipe ? PFB_WIN_POS : PFA_WIN_POS,
|
||||
dev_priv->pch_pf_pos);
|
||||
I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ,
|
||||
dev_priv->pch_pf_size);
|
||||
}
|
||||
|
||||
/* Enable CPU pipe */
|
||||
|
@ -2115,7 +2070,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
I915_WRITE(transconf_reg, temp | TRANS_ENABLE);
|
||||
I915_READ(transconf_reg);
|
||||
|
||||
if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 10, 0))
|
||||
if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100, 1))
|
||||
DRM_ERROR("failed to enable transcoder\n");
|
||||
}
|
||||
|
||||
|
@ -2155,14 +2110,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
udelay(100);
|
||||
|
||||
/* Disable PF */
|
||||
temp = I915_READ(pf_ctl_reg);
|
||||
if ((temp & PF_ENABLE) != 0) {
|
||||
I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
|
||||
I915_READ(pf_ctl_reg);
|
||||
}
|
||||
I915_WRITE(pf_win_size, 0);
|
||||
POSTING_READ(pf_win_size);
|
||||
|
||||
I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0);
|
||||
I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, 0);
|
||||
|
||||
/* disable CPU FDI tx and PCH FDI rx */
|
||||
temp = I915_READ(fdi_tx_reg);
|
||||
|
@ -2421,6 +2370,9 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
int pipe = intel_crtc->pipe;
|
||||
bool enabled;
|
||||
|
||||
if (intel_crtc->dpms_mode == mode)
|
||||
return;
|
||||
|
||||
intel_crtc->dpms_mode = mode;
|
||||
intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON;
|
||||
|
||||
|
@ -3554,10 +3506,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
|
||||
bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
|
||||
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
|
||||
bool is_edp = false;
|
||||
struct intel_encoder *has_edp_encoder = NULL;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct drm_encoder *encoder;
|
||||
struct intel_encoder *intel_encoder = NULL;
|
||||
const intel_limit_t *limit;
|
||||
int ret;
|
||||
struct fdi_m_n m_n = {0};
|
||||
|
@ -3578,12 +3529,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
drm_vblank_pre_modeset(dev, pipe);
|
||||
|
||||
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
|
||||
struct intel_encoder *intel_encoder;
|
||||
|
||||
if (!encoder || encoder->crtc != crtc)
|
||||
if (encoder->crtc != crtc)
|
||||
continue;
|
||||
|
||||
intel_encoder = enc_to_intel_encoder(encoder);
|
||||
|
||||
switch (intel_encoder->type) {
|
||||
case INTEL_OUTPUT_LVDS:
|
||||
is_lvds = true;
|
||||
|
@ -3607,7 +3558,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
is_dp = true;
|
||||
break;
|
||||
case INTEL_OUTPUT_EDP:
|
||||
is_edp = true;
|
||||
has_edp_encoder = intel_encoder;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3685,10 +3636,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
int lane = 0, link_bw, bpp;
|
||||
/* eDP doesn't require FDI link, so just set DP M/N
|
||||
according to current link config */
|
||||
if (is_edp) {
|
||||
if (has_edp_encoder) {
|
||||
target_clock = mode->clock;
|
||||
intel_edp_link_config(intel_encoder,
|
||||
&lane, &link_bw);
|
||||
intel_edp_link_config(has_edp_encoder,
|
||||
&lane, &link_bw);
|
||||
} else {
|
||||
/* DP over FDI requires target mode clock
|
||||
instead of link clock */
|
||||
|
@ -3709,7 +3660,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
temp |= PIPE_8BPC;
|
||||
else
|
||||
temp |= PIPE_6BPC;
|
||||
} else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) {
|
||||
} else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) {
|
||||
switch (dev_priv->edp_bpp/3) {
|
||||
case 8:
|
||||
temp |= PIPE_8BPC;
|
||||
|
@ -3782,7 +3733,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
|
||||
udelay(200);
|
||||
|
||||
if (is_edp) {
|
||||
if (has_edp_encoder) {
|
||||
if (dev_priv->lvds_use_ssc) {
|
||||
temp |= DREF_SSC1_ENABLE;
|
||||
I915_WRITE(PCH_DREF_CONTROL, temp);
|
||||
|
@ -3931,7 +3882,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
dpll_reg = pch_dpll_reg;
|
||||
}
|
||||
|
||||
if (!is_edp) {
|
||||
if (!has_edp_encoder) {
|
||||
I915_WRITE(fp_reg, fp);
|
||||
I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
|
||||
I915_READ(dpll_reg);
|
||||
|
@ -4026,7 +3977,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
}
|
||||
}
|
||||
|
||||
if (!is_edp) {
|
||||
if (!has_edp_encoder) {
|
||||
I915_WRITE(fp_reg, fp);
|
||||
I915_WRITE(dpll_reg, dpll);
|
||||
I915_READ(dpll_reg);
|
||||
|
@ -4105,7 +4056,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
I915_WRITE(link_m1_reg, m_n.link_m);
|
||||
I915_WRITE(link_n1_reg, m_n.link_n);
|
||||
|
||||
if (is_edp) {
|
||||
if (has_edp_encoder) {
|
||||
ironlake_set_pll_edp(crtc, adjusted_mode->clock);
|
||||
} else {
|
||||
/* enable FDI RX PLL too */
|
||||
|
@ -4911,15 +4862,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
|
|||
kfree(intel_crtc);
|
||||
}
|
||||
|
||||
struct intel_unpin_work {
|
||||
struct work_struct work;
|
||||
struct drm_device *dev;
|
||||
struct drm_gem_object *old_fb_obj;
|
||||
struct drm_gem_object *pending_flip_obj;
|
||||
struct drm_pending_vblank_event *event;
|
||||
int pending;
|
||||
};
|
||||
|
||||
static void intel_unpin_work_fn(struct work_struct *__work)
|
||||
{
|
||||
struct intel_unpin_work *work =
|
||||
|
@ -5007,7 +4949,8 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
|
|||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
if (intel_crtc->unpin_work) {
|
||||
intel_crtc->unpin_work->pending = 1;
|
||||
if ((++intel_crtc->unpin_work->pending) > 1)
|
||||
DRM_ERROR("Prepared flip multiple times\n");
|
||||
} else {
|
||||
DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
|
||||
}
|
||||
|
@ -5026,9 +4969,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_unpin_work *work;
|
||||
unsigned long flags, offset;
|
||||
int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
|
||||
int ret, pipesrc;
|
||||
u32 flip_mask;
|
||||
int pipe = intel_crtc->pipe;
|
||||
u32 pf, pipesrc;
|
||||
int ret;
|
||||
|
||||
work = kzalloc(sizeof *work, GFP_KERNEL);
|
||||
if (work == NULL)
|
||||
|
@ -5077,42 +5020,73 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|||
atomic_inc(&obj_priv->pending_flip);
|
||||
work->pending_flip_obj = obj;
|
||||
|
||||
if (intel_crtc->plane)
|
||||
flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
|
||||
else
|
||||
flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
|
||||
|
||||
if (IS_GEN3(dev) || IS_GEN2(dev)) {
|
||||
u32 flip_mask;
|
||||
|
||||
if (intel_crtc->plane)
|
||||
flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
|
||||
else
|
||||
flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
|
||||
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
|
||||
OUT_RING(0);
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
work->enable_stall_check = true;
|
||||
|
||||
/* Offset into the new buffer for cases of shared fbs between CRTCs */
|
||||
offset = obj_priv->gtt_offset;
|
||||
offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8);
|
||||
offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
|
||||
|
||||
BEGIN_LP_RING(4);
|
||||
if (IS_I965G(dev)) {
|
||||
switch(INTEL_INFO(dev)->gen) {
|
||||
case 2:
|
||||
OUT_RING(MI_DISPLAY_FLIP |
|
||||
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
||||
OUT_RING(fb->pitch);
|
||||
OUT_RING(offset | obj_priv->tiling_mode);
|
||||
pipesrc = I915_READ(pipesrc_reg);
|
||||
OUT_RING(pipesrc & 0x0fff0fff);
|
||||
} else if (IS_GEN3(dev)) {
|
||||
OUT_RING(obj_priv->gtt_offset + offset);
|
||||
OUT_RING(MI_NOOP);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
OUT_RING(MI_DISPLAY_FLIP_I915 |
|
||||
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
||||
OUT_RING(fb->pitch);
|
||||
OUT_RING(offset);
|
||||
OUT_RING(obj_priv->gtt_offset + offset);
|
||||
OUT_RING(MI_NOOP);
|
||||
} else {
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
/* i965+ uses the linear or tiled offsets from the
|
||||
* Display Registers (which do not change across a page-flip)
|
||||
* so we need only reprogram the base address.
|
||||
*/
|
||||
OUT_RING(MI_DISPLAY_FLIP |
|
||||
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
||||
OUT_RING(fb->pitch);
|
||||
OUT_RING(offset);
|
||||
OUT_RING(MI_NOOP);
|
||||
OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
|
||||
|
||||
/* XXX Enabling the panel-fitter across page-flip is so far
|
||||
* untested on non-native modes, so ignore it for now.
|
||||
* pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
|
||||
*/
|
||||
pf = 0;
|
||||
pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff;
|
||||
OUT_RING(pf | pipesrc);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
OUT_RING(MI_DISPLAY_FLIP |
|
||||
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
||||
OUT_RING(fb->pitch | obj_priv->tiling_mode);
|
||||
OUT_RING(obj_priv->gtt_offset);
|
||||
|
||||
pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
|
||||
pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff;
|
||||
OUT_RING(pf | pipesrc);
|
||||
break;
|
||||
}
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
|
@ -5193,7 +5167,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
|
|||
dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
|
||||
|
||||
intel_crtc->cursor_addr = 0;
|
||||
intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
|
||||
intel_crtc->dpms_mode = -1;
|
||||
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
|
||||
|
||||
intel_crtc->busy = false;
|
||||
|
|
|
@ -239,7 +239,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
|
|||
uint32_t ch_data = ch_ctl + 4;
|
||||
int i;
|
||||
int recv_bytes;
|
||||
uint32_t ctl;
|
||||
uint32_t status;
|
||||
uint32_t aux_clock_divider;
|
||||
int try, precharge;
|
||||
|
@ -263,41 +262,43 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
|
|||
else
|
||||
precharge = 5;
|
||||
|
||||
if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) {
|
||||
DRM_ERROR("dp_aux_ch not started status 0x%08x\n",
|
||||
I915_READ(ch_ctl));
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Must try at least 3 times according to DP spec */
|
||||
for (try = 0; try < 5; try++) {
|
||||
/* Load the send data into the aux channel data registers */
|
||||
for (i = 0; i < send_bytes; i += 4) {
|
||||
uint32_t d = pack_aux(send + i, send_bytes - i);
|
||||
|
||||
I915_WRITE(ch_data + i, d);
|
||||
}
|
||||
|
||||
ctl = (DP_AUX_CH_CTL_SEND_BUSY |
|
||||
DP_AUX_CH_CTL_TIME_OUT_400us |
|
||||
(send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
|
||||
(precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
|
||||
(aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
|
||||
DP_AUX_CH_CTL_DONE |
|
||||
DP_AUX_CH_CTL_TIME_OUT_ERROR |
|
||||
DP_AUX_CH_CTL_RECEIVE_ERROR);
|
||||
for (i = 0; i < send_bytes; i += 4)
|
||||
I915_WRITE(ch_data + i,
|
||||
pack_aux(send + i, send_bytes - i));
|
||||
|
||||
/* Send the command and wait for it to complete */
|
||||
I915_WRITE(ch_ctl, ctl);
|
||||
(void) I915_READ(ch_ctl);
|
||||
I915_WRITE(ch_ctl,
|
||||
DP_AUX_CH_CTL_SEND_BUSY |
|
||||
DP_AUX_CH_CTL_TIME_OUT_400us |
|
||||
(send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
|
||||
(precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
|
||||
(aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
|
||||
DP_AUX_CH_CTL_DONE |
|
||||
DP_AUX_CH_CTL_TIME_OUT_ERROR |
|
||||
DP_AUX_CH_CTL_RECEIVE_ERROR);
|
||||
for (;;) {
|
||||
udelay(100);
|
||||
status = I915_READ(ch_ctl);
|
||||
if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
|
||||
break;
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
/* Clear done status and any errors */
|
||||
I915_WRITE(ch_ctl, (status |
|
||||
DP_AUX_CH_CTL_DONE |
|
||||
DP_AUX_CH_CTL_TIME_OUT_ERROR |
|
||||
DP_AUX_CH_CTL_RECEIVE_ERROR));
|
||||
(void) I915_READ(ch_ctl);
|
||||
if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0)
|
||||
I915_WRITE(ch_ctl,
|
||||
status |
|
||||
DP_AUX_CH_CTL_DONE |
|
||||
DP_AUX_CH_CTL_TIME_OUT_ERROR |
|
||||
DP_AUX_CH_CTL_RECEIVE_ERROR);
|
||||
if (status & DP_AUX_CH_CTL_DONE)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -324,15 +325,12 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
|
|||
/* Unload any bytes sent back from the other side */
|
||||
recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
|
||||
DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
|
||||
|
||||
if (recv_bytes > recv_size)
|
||||
recv_bytes = recv_size;
|
||||
|
||||
for (i = 0; i < recv_bytes; i += 4) {
|
||||
uint32_t d = I915_READ(ch_data + i);
|
||||
|
||||
unpack_aux(d, recv + i, recv_bytes - i);
|
||||
}
|
||||
for (i = 0; i < recv_bytes; i += 4)
|
||||
unpack_aux(I915_READ(ch_data + i),
|
||||
recv + i, recv_bytes - i);
|
||||
|
||||
return recv_bytes;
|
||||
}
|
||||
|
|
|
@ -176,6 +176,16 @@ struct intel_crtc {
|
|||
#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
|
||||
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
|
||||
|
||||
struct intel_unpin_work {
|
||||
struct work_struct work;
|
||||
struct drm_device *dev;
|
||||
struct drm_gem_object *old_fb_obj;
|
||||
struct drm_gem_object *pending_flip_obj;
|
||||
struct drm_pending_vblank_event *event;
|
||||
int pending;
|
||||
bool enable_stall_check;
|
||||
};
|
||||
|
||||
struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||
const char *name);
|
||||
void intel_i2c_destroy(struct i2c_adapter *adapter);
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
*
|
||||
* Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
|
||||
*/
|
||||
|
||||
#include <linux/seq_file.h>
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "i915_drm.h"
|
||||
|
|
|
@ -220,9 +220,13 @@ static int init_render_ring(struct drm_device *dev,
|
|||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
int ret = init_ring_common(dev, ring);
|
||||
int mode;
|
||||
|
||||
if (IS_I9XX(dev) && !IS_GEN3(dev)) {
|
||||
I915_WRITE(MI_MODE,
|
||||
(VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
|
||||
mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
|
||||
if (IS_GEN6(dev))
|
||||
mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
|
||||
I915_WRITE(MI_MODE, mode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1061,8 +1061,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
|
|||
if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
|
||||
return false;
|
||||
|
||||
if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode))
|
||||
return false;
|
||||
(void) intel_sdvo_set_input_timings_for_mode(intel_sdvo,
|
||||
mode,
|
||||
adjusted_mode);
|
||||
} else if (intel_sdvo->is_lvds) {
|
||||
drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0);
|
||||
|
||||
|
@ -1070,8 +1071,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
|
|||
intel_sdvo->sdvo_lvds_fixed_mode))
|
||||
return false;
|
||||
|
||||
if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode))
|
||||
return false;
|
||||
(void) intel_sdvo_set_input_timings_for_mode(intel_sdvo,
|
||||
mode,
|
||||
adjusted_mode);
|
||||
}
|
||||
|
||||
/* Make the CRTC code factor in the SDVO pixel multiplier. The
|
||||
|
@ -1108,10 +1110,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
|
|||
in_out.in0 = intel_sdvo->attached_output;
|
||||
in_out.in1 = 0;
|
||||
|
||||
if (!intel_sdvo_set_value(intel_sdvo,
|
||||
SDVO_CMD_SET_IN_OUT_MAP,
|
||||
&in_out, sizeof(in_out)))
|
||||
return;
|
||||
intel_sdvo_set_value(intel_sdvo,
|
||||
SDVO_CMD_SET_IN_OUT_MAP,
|
||||
&in_out, sizeof(in_out));
|
||||
|
||||
if (intel_sdvo->is_hdmi) {
|
||||
if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode))
|
||||
|
@ -1122,11 +1123,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
|
|||
|
||||
/* We have tried to get input timing in mode_fixup, and filled into
|
||||
adjusted_mode */
|
||||
if (intel_sdvo->is_tv || intel_sdvo->is_lvds) {
|
||||
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
|
||||
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
|
||||
if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
|
||||
input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags;
|
||||
} else
|
||||
intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
|
||||
|
||||
/* If it's a TV, we already set the output timing in mode_fixup.
|
||||
* Otherwise, the output timing is equal to the input timing.
|
||||
|
@ -1137,8 +1136,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
|
|||
intel_sdvo->attached_output))
|
||||
return;
|
||||
|
||||
if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd))
|
||||
return;
|
||||
(void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd);
|
||||
}
|
||||
|
||||
/* Set the input timing to the screen. Assume always input 0. */
|
||||
|
@ -1165,8 +1163,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
|
|||
intel_sdvo_set_input_timing(encoder, &input_dtd);
|
||||
}
|
||||
#else
|
||||
if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
|
||||
return;
|
||||
(void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd);
|
||||
#endif
|
||||
|
||||
sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
|
||||
|
@ -1932,6 +1929,41 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
|
|||
.destroy = intel_sdvo_enc_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)
|
||||
{
|
||||
uint16_t mask = 0;
|
||||
unsigned int num_bits;
|
||||
|
||||
/* Make a mask of outputs less than or equal to our own priority in the
|
||||
* list.
|
||||
*/
|
||||
switch (sdvo->controlled_output) {
|
||||
case SDVO_OUTPUT_LVDS1:
|
||||
mask |= SDVO_OUTPUT_LVDS1;
|
||||
case SDVO_OUTPUT_LVDS0:
|
||||
mask |= SDVO_OUTPUT_LVDS0;
|
||||
case SDVO_OUTPUT_TMDS1:
|
||||
mask |= SDVO_OUTPUT_TMDS1;
|
||||
case SDVO_OUTPUT_TMDS0:
|
||||
mask |= SDVO_OUTPUT_TMDS0;
|
||||
case SDVO_OUTPUT_RGB1:
|
||||
mask |= SDVO_OUTPUT_RGB1;
|
||||
case SDVO_OUTPUT_RGB0:
|
||||
mask |= SDVO_OUTPUT_RGB0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Count bits to find what number we are in the priority list. */
|
||||
mask &= sdvo->caps.output_flags;
|
||||
num_bits = hweight16(mask);
|
||||
/* If more than 3 outputs, default to DDC bus 3 for now. */
|
||||
if (num_bits > 3)
|
||||
num_bits = 3;
|
||||
|
||||
/* Corresponds to SDVO_CONTROL_BUS_DDCx */
|
||||
sdvo->ddc_bus = 1 << num_bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the appropriate DDC bus for control bus switch command for this
|
||||
|
@ -1951,7 +1983,10 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
|
|||
else
|
||||
mapping = &(dev_priv->sdvo_mappings[1]);
|
||||
|
||||
sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
|
||||
if (mapping->initialized)
|
||||
sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
|
||||
else
|
||||
intel_sdvo_guess_ddc_bus(sdvo);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1231,7 +1231,6 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
|
|||
struct drm_encoder *encoder = &intel_tv->base.enc;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
|
||||
unsigned long irqflags;
|
||||
u32 tv_ctl, save_tv_ctl;
|
||||
u32 tv_dac, save_tv_dac;
|
||||
|
@ -1268,11 +1267,15 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
|
|||
DAC_C_0_7_V);
|
||||
I915_WRITE(TV_CTL, tv_ctl);
|
||||
I915_WRITE(TV_DAC, tv_dac);
|
||||
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
||||
POSTING_READ(TV_DAC);
|
||||
msleep(20);
|
||||
|
||||
tv_dac = I915_READ(TV_DAC);
|
||||
I915_WRITE(TV_DAC, save_tv_dac);
|
||||
I915_WRITE(TV_CTL, save_tv_ctl);
|
||||
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
||||
POSTING_READ(TV_CTL);
|
||||
msleep(20);
|
||||
|
||||
/*
|
||||
* A B C
|
||||
* 0 1 1 Composite
|
||||
|
|
|
@ -64,16 +64,17 @@ nouveau_fence_update(struct nouveau_channel *chan)
|
|||
struct nouveau_fence *fence;
|
||||
uint32_t sequence;
|
||||
|
||||
spin_lock(&chan->fence.lock);
|
||||
|
||||
if (USE_REFCNT)
|
||||
sequence = nvchan_rd32(chan, 0x48);
|
||||
else
|
||||
sequence = atomic_read(&chan->fence.last_sequence_irq);
|
||||
|
||||
if (chan->fence.sequence_ack == sequence)
|
||||
return;
|
||||
goto out;
|
||||
chan->fence.sequence_ack = sequence;
|
||||
|
||||
spin_lock(&chan->fence.lock);
|
||||
list_for_each_safe(entry, tmp, &chan->fence.pending) {
|
||||
fence = list_entry(entry, struct nouveau_fence, entry);
|
||||
|
||||
|
@ -85,6 +86,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
|
|||
if (sequence == chan->fence.sequence_ack)
|
||||
break;
|
||||
}
|
||||
out:
|
||||
spin_unlock(&chan->fence.lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence)
|
|||
list_del(&nvbo->entry);
|
||||
nvbo->reserved_by = NULL;
|
||||
ttm_bo_unreserve(&nvbo->bo);
|
||||
drm_gem_object_unreference(nvbo->gem);
|
||||
drm_gem_object_unreference_unlocked(nvbo->gem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,7 +300,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
|
|||
validate_fini(op, NULL);
|
||||
if (ret == -EAGAIN)
|
||||
ret = ttm_bo_wait_unreserved(&nvbo->bo, false);
|
||||
drm_gem_object_unreference(gem);
|
||||
drm_gem_object_unreference_unlocked(gem);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "fail reserve\n");
|
||||
return ret;
|
||||
|
@ -616,8 +616,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
|
|||
return PTR_ERR(bo);
|
||||
}
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
/* Mark push buffers as being used on PFIFO, the validation code
|
||||
* will then make sure that if the pushbuf bo moves, that they
|
||||
* happen on the kernel channel, which will in turn cause a sync
|
||||
|
@ -731,7 +729,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
|
|||
out:
|
||||
validate_fini(&op, fence);
|
||||
nouveau_fence_unref((void**)&fence);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
kfree(bo);
|
||||
kfree(push);
|
||||
|
||||
|
|
|
@ -139,6 +139,8 @@ nv50_instmem_init(struct drm_device *dev)
|
|||
chan->file_priv = (struct drm_file *)-2;
|
||||
dev_priv->fifos[0] = dev_priv->fifos[127] = chan;
|
||||
|
||||
INIT_LIST_HEAD(&chan->ramht_refs);
|
||||
|
||||
/* Channel's PRAMIN object + heap */
|
||||
ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0,
|
||||
NULL, &chan->ramin);
|
||||
|
|
|
@ -332,6 +332,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
|
|||
args.usV_SyncWidth =
|
||||
cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
|
||||
|
||||
args.ucOverscanRight = radeon_crtc->h_border;
|
||||
args.ucOverscanLeft = radeon_crtc->h_border;
|
||||
args.ucOverscanBottom = radeon_crtc->v_border;
|
||||
args.ucOverscanTop = radeon_crtc->v_border;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
|
||||
misc |= ATOM_VSYNC_POLARITY;
|
||||
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
|
@ -534,6 +539,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
|||
pll->algo = PLL_ALGO_LEGACY;
|
||||
pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
|
||||
}
|
||||
/* There is some evidence (often anecdotal) that RV515 LVDS
|
||||
* (on some boards at least) prefers the legacy algo. I'm not
|
||||
* sure whether this should handled generically or on a
|
||||
* case-by-case quirk basis. Both algos should work fine in the
|
||||
* majority of cases.
|
||||
*/
|
||||
if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) &&
|
||||
(rdev->family == CHIP_RV515)) {
|
||||
/* allow the user to overrride just in case */
|
||||
if (radeon_new_pll == 1)
|
||||
pll->algo = PLL_ALGO_NEW;
|
||||
else
|
||||
pll->algo = PLL_ALGO_LEGACY;
|
||||
}
|
||||
} else {
|
||||
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
|
||||
pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||
|
@ -1056,11 +1075,11 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
|||
|
||||
if (rdev->family >= CHIP_RV770) {
|
||||
if (radeon_crtc->crtc_id) {
|
||||
WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
|
||||
WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
|
||||
WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
|
||||
WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
|
||||
} else {
|
||||
WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
|
||||
WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
|
||||
WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
|
||||
WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
|
||||
}
|
||||
}
|
||||
WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
|
||||
|
@ -1197,8 +1216,18 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
|
|||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_encoder *encoder;
|
||||
bool is_tvcv = false;
|
||||
|
||||
/* TODO color tiling */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
/* find tv std */
|
||||
if (encoder->crtc == crtc) {
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
if (radeon_encoder->active_device &
|
||||
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
|
||||
is_tvcv = true;
|
||||
}
|
||||
}
|
||||
|
||||
atombios_disable_ss(crtc);
|
||||
/* always set DCPLL */
|
||||
|
@ -1207,9 +1236,14 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
|
|||
atombios_crtc_set_pll(crtc, adjusted_mode);
|
||||
atombios_enable_ss(crtc);
|
||||
|
||||
if (ASIC_IS_AVIVO(rdev))
|
||||
if (ASIC_IS_DCE4(rdev))
|
||||
atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
|
||||
else {
|
||||
else if (ASIC_IS_AVIVO(rdev)) {
|
||||
if (is_tvcv)
|
||||
atombios_crtc_set_timing(crtc, adjusted_mode);
|
||||
else
|
||||
atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
|
||||
} else {
|
||||
atombios_crtc_set_timing(crtc, adjusted_mode);
|
||||
if (radeon_crtc->crtc_id == 0)
|
||||
atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
|
||||
|
|
|
@ -675,6 +675,43 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int evergreen_cp_start(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
uint32_t cp_me;
|
||||
|
||||
r = radeon_ring_lock(rdev, 7);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
|
||||
radeon_ring_write(rdev, 0x1);
|
||||
radeon_ring_write(rdev, 0x0);
|
||||
radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1);
|
||||
radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
|
||||
radeon_ring_write(rdev, 0);
|
||||
radeon_ring_write(rdev, 0);
|
||||
radeon_ring_unlock_commit(rdev);
|
||||
|
||||
cp_me = 0xff;
|
||||
WREG32(CP_ME_CNTL, cp_me);
|
||||
|
||||
r = radeon_ring_lock(rdev, 4);
|
||||
if (r) {
|
||||
DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
/* init some VGT regs */
|
||||
radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
|
||||
radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2);
|
||||
radeon_ring_write(rdev, 0xe);
|
||||
radeon_ring_write(rdev, 0x10);
|
||||
radeon_ring_unlock_commit(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int evergreen_cp_resume(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
@ -719,7 +756,7 @@ int evergreen_cp_resume(struct radeon_device *rdev)
|
|||
rdev->cp.rptr = RREG32(CP_RB_RPTR);
|
||||
rdev->cp.wptr = RREG32(CP_RB_WPTR);
|
||||
|
||||
r600_cp_start(rdev);
|
||||
evergreen_cp_start(rdev);
|
||||
rdev->cp.ready = true;
|
||||
r = radeon_ring_test(rdev);
|
||||
if (r) {
|
||||
|
@ -2054,11 +2091,6 @@ int evergreen_resume(struct radeon_device *rdev)
|
|||
*/
|
||||
/* post card */
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
/* Initialize clocks */
|
||||
r = radeon_clocks_init(rdev);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = evergreen_startup(rdev);
|
||||
if (r) {
|
||||
|
@ -2164,9 +2196,6 @@ int evergreen_init(struct radeon_device *rdev)
|
|||
radeon_surface_init(rdev);
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
r = radeon_clocks_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* Fence driver */
|
||||
r = radeon_fence_driver_init(rdev);
|
||||
if (r)
|
||||
|
@ -2236,7 +2265,6 @@ void evergreen_fini(struct radeon_device *rdev)
|
|||
evergreen_pcie_gart_fini(rdev);
|
||||
radeon_gem_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_clocks_fini(rdev);
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
|
|
|
@ -2119,10 +2119,7 @@ int r600_cp_start(struct radeon_device *rdev)
|
|||
}
|
||||
radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
|
||||
radeon_ring_write(rdev, 0x1);
|
||||
if (rdev->family >= CHIP_CEDAR) {
|
||||
radeon_ring_write(rdev, 0x0);
|
||||
radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1);
|
||||
} else if (rdev->family >= CHIP_RV770) {
|
||||
if (rdev->family >= CHIP_RV770) {
|
||||
radeon_ring_write(rdev, 0x0);
|
||||
radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1);
|
||||
} else {
|
||||
|
@ -2489,11 +2486,6 @@ int r600_resume(struct radeon_device *rdev)
|
|||
*/
|
||||
/* post card */
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
/* Initialize clocks */
|
||||
r = radeon_clocks_init(rdev);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = r600_startup(rdev);
|
||||
if (r) {
|
||||
|
@ -2586,9 +2578,6 @@ int r600_init(struct radeon_device *rdev)
|
|||
radeon_surface_init(rdev);
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
r = radeon_clocks_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* Fence driver */
|
||||
r = radeon_fence_driver_init(rdev);
|
||||
if (r)
|
||||
|
@ -2663,7 +2652,6 @@ void r600_fini(struct radeon_device *rdev)
|
|||
radeon_agp_fini(rdev);
|
||||
radeon_gem_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_clocks_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
|
@ -3541,7 +3529,7 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
|
|||
* rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
|
||||
*/
|
||||
if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
|
||||
void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
|
||||
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
|
||||
u32 tmp;
|
||||
|
||||
WREG32(HDP_DEBUG1, 0);
|
||||
|
|
|
@ -1013,6 +1013,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
|
|||
int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filp);
|
||||
|
||||
/* VRAM scratch page for HDP bug */
|
||||
struct r700_vram_scratch {
|
||||
struct radeon_bo *robj;
|
||||
volatile uint32_t *ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Core structure, functions and helpers.
|
||||
|
@ -1079,6 +1084,7 @@ struct radeon_device {
|
|||
const struct firmware *pfp_fw; /* r6/700 PFP firmware */
|
||||
const struct firmware *rlc_fw; /* r6/700 RLC firmware */
|
||||
struct r600_blit r600_blit;
|
||||
struct r700_vram_scratch vram_scratch;
|
||||
int msi_enabled; /* msi enabled */
|
||||
struct r600_ih ih; /* r6/700 interrupt ring */
|
||||
struct workqueue_struct *wq;
|
||||
|
@ -1333,8 +1339,6 @@ extern bool radeon_card_posted(struct radeon_device *rdev);
|
|||
extern void radeon_update_bandwidth_info(struct radeon_device *rdev);
|
||||
extern void radeon_update_display_priority(struct radeon_device *rdev);
|
||||
extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
|
||||
extern int radeon_clocks_init(struct radeon_device *rdev);
|
||||
extern void radeon_clocks_fini(struct radeon_device *rdev);
|
||||
extern void radeon_scratch_init(struct radeon_device *rdev);
|
||||
extern void radeon_surface_init(struct radeon_device *rdev);
|
||||
extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
|
||||
|
|
|
@ -858,21 +858,3 @@ int radeon_asic_init(struct radeon_device *rdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper around modesetting bits. Move to radeon_clocks.c?
|
||||
*/
|
||||
int radeon_clocks_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = radeon_static_clocks_init(rdev->ddev);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
DRM_INFO("Clocks initialized !\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_clocks_fini(struct radeon_device *rdev)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -85,6 +85,19 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
|
|||
for (i = 0; i < num_indices; i++) {
|
||||
gpio = &i2c_info->asGPIO_Info[i];
|
||||
|
||||
/* some evergreen boards have bad data for this entry */
|
||||
if (ASIC_IS_DCE4(rdev)) {
|
||||
if ((i == 7) &&
|
||||
(gpio->usClkMaskRegisterIndex == 0x1936) &&
|
||||
(gpio->sucI2cId.ucAccess == 0)) {
|
||||
gpio->sucI2cId.ucAccess = 0x97;
|
||||
gpio->ucDataMaskShift = 8;
|
||||
gpio->ucDataEnShift = 8;
|
||||
gpio->ucDataY_Shift = 8;
|
||||
gpio->ucDataA_Shift = 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (gpio->sucI2cId.ucAccess == id) {
|
||||
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
|
||||
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
|
||||
|
@ -147,6 +160,20 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
|
|||
for (i = 0; i < num_indices; i++) {
|
||||
gpio = &i2c_info->asGPIO_Info[i];
|
||||
i2c.valid = false;
|
||||
|
||||
/* some evergreen boards have bad data for this entry */
|
||||
if (ASIC_IS_DCE4(rdev)) {
|
||||
if ((i == 7) &&
|
||||
(gpio->usClkMaskRegisterIndex == 0x1936) &&
|
||||
(gpio->sucI2cId.ucAccess == 0)) {
|
||||
gpio->sucI2cId.ucAccess = 0x97;
|
||||
gpio->ucDataMaskShift = 8;
|
||||
gpio->ucDataEnShift = 8;
|
||||
gpio->ucDataY_Shift = 8;
|
||||
gpio->ucDataA_Shift = 8;
|
||||
}
|
||||
}
|
||||
|
||||
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
|
||||
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
|
||||
i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
|
||||
|
|
|
@ -327,6 +327,14 @@ void radeon_get_clock_info(struct drm_device *dev)
|
|||
mpll->max_feedback_div = 0xff;
|
||||
mpll->best_vco = 0;
|
||||
|
||||
if (!rdev->clock.default_sclk)
|
||||
rdev->clock.default_sclk = radeon_get_engine_clock(rdev);
|
||||
if ((!rdev->clock.default_mclk) && rdev->asic->get_memory_clock)
|
||||
rdev->clock.default_mclk = radeon_get_memory_clock(rdev);
|
||||
|
||||
rdev->pm.current_sclk = rdev->clock.default_sclk;
|
||||
rdev->pm.current_mclk = rdev->clock.default_mclk;
|
||||
|
||||
}
|
||||
|
||||
/* 10 khz */
|
||||
|
@ -897,53 +905,3 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
|
|||
}
|
||||
}
|
||||
|
||||
static void radeon_apply_clock_quirks(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* XXX make sure engine is idle */
|
||||
|
||||
if (rdev->family < CHIP_RS600) {
|
||||
tmp = RREG32_PLL(RADEON_SCLK_CNTL);
|
||||
if (ASIC_IS_R300(rdev) || ASIC_IS_RV100(rdev))
|
||||
tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP;
|
||||
if ((rdev->family == CHIP_RV250)
|
||||
|| (rdev->family == CHIP_RV280))
|
||||
tmp |=
|
||||
RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_DISP2;
|
||||
if ((rdev->family == CHIP_RV350)
|
||||
|| (rdev->family == CHIP_RV380))
|
||||
tmp |= R300_SCLK_FORCE_VAP;
|
||||
if (rdev->family == CHIP_R420)
|
||||
tmp |= R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX;
|
||||
WREG32_PLL(RADEON_SCLK_CNTL, tmp);
|
||||
} else if (rdev->family < CHIP_R600) {
|
||||
tmp = RREG32_PLL(AVIVO_CP_DYN_CNTL);
|
||||
tmp |= AVIVO_CP_FORCEON;
|
||||
WREG32_PLL(AVIVO_CP_DYN_CNTL, tmp);
|
||||
|
||||
tmp = RREG32_PLL(AVIVO_E2_DYN_CNTL);
|
||||
tmp |= AVIVO_E2_FORCEON;
|
||||
WREG32_PLL(AVIVO_E2_DYN_CNTL, tmp);
|
||||
|
||||
tmp = RREG32_PLL(AVIVO_IDCT_DYN_CNTL);
|
||||
tmp |= AVIVO_IDCT_FORCEON;
|
||||
WREG32_PLL(AVIVO_IDCT_DYN_CNTL, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
int radeon_static_clocks_init(struct drm_device *dev)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
/* XXX make sure engine is idle */
|
||||
|
||||
if (radeon_dynclks != -1) {
|
||||
if (radeon_dynclks) {
|
||||
if (rdev->asic->set_clock_gating)
|
||||
radeon_set_clock_gating(rdev, 1);
|
||||
}
|
||||
}
|
||||
radeon_apply_clock_quirks(rdev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1051,10 +1051,16 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
uint32_t subpixel_order = SubPixelNone;
|
||||
bool shared_ddc = false;
|
||||
|
||||
/* fixme - tv/cv/din */
|
||||
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
|
||||
return;
|
||||
|
||||
/* if the user selected tv=0 don't try and add the connector */
|
||||
if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
|
||||
(connector_type == DRM_MODE_CONNECTOR_Composite) ||
|
||||
(connector_type == DRM_MODE_CONNECTOR_9PinDIN)) &&
|
||||
(radeon_tv == 0))
|
||||
return;
|
||||
|
||||
/* see if we already added it */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
radeon_connector = to_radeon_connector(connector);
|
||||
|
@ -1209,19 +1215,17 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
case DRM_MODE_CONNECTOR_Composite:
|
||||
case DRM_MODE_CONNECTOR_9PinDIN:
|
||||
if (radeon_tv == 1) {
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
radeon_atombios_get_tv_info(rdev));
|
||||
/* no HPD on analog connectors */
|
||||
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
}
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
radeon_atombios_get_tv_info(rdev));
|
||||
/* no HPD on analog connectors */
|
||||
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
|
||||
|
@ -1272,10 +1276,16 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
struct radeon_connector *radeon_connector;
|
||||
uint32_t subpixel_order = SubPixelNone;
|
||||
|
||||
/* fixme - tv/cv/din */
|
||||
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
|
||||
return;
|
||||
|
||||
/* if the user selected tv=0 don't try and add the connector */
|
||||
if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
|
||||
(connector_type == DRM_MODE_CONNECTOR_Composite) ||
|
||||
(connector_type == DRM_MODE_CONNECTOR_9PinDIN)) &&
|
||||
(radeon_tv == 0))
|
||||
return;
|
||||
|
||||
/* see if we already added it */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
radeon_connector = to_radeon_connector(connector);
|
||||
|
@ -1347,26 +1357,24 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
case DRM_MODE_CONNECTOR_Composite:
|
||||
case DRM_MODE_CONNECTOR_9PinDIN:
|
||||
if (radeon_tv == 1) {
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
radeon_connector->dac_load_detect = true;
|
||||
/* RS400,RC410,RS480 chipset seems to report a lot
|
||||
* of false positive on load detect, we haven't yet
|
||||
* found a way to make load detect reliable on those
|
||||
* chipset, thus just disable it for TV.
|
||||
*/
|
||||
if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
|
||||
radeon_connector->dac_load_detect = false;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
radeon_connector->dac_load_detect);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
radeon_combios_get_tv_info(rdev));
|
||||
/* no HPD on analog connectors */
|
||||
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
}
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
radeon_connector->dac_load_detect = true;
|
||||
/* RS400,RC410,RS480 chipset seems to report a lot
|
||||
* of false positive on load detect, we haven't yet
|
||||
* found a way to make load detect reliable on those
|
||||
* chipset, thus just disable it for TV.
|
||||
*/
|
||||
if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
|
||||
radeon_connector->dac_load_detect = false;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
radeon_connector->dac_load_detect);
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.tv_std_property,
|
||||
radeon_combios_get_tv_info(rdev));
|
||||
/* no HPD on analog connectors */
|
||||
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
|
||||
|
|
|
@ -293,30 +293,20 @@ bool radeon_card_posted(struct radeon_device *rdev)
|
|||
void radeon_update_bandwidth_info(struct radeon_device *rdev)
|
||||
{
|
||||
fixed20_12 a;
|
||||
u32 sclk, mclk;
|
||||
u32 sclk = rdev->pm.current_sclk;
|
||||
u32 mclk = rdev->pm.current_mclk;
|
||||
|
||||
/* sclk/mclk in Mhz */
|
||||
a.full = dfixed_const(100);
|
||||
rdev->pm.sclk.full = dfixed_const(sclk);
|
||||
rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a);
|
||||
rdev->pm.mclk.full = dfixed_const(mclk);
|
||||
rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a);
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
sclk = radeon_get_engine_clock(rdev);
|
||||
mclk = rdev->clock.default_mclk;
|
||||
|
||||
a.full = dfixed_const(100);
|
||||
rdev->pm.sclk.full = dfixed_const(sclk);
|
||||
rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a);
|
||||
rdev->pm.mclk.full = dfixed_const(mclk);
|
||||
rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a);
|
||||
|
||||
a.full = dfixed_const(16);
|
||||
/* core_bandwidth = sclk(Mhz) * 16 */
|
||||
rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a);
|
||||
} else {
|
||||
sclk = radeon_get_engine_clock(rdev);
|
||||
mclk = radeon_get_memory_clock(rdev);
|
||||
|
||||
a.full = dfixed_const(100);
|
||||
rdev->pm.sclk.full = dfixed_const(sclk);
|
||||
rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a);
|
||||
rdev->pm.mclk.full = dfixed_const(mclk);
|
||||
rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ static void post_xfer(struct i2c_adapter *i2c_adap)
|
|||
|
||||
static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
|
||||
{
|
||||
u32 sclk = radeon_get_engine_clock(rdev);
|
||||
u32 sclk = rdev->pm.current_sclk;
|
||||
u32 prescale = 0;
|
||||
u32 nm;
|
||||
u8 n, m, loop;
|
||||
|
|
|
@ -600,7 +600,6 @@ extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct d
|
|||
void radeon_enc_destroy(struct drm_encoder *encoder);
|
||||
void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
|
||||
void radeon_combios_asic_init(struct drm_device *dev);
|
||||
extern int radeon_static_clocks_init(struct drm_device *dev);
|
||||
bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
|
|
|
@ -905,6 +905,54 @@ static void rv770_gpu_init(struct radeon_device *rdev)
|
|||
|
||||
}
|
||||
|
||||
static int rv770_vram_scratch_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
u64 gpu_addr;
|
||||
|
||||
if (rdev->vram_scratch.robj == NULL) {
|
||||
r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
|
||||
true, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->vram_scratch.robj);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
r = radeon_bo_pin(rdev->vram_scratch.robj,
|
||||
RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
|
||||
if (r) {
|
||||
radeon_bo_unreserve(rdev->vram_scratch.robj);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_kmap(rdev->vram_scratch.robj,
|
||||
(void **)&rdev->vram_scratch.ptr);
|
||||
if (r)
|
||||
radeon_bo_unpin(rdev->vram_scratch.robj);
|
||||
radeon_bo_unreserve(rdev->vram_scratch.robj);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void rv770_vram_scratch_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (rdev->vram_scratch.robj == NULL) {
|
||||
return;
|
||||
}
|
||||
r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
|
||||
if (likely(r == 0)) {
|
||||
radeon_bo_kunmap(rdev->vram_scratch.robj);
|
||||
radeon_bo_unpin(rdev->vram_scratch.robj);
|
||||
radeon_bo_unreserve(rdev->vram_scratch.robj);
|
||||
}
|
||||
radeon_bo_unref(&rdev->vram_scratch.robj);
|
||||
}
|
||||
|
||||
int rv770_mc_init(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
@ -970,6 +1018,9 @@ static int rv770_startup(struct radeon_device *rdev)
|
|||
if (r)
|
||||
return r;
|
||||
}
|
||||
r = rv770_vram_scratch_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rv770_gpu_init(rdev);
|
||||
r = r600_blit_init(rdev);
|
||||
if (r) {
|
||||
|
@ -1023,11 +1074,6 @@ int rv770_resume(struct radeon_device *rdev)
|
|||
*/
|
||||
/* post card */
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
/* Initialize clocks */
|
||||
r = radeon_clocks_init(rdev);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = rv770_startup(rdev);
|
||||
if (r) {
|
||||
|
@ -1118,9 +1164,6 @@ int rv770_init(struct radeon_device *rdev)
|
|||
radeon_surface_init(rdev);
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
r = radeon_clocks_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* Fence driver */
|
||||
r = radeon_fence_driver_init(rdev);
|
||||
if (r)
|
||||
|
@ -1195,9 +1238,9 @@ void rv770_fini(struct radeon_device *rdev)
|
|||
r600_irq_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
rv770_pcie_gart_fini(rdev);
|
||||
rv770_vram_scratch_fini(rdev);
|
||||
radeon_gem_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_clocks_fini(rdev);
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_bo_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
mktables
|
||||
raid6altivec*.c
|
||||
raid6int*.c
|
||||
raid6tables.c
|
|
@ -1542,8 +1542,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
|
|||
atomic_read(&bitmap->mddev->recovery_active) == 0);
|
||||
|
||||
bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync;
|
||||
if (bitmap->mddev->persistent)
|
||||
set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
|
||||
set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
|
||||
sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
|
||||
s = 0;
|
||||
while (s < sector && s < bitmap->mddev->resync_max_sectors) {
|
||||
|
|
|
@ -2167,9 +2167,9 @@ static void md_update_sb(mddev_t * mddev, int force_change)
|
|||
rdev->recovery_offset = mddev->curr_resync_completed;
|
||||
|
||||
}
|
||||
if (mddev->external || !mddev->persistent) {
|
||||
clear_bit(MD_CHANGE_DEVS, &mddev->flags);
|
||||
if (!mddev->persistent) {
|
||||
clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
clear_bit(MD_CHANGE_DEVS, &mddev->flags);
|
||||
wake_up(&mddev->sb_wait);
|
||||
return;
|
||||
}
|
||||
|
@ -2178,7 +2178,6 @@ static void md_update_sb(mddev_t * mddev, int force_change)
|
|||
|
||||
mddev->utime = get_seconds();
|
||||
|
||||
set_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
|
||||
force_change = 1;
|
||||
if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags))
|
||||
|
@ -3371,7 +3370,7 @@ array_state_show(mddev_t *mddev, char *page)
|
|||
case 0:
|
||||
if (mddev->in_sync)
|
||||
st = clean;
|
||||
else if (test_bit(MD_CHANGE_CLEAN, &mddev->flags))
|
||||
else if (test_bit(MD_CHANGE_PENDING, &mddev->flags))
|
||||
st = write_pending;
|
||||
else if (mddev->safemode)
|
||||
st = active_idle;
|
||||
|
@ -3452,9 +3451,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
|
|||
mddev->in_sync = 1;
|
||||
if (mddev->safemode == 1)
|
||||
mddev->safemode = 0;
|
||||
if (mddev->persistent)
|
||||
set_bit(MD_CHANGE_CLEAN,
|
||||
&mddev->flags);
|
||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
}
|
||||
err = 0;
|
||||
} else
|
||||
|
@ -3466,8 +3463,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
|
|||
case active:
|
||||
if (mddev->pers) {
|
||||
restart_array(mddev);
|
||||
if (mddev->external)
|
||||
clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
clear_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
wake_up(&mddev->sb_wait);
|
||||
err = 0;
|
||||
} else {
|
||||
|
@ -6572,6 +6568,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
|
|||
if (mddev->in_sync) {
|
||||
mddev->in_sync = 0;
|
||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
set_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
md_wakeup_thread(mddev->thread);
|
||||
did_change = 1;
|
||||
}
|
||||
|
@ -6580,7 +6577,6 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
|
|||
if (did_change)
|
||||
sysfs_notify_dirent_safe(mddev->sysfs_state);
|
||||
wait_event(mddev->sb_wait,
|
||||
!test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
|
||||
!test_bit(MD_CHANGE_PENDING, &mddev->flags));
|
||||
}
|
||||
|
||||
|
@ -6616,6 +6612,7 @@ int md_allow_write(mddev_t *mddev)
|
|||
if (mddev->in_sync) {
|
||||
mddev->in_sync = 0;
|
||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
set_bit(MD_CHANGE_PENDING, &mddev->flags);
|
||||
if (mddev->safemode_delay &&
|
||||
mddev->safemode == 0)
|
||||
mddev->safemode = 1;
|
||||
|
@ -6625,7 +6622,7 @@ int md_allow_write(mddev_t *mddev)
|
|||
} else
|
||||
spin_unlock_irq(&mddev->write_lock);
|
||||
|
||||
if (test_bit(MD_CHANGE_CLEAN, &mddev->flags))
|
||||
if (test_bit(MD_CHANGE_PENDING, &mddev->flags))
|
||||
return -EAGAIN;
|
||||
else
|
||||
return 0;
|
||||
|
@ -6823,8 +6820,7 @@ void md_do_sync(mddev_t *mddev)
|
|||
atomic_read(&mddev->recovery_active) == 0);
|
||||
mddev->curr_resync_completed =
|
||||
mddev->curr_resync;
|
||||
if (mddev->persistent)
|
||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
|
||||
}
|
||||
|
||||
|
@ -7103,8 +7099,7 @@ void md_check_recovery(mddev_t *mddev)
|
|||
mddev->recovery_cp == MaxSector) {
|
||||
mddev->in_sync = 1;
|
||||
did_change = 1;
|
||||
if (mddev->persistent)
|
||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||
}
|
||||
if (mddev->safemode == 1)
|
||||
mddev->safemode = 0;
|
||||
|
|
|
@ -140,7 +140,7 @@ struct mddev_s
|
|||
unsigned long flags;
|
||||
#define MD_CHANGE_DEVS 0 /* Some device status has changed */
|
||||
#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
|
||||
#define MD_CHANGE_PENDING 2 /* superblock update in progress */
|
||||
#define MD_CHANGE_PENDING 2 /* switch from 'clean' to 'active' in progress */
|
||||
|
||||
int suspended;
|
||||
atomic_t active_io;
|
||||
|
|
|
@ -6,7 +6,7 @@ config MTD_UBI_DEBUG
|
|||
depends on SYSFS
|
||||
depends on MTD_UBI
|
||||
select DEBUG_FS
|
||||
select KALLSYMS_ALL
|
||||
select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL
|
||||
help
|
||||
This option enables UBI debugging.
|
||||
|
||||
|
|
|
@ -798,18 +798,18 @@ static int rename_volumes(struct ubi_device *ubi,
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
|
||||
if (!re) {
|
||||
re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
|
||||
if (!re1) {
|
||||
err = -ENOMEM;
|
||||
ubi_close_volume(desc);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
re->remove = 1;
|
||||
re->desc = desc;
|
||||
list_add(&re->list, &rename_list);
|
||||
re1->remove = 1;
|
||||
re1->desc = desc;
|
||||
list_add(&re1->list, &rename_list);
|
||||
dbg_msg("will remove volume %d, name \"%s\"",
|
||||
re->desc->vol->vol_id, re->desc->vol->name);
|
||||
re1->desc->vol->vol_id, re1->desc->vol->name);
|
||||
}
|
||||
|
||||
mutex_lock(&ubi->device_mutex);
|
||||
|
|
|
@ -843,7 +843,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
|
|||
case UBI_COMPAT_DELETE:
|
||||
ubi_msg("\"delete\" compatible internal volume %d:%d"
|
||||
" found, will remove it", vol_id, lnum);
|
||||
err = add_to_list(si, pnum, ec, &si->corr);
|
||||
err = add_to_list(si, pnum, ec, &si->erase);
|
||||
if (err)
|
||||
return err;
|
||||
return 0;
|
||||
|
|
|
@ -1212,7 +1212,8 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum)
|
|||
retry:
|
||||
spin_lock(&ubi->wl_lock);
|
||||
e = ubi->lookuptbl[pnum];
|
||||
if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub)) {
|
||||
if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub) ||
|
||||
in_wl_tree(e, &ubi->erroneous)) {
|
||||
spin_unlock(&ubi->wl_lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -647,7 +647,7 @@ struct vortex_private {
|
|||
u16 io_size; /* Size of PCI region (for release_region) */
|
||||
|
||||
/* Serialises access to hardware other than MII and variables below.
|
||||
* The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */
|
||||
* The lock hierarchy is rtnl_lock > {lock, mii_lock} > window_lock. */
|
||||
spinlock_t lock;
|
||||
|
||||
spinlock_t mii_lock; /* Serialises access to MII */
|
||||
|
@ -2984,7 +2984,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
{
|
||||
int err;
|
||||
struct vortex_private *vp = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
pci_power_t state = 0;
|
||||
|
||||
if(VORTEX_PCI(vp))
|
||||
|
@ -2994,9 +2993,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
|
||||
if(state != 0)
|
||||
pci_set_power_state(VORTEX_PCI(vp), PCI_D0);
|
||||
spin_lock_irqsave(&vp->lock, flags);
|
||||
err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL);
|
||||
spin_unlock_irqrestore(&vp->lock, flags);
|
||||
if(state != 0)
|
||||
pci_set_power_state(VORTEX_PCI(vp), state);
|
||||
|
||||
|
|
|
@ -1637,6 +1637,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
|
|||
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b),
|
||||
PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0),
|
||||
PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956),
|
||||
PCMCIA_DEVICE_PROD_ID12("KENTRONICS", "KEP-230", 0xaf8144c9, 0x868f6616),
|
||||
PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64),
|
||||
PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5),
|
||||
PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3),
|
||||
|
|
|
@ -1606,6 +1606,8 @@ static int pxa168_eth_remove(struct platform_device *pdev)
|
|||
|
||||
iounmap(pep->base);
|
||||
pep->base = NULL;
|
||||
mdiobus_unregister(pep->smi_bus);
|
||||
mdiobus_free(pep->smi_bus);
|
||||
unregister_netdev(dev);
|
||||
flush_scheduled_work();
|
||||
free_netdev(dev);
|
||||
|
|
|
@ -1327,6 +1327,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
|
|||
PCI_DMA_TODEVICE);
|
||||
|
||||
rate = ieee80211_get_tx_rate(sc->hw, info);
|
||||
if (!rate) {
|
||||
ret = -EINVAL;
|
||||
goto err_unmap;
|
||||
}
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
flags |= AR5K_TXDESC_NOACK;
|
||||
|
|
|
@ -797,7 +797,7 @@ static bool ar9300_uncompress_block(struct ath_hw *ah,
|
|||
length = block[it+1];
|
||||
length &= 0xff;
|
||||
|
||||
if (length > 0 && spot >= 0 && spot+length < mdataSize) {
|
||||
if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
|
||||
ath_print(common, ATH_DBG_EEPROM,
|
||||
"Restore at %d: spot=%d "
|
||||
"offset=%d length=%d\n",
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
#define SD_NO_CTL 0xE0
|
||||
#define NO_CTL 0xff
|
||||
#define CTL_MODE_M 7
|
||||
#define CTL_MODE_M 0xf
|
||||
#define CTL_11A 0
|
||||
#define CTL_11B 1
|
||||
#define CTL_11G 2
|
||||
|
|
|
@ -31,7 +31,6 @@ enum ctl_group {
|
|||
#define NO_CTL 0xff
|
||||
#define SD_NO_CTL 0xE0
|
||||
#define NO_CTL 0xff
|
||||
#define CTL_MODE_M 7
|
||||
#define CTL_11A 0
|
||||
#define CTL_11B 1
|
||||
#define CTL_11G 2
|
||||
|
|
|
@ -128,7 +128,7 @@ struct if_sdio_card {
|
|||
bool helper_allocated;
|
||||
bool firmware_allocated;
|
||||
|
||||
u8 buffer[65536];
|
||||
u8 buffer[65536] __attribute__((aligned(4)));
|
||||
|
||||
spinlock_t lock;
|
||||
struct if_sdio_packet *packets;
|
||||
|
|
|
@ -446,7 +446,7 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
|
||||
(!payload->status))
|
||||
!(payload->status & P54_TX_FAILED))
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
if (payload->status & P54_TX_PSM_CANCELLED)
|
||||
info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
|
||||
|
|
|
@ -338,9 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
|
|||
acpi_handle chandle, handle;
|
||||
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
||||
flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
|
||||
OSC_SHPC_NATIVE_HP_CONTROL |
|
||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||
flags &= OSC_SHPC_NATIVE_HP_CONTROL;
|
||||
if (!flags) {
|
||||
err("Invalid flags %u specified!\n", flags);
|
||||
return -EINVAL;
|
||||
|
@ -360,7 +358,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
|
|||
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
|
||||
dbg("Trying to get hotplug control for %s\n",
|
||||
(char *)string.pointer);
|
||||
status = acpi_pci_osc_control_set(handle, flags);
|
||||
status = acpi_pci_osc_control_set(handle, &flags, flags);
|
||||
if (ACPI_SUCCESS(status))
|
||||
goto got_one;
|
||||
if (status == AE_SUPPORT)
|
||||
|
|
|
@ -176,19 +176,11 @@ static inline void pciehp_firmware_init(void)
|
|||
{
|
||||
pciehp_acpi_slot_detection_init();
|
||||
}
|
||||
|
||||
static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
|
||||
{
|
||||
int retval;
|
||||
u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
|
||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||
retval = acpi_get_hp_hw_control_from_firmware(dev, flags);
|
||||
if (retval)
|
||||
return retval;
|
||||
return pciehp_acpi_slot_detection_check(dev);
|
||||
}
|
||||
#else
|
||||
#define pciehp_firmware_init() do {} while (0)
|
||||
#define pciehp_get_hp_hw_control_from_firmware(dev) 0
|
||||
static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ACPI */
|
||||
#endif /* _PCIEHP_H */
|
||||
|
|
|
@ -85,9 +85,7 @@ static int __init dummy_probe(struct pcie_device *dev)
|
|||
acpi_handle handle;
|
||||
struct dummy_slot *slot, *tmp;
|
||||
struct pci_dev *pdev = dev->port;
|
||||
/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
|
||||
if (pciehp_get_hp_hw_control_from_firmware(pdev))
|
||||
return -ENODEV;
|
||||
|
||||
pos = pci_pcie_cap(pdev);
|
||||
if (!pos)
|
||||
return -ENODEV;
|
||||
|
|
|
@ -59,7 +59,7 @@ module_param(pciehp_force, bool, 0644);
|
|||
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
|
||||
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
|
||||
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
|
||||
MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
|
||||
MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing");
|
||||
|
||||
#define PCIE_MODULE_NAME "pciehp"
|
||||
|
||||
|
@ -235,7 +235,7 @@ static int pciehp_probe(struct pcie_device *dev)
|
|||
dev_info(&dev->device,
|
||||
"Bypassing BIOS check for pciehp use on %s\n",
|
||||
pci_name(dev->port));
|
||||
else if (pciehp_get_hp_hw_control_from_firmware(dev->port))
|
||||
else if (pciehp_acpi_slot_detection_check(dev->port))
|
||||
goto err_out_none;
|
||||
|
||||
ctrl = pcie_init(dev);
|
||||
|
|
|
@ -140,8 +140,10 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
|
|||
|
||||
#ifdef CONFIG_PCIEAER
|
||||
void pci_no_aer(void);
|
||||
bool pci_aer_available(void);
|
||||
#else
|
||||
static inline void pci_no_aer(void) { }
|
||||
static inline bool pci_aer_available(void) { return false; }
|
||||
#endif
|
||||
|
||||
static inline int pci_no_d1d2(struct pci_dev *dev)
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
obj-$(CONFIG_PCIEASPM) += aspm.o
|
||||
|
||||
pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
|
||||
pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o
|
||||
|
||||
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
|
||||
|
||||
# Build PCI Express AER if needed
|
||||
obj-$(CONFIG_PCIEAER) += aer/
|
||||
|
||||
obj-$(CONFIG_PCIE_PME) += pme/
|
||||
obj-$(CONFIG_PCIE_PME) += pme.o
|
||||
|
|
|
@ -72,6 +72,11 @@ void pci_no_aer(void)
|
|||
pcie_aer_disable = 1; /* has priority over 'forceload' */
|
||||
}
|
||||
|
||||
bool pci_aer_available(void)
|
||||
{
|
||||
return !pcie_aer_disable && pci_msi_enabled();
|
||||
}
|
||||
|
||||
static int set_device_error_reporting(struct pci_dev *dev, void *data)
|
||||
{
|
||||
bool enable = *((bool *)data);
|
||||
|
@ -411,9 +416,7 @@ static void aer_error_resume(struct pci_dev *dev)
|
|||
*/
|
||||
static int __init aer_service_init(void)
|
||||
{
|
||||
if (pcie_aer_disable)
|
||||
return -ENXIO;
|
||||
if (!pci_msi_enabled())
|
||||
if (!pci_aer_available())
|
||||
return -ENXIO;
|
||||
return pcie_port_service_register(&aerdriver);
|
||||
}
|
||||
|
|
|
@ -19,42 +19,6 @@
|
|||
#include <acpi/apei.h>
|
||||
#include "aerdrv.h"
|
||||
|
||||
/**
|
||||
* aer_osc_setup - run ACPI _OSC method
|
||||
* @pciedev: pcie_device which AER is being enabled on
|
||||
*
|
||||
* @return: Zero on success. Nonzero otherwise.
|
||||
*
|
||||
* Invoked when PCIe bus loads AER service driver. To avoid conflict with
|
||||
* BIOS AER support requires BIOS to yield AER control to OS native driver.
|
||||
**/
|
||||
int aer_osc_setup(struct pcie_device *pciedev)
|
||||
{
|
||||
acpi_status status = AE_NOT_FOUND;
|
||||
struct pci_dev *pdev = pciedev->port;
|
||||
acpi_handle handle = NULL;
|
||||
|
||||
if (acpi_pci_disabled)
|
||||
return -1;
|
||||
|
||||
handle = acpi_find_root_bridge_handle(pdev);
|
||||
if (handle) {
|
||||
status = acpi_pci_osc_control_set(handle,
|
||||
OSC_PCI_EXPRESS_AER_CONTROL |
|
||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||
}
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_printk(KERN_DEBUG, &pciedev->device, "AER service couldn't "
|
||||
"init device: %s\n",
|
||||
(status == AE_SUPPORT || status == AE_NOT_FOUND) ?
|
||||
"no _OSC support" : "_OSC failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI
|
||||
static inline int hest_match_pci(struct acpi_hest_aer_common *p,
|
||||
struct pci_dev *pci)
|
||||
|
|
|
@ -772,22 +772,10 @@ void aer_isr(struct work_struct *work)
|
|||
*/
|
||||
int aer_init(struct pcie_device *dev)
|
||||
{
|
||||
if (pcie_aer_get_firmware_first(dev->port)) {
|
||||
dev_printk(KERN_DEBUG, &dev->device,
|
||||
"PCIe errors handled by platform firmware.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (aer_osc_setup(dev))
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (forceload) {
|
||||
dev_printk(KERN_DEBUG, &dev->device,
|
||||
"aerdrv forceload requested.\n");
|
||||
pcie_aer_force_firmware_first(dev->port, 0);
|
||||
return 0;
|
||||
}
|
||||
return -ENXIO;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,37 +23,12 @@
|
|||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "../../pci.h"
|
||||
#include "pcie_pme.h"
|
||||
#include "../pci.h"
|
||||
#include "portdrv.h"
|
||||
|
||||
#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
|
||||
#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
|
||||
|
||||
/*
|
||||
* If set, this switch will prevent the PCIe root port PME service driver from
|
||||
* being registered. Consequently, the interrupt-based PCIe PME signaling will
|
||||
* not be used by any PCIe root ports in that case.
|
||||
*/
|
||||
static bool pcie_pme_disabled = true;
|
||||
|
||||
/*
|
||||
* The PCI Express Base Specification 2.0, Section 6.1.8, states the following:
|
||||
* "In order to maintain compatibility with non-PCI Express-aware system
|
||||
* software, system power management logic must be configured by firmware to use
|
||||
* the legacy mechanism of signaling PME by default. PCI Express-aware system
|
||||
* software must notify the firmware prior to enabling native, interrupt-based
|
||||
* PME signaling." However, if the platform doesn't provide us with a suitable
|
||||
* notification mechanism or the notification fails, it is not clear whether or
|
||||
* not we are supposed to use the interrupt-based PCIe PME signaling. The
|
||||
* switch below can be used to indicate the desired behaviour. When set, it
|
||||
* will make the kernel use the interrupt-based PCIe PME signaling regardless of
|
||||
* the platform notification status, although the kernel will attempt to notify
|
||||
* the platform anyway. When unset, it will prevent the kernel from using the
|
||||
* the interrupt-based PCIe PME signaling if the platform notification fails,
|
||||
* which is the default.
|
||||
*/
|
||||
static bool pcie_pme_force_enable;
|
||||
|
||||
/*
|
||||
* If this switch is set, MSI will not be used for PCIe PME signaling. This
|
||||
* causes the PCIe port driver to use INTx interrupts only, but it turns out
|
||||
|
@ -64,38 +39,13 @@ bool pcie_pme_msi_disabled;
|
|||
|
||||
static int __init pcie_pme_setup(char *str)
|
||||
{
|
||||
if (!strncmp(str, "auto", 4))
|
||||
pcie_pme_disabled = false;
|
||||
else if (!strncmp(str, "force", 5))
|
||||
pcie_pme_force_enable = true;
|
||||
|
||||
str = strchr(str, ',');
|
||||
if (str) {
|
||||
str++;
|
||||
str += strspn(str, " \t");
|
||||
if (*str && !strcmp(str, "nomsi"))
|
||||
pcie_pme_msi_disabled = true;
|
||||
}
|
||||
if (!strncmp(str, "nomsi", 5))
|
||||
pcie_pme_msi_disabled = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
__setup("pcie_pme=", pcie_pme_setup);
|
||||
|
||||
/**
|
||||
* pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME.
|
||||
* @srv: PCIe PME root port service to use for carrying out the check.
|
||||
*
|
||||
* Notify the platform that the native PCIe PME is going to be used and return
|
||||
* 'true' if the control of the PCIe PME registers has been acquired from the
|
||||
* platform.
|
||||
*/
|
||||
static bool pcie_pme_platform_setup(struct pcie_device *srv)
|
||||
{
|
||||
if (!pcie_pme_platform_notify(srv))
|
||||
return true;
|
||||
return pcie_pme_force_enable;
|
||||
}
|
||||
|
||||
struct pcie_pme_service_data {
|
||||
spinlock_t lock;
|
||||
struct pcie_device *srv;
|
||||
|
@ -108,7 +58,7 @@ struct pcie_pme_service_data {
|
|||
* @dev: PCIe root port or event collector.
|
||||
* @enable: Enable or disable the interrupt.
|
||||
*/
|
||||
static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
|
||||
void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
|
||||
{
|
||||
int rtctl_pos;
|
||||
u16 rtctl;
|
||||
|
@ -417,9 +367,6 @@ static int pcie_pme_probe(struct pcie_device *srv)
|
|||
struct pcie_pme_service_data *data;
|
||||
int ret;
|
||||
|
||||
if (!pcie_pme_platform_setup(srv))
|
||||
return -EACCES;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
@ -509,8 +456,7 @@ static struct pcie_port_service_driver pcie_pme_driver = {
|
|||
*/
|
||||
static int __init pcie_pme_service_init(void)
|
||||
{
|
||||
return pcie_pme_disabled ?
|
||||
-ENODEV : pcie_port_service_register(&pcie_pme_driver);
|
||||
return pcie_port_service_register(&pcie_pme_driver);
|
||||
}
|
||||
|
||||
module_init(pcie_pme_service_init);
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# Makefile for PCI-Express Root Port PME signaling driver
|
||||
#
|
||||
|
||||
obj-$(CONFIG_PCIE_PME) += pmedriver.o
|
||||
|
||||
pmedriver-objs := pcie_pme.o
|
||||
pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* drivers/pci/pcie/pme/pcie_pme.h
|
||||
*
|
||||
* PCI Express Root Port PME signaling support
|
||||
*
|
||||
* Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
|
||||
*/
|
||||
|
||||
#ifndef _PCIE_PME_H_
|
||||
#define _PCIE_PME_H_
|
||||
|
||||
struct pcie_device;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
extern int pcie_pme_acpi_setup(struct pcie_device *srv);
|
||||
|
||||
static inline int pcie_pme_platform_notify(struct pcie_device *srv)
|
||||
{
|
||||
return pcie_pme_acpi_setup(srv);
|
||||
}
|
||||
#else /* !CONFIG_ACPI */
|
||||
static inline int pcie_pme_platform_notify(struct pcie_device *srv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* !CONFIG_ACPI */
|
||||
|
||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* PCIe Native PME support, ACPI-related part
|
||||
*
|
||||
* Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License V2. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pcieport_if.h>
|
||||
|
||||
/**
|
||||
* pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME.
|
||||
* @srv - PCIe PME service for a root port or event collector.
|
||||
*
|
||||
* Invoked when the PCIe bus type loads PCIe PME service driver. To avoid
|
||||
* conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME
|
||||
* control to the kernel.
|
||||
*/
|
||||
int pcie_pme_acpi_setup(struct pcie_device *srv)
|
||||
{
|
||||
acpi_status status = AE_NOT_FOUND;
|
||||
struct pci_dev *port = srv->port;
|
||||
acpi_handle handle;
|
||||
int error = 0;
|
||||
|
||||
if (acpi_pci_disabled)
|
||||
return -ENOSYS;
|
||||
|
||||
dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n");
|
||||
|
||||
handle = acpi_find_root_bridge_handle(port);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_pci_osc_control_set(handle,
|
||||
OSC_PCI_EXPRESS_PME_CONTROL |
|
||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_info(&port->dev,
|
||||
"Failed to receive control of PCIe PME service: %s\n",
|
||||
(status == AE_SUPPORT || status == AE_NOT_FOUND) ?
|
||||
"no _OSC support" : "ACPI _OSC failed");
|
||||
error = -ENODEV;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
|
||||
|
||||
extern bool pcie_ports_disabled;
|
||||
extern bool pcie_ports_auto;
|
||||
|
||||
extern struct bus_type pcie_port_bus_type;
|
||||
extern int pcie_port_device_register(struct pci_dev *dev);
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -30,6 +33,8 @@ extern void pcie_port_device_remove(struct pci_dev *dev);
|
|||
extern int __must_check pcie_port_bus_register(void);
|
||||
extern void pcie_port_bus_unregister(void);
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
#ifdef CONFIG_PCIE_PME
|
||||
extern bool pcie_pme_msi_disabled;
|
||||
|
||||
|
@ -42,9 +47,26 @@ static inline bool pcie_pme_no_msi(void)
|
|||
{
|
||||
return pcie_pme_msi_disabled;
|
||||
}
|
||||
|
||||
extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable);
|
||||
#else /* !CONFIG_PCIE_PME */
|
||||
static inline void pcie_pme_disable_msi(void) {}
|
||||
static inline bool pcie_pme_no_msi(void) { return false; }
|
||||
static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {}
|
||||
#endif /* !CONFIG_PCIE_PME */
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask);
|
||||
|
||||
static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
|
||||
{
|
||||
return pcie_port_acpi_setup(port, mask);
|
||||
}
|
||||
#else /* !CONFIG_ACPI */
|
||||
static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* !CONFIG_ACPI */
|
||||
|
||||
#endif /* _PORTDRV_H_ */
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* PCIe Port Native Services Support, ACPI-Related Part
|
||||
*
|
||||
* Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License V2. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pcieport_if.h>
|
||||
|
||||
#include "aer/aerdrv.h"
|
||||
#include "../pci.h"
|
||||
|
||||
/**
|
||||
* pcie_port_acpi_setup - Request the BIOS to release control of PCIe services.
|
||||
* @port: PCIe Port service for a root port or event collector.
|
||||
* @srv_mask: Bit mask of services that can be enabled for @port.
|
||||
*
|
||||
* Invoked when @port is identified as a PCIe port device. To avoid conflicts
|
||||
* with the BIOS PCIe port native services support requires the BIOS to yield
|
||||
* control of these services to the kernel. The mask of services that the BIOS
|
||||
* allows to be enabled for @port is written to @srv_mask.
|
||||
*
|
||||
* NOTE: It turns out that we cannot do that for individual port services
|
||||
* separately, because that would make some systems work incorrectly.
|
||||
*/
|
||||
int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_handle handle;
|
||||
u32 flags;
|
||||
|
||||
if (acpi_pci_disabled)
|
||||
return 0;
|
||||
|
||||
handle = acpi_find_root_bridge_handle(port);
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
|
||||
| OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
|
||||
| OSC_PCI_EXPRESS_PME_CONTROL;
|
||||
|
||||
if (pci_aer_available()) {
|
||||
if (pcie_aer_get_firmware_first(port))
|
||||
dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n");
|
||||
else
|
||||
flags |= OSC_PCI_EXPRESS_AER_CONTROL;
|
||||
}
|
||||
|
||||
status = acpi_pci_osc_control_set(handle, &flags,
|
||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n",
|
||||
status);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags);
|
||||
|
||||
*srv_mask = PCIE_PORT_SERVICE_VC;
|
||||
if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
|
||||
*srv_mask |= PCIE_PORT_SERVICE_HP;
|
||||
if (flags & OSC_PCI_EXPRESS_PME_CONTROL)
|
||||
*srv_mask |= PCIE_PORT_SERVICE_PME;
|
||||
if (flags & OSC_PCI_EXPRESS_AER_CONTROL)
|
||||
*srv_mask |= PCIE_PORT_SERVICE_AER;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -14,6 +14,8 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pcieport_if.h>
|
||||
#include <linux/aer.h>
|
||||
#include <linux/pci-aspm.h>
|
||||
|
||||
#include "../pci.h"
|
||||
#include "portdrv.h"
|
||||
|
@ -236,24 +238,64 @@ static int get_port_device_capability(struct pci_dev *dev)
|
|||
int services = 0, pos;
|
||||
u16 reg16;
|
||||
u32 reg32;
|
||||
int cap_mask;
|
||||
int err;
|
||||
|
||||
err = pcie_port_platform_notify(dev, &cap_mask);
|
||||
if (pcie_ports_auto) {
|
||||
if (err) {
|
||||
pcie_no_aspm();
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
|
||||
| PCIE_PORT_SERVICE_VC;
|
||||
if (pci_aer_available())
|
||||
cap_mask |= PCIE_PORT_SERVICE_AER;
|
||||
}
|
||||
|
||||
pos = pci_pcie_cap(dev);
|
||||
pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16);
|
||||
/* Hot-Plug Capable */
|
||||
if (reg16 & PCI_EXP_FLAGS_SLOT) {
|
||||
if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
|
||||
pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32);
|
||||
if (reg32 & PCI_EXP_SLTCAP_HPC)
|
||||
if (reg32 & PCI_EXP_SLTCAP_HPC) {
|
||||
services |= PCIE_PORT_SERVICE_HP;
|
||||
/*
|
||||
* Disable hot-plug interrupts in case they have been
|
||||
* enabled by the BIOS and the hot-plug service driver
|
||||
* is not loaded.
|
||||
*/
|
||||
pos += PCI_EXP_SLTCTL;
|
||||
pci_read_config_word(dev, pos, ®16);
|
||||
reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
|
||||
pci_write_config_word(dev, pos, reg16);
|
||||
}
|
||||
}
|
||||
/* AER capable */
|
||||
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
|
||||
if ((cap_mask & PCIE_PORT_SERVICE_AER)
|
||||
&& pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
|
||||
services |= PCIE_PORT_SERVICE_AER;
|
||||
/*
|
||||
* Disable AER on this port in case it's been enabled by the
|
||||
* BIOS (the AER service driver will enable it when necessary).
|
||||
*/
|
||||
pci_disable_pcie_error_reporting(dev);
|
||||
}
|
||||
/* VC support */
|
||||
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
|
||||
services |= PCIE_PORT_SERVICE_VC;
|
||||
/* Root ports are capable of generating PME too */
|
||||
if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
|
||||
if ((cap_mask & PCIE_PORT_SERVICE_PME)
|
||||
&& dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
|
||||
services |= PCIE_PORT_SERVICE_PME;
|
||||
/*
|
||||
* Disable PME interrupt on this port in case it's been enabled
|
||||
* by the BIOS (the PME service driver will enable it when
|
||||
* necessary).
|
||||
*/
|
||||
pcie_pme_interrupt_enable(dev, false);
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
@ -494,6 +536,9 @@ static void pcie_port_shutdown_service(struct device *dev) {}
|
|||
*/
|
||||
int pcie_port_service_register(struct pcie_port_service_driver *new)
|
||||
{
|
||||
if (pcie_ports_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
new->driver.name = (char *)new->name;
|
||||
new->driver.bus = &pcie_port_bus_type;
|
||||
new->driver.probe = pcie_port_probe_service;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue