mirror of https://gitee.com/openkylin/linux.git
Merge remote branch 'intel/drm-intel-next' of /ssd/git/drm-next into drm-core-next
* 'intel/drm-intel-next' of /ssd/git/drm-next: (230 commits) drm/i915: Clear the Ironlake dithering flags when the pipe doesn't want it. drm/agp/i915: trim stolen space to 32M drm/i915: Unset cursor if out-of-bounds upon mode change (v4) drm/i915: Unreference object not handle on creation drm/i915: Attempt to uncouple object after catastrophic failure in unbind drm/i915: Repeat unbinding during free if interrupted (v6) drm/i915: Refactor i915_gem_retire_requests() drm/i915: Warn if we run out of FIFO space for a mode drm/i915: Round up the watermark entries (v3) drm/i915: Typo in (unused) register mask for overlay. drm/i915: Check overlay stride errata for i830 and i845 drm/i915: Validate the mode for eDP by using fixed panel size drm/i915: Always use the fixed panel timing for eDP drm/i915: Enable panel fitting for eDP drm/i915: Add fixed panel mode parsed from EDID for eDP without fixed mode in VBT drm/i915/sdvo: Set sync polarity based on actual mode drm/i915/hdmi: Set sync polarity based on actual mode drm/i915/pch: Set transcoder sync polarity for DP based on actual mode drm/i915: Initialize LVDS and eDP outputs before anything else drm/i915/dp: Correctly report eDP in the core connector type ...
This commit is contained in:
commit
fa0a6024da
|
@ -417,6 +417,9 @@ reference on them using:
|
|||
This does all the RCU magic inside of it. The caller must call put_cred() on
|
||||
the credentials so obtained when they're finished with.
|
||||
|
||||
[*] Note: The result of __task_cred() should not be passed directly to
|
||||
get_cred() as this may race with commit_cred().
|
||||
|
||||
There are a couple of convenience functions to access bits of another task's
|
||||
credentials, hiding the RCU magic from the caller:
|
||||
|
||||
|
|
|
@ -647,3 +647,10 @@ Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
|
|||
|
||||
----------------------------
|
||||
|
||||
What: The acpi_sleep=s4_nonvs command line option
|
||||
When: 2.6.37
|
||||
Files: arch/x86/kernel/acpi/sleep.c
|
||||
Why: superseded by acpi_sleep=nonvs
|
||||
Who: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
|
||||
----------------------------
|
||||
|
|
|
@ -254,8 +254,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
control method, with respect to putting devices into
|
||||
low power states, to be enforced (the ACPI 2.0 ordering
|
||||
of _PTS is used by default).
|
||||
s4_nonvs prevents the kernel from saving/restoring the
|
||||
ACPI NVS memory during hibernation.
|
||||
nonvs prevents the kernel from saving/restoring the
|
||||
ACPI NVS memory during suspend/hibernation and resume.
|
||||
sci_force_enable causes the kernel to set SCI_EN directly
|
||||
on resume from S1/S3 (which is against the ACPI spec,
|
||||
but some broken systems don't work without it).
|
||||
|
|
|
@ -6243,6 +6243,8 @@ F: drivers/mmc/host/wbsd.*
|
|||
|
||||
WATCHDOG DEVICE DRIVERS
|
||||
M: Wim Van Sebroeck <wim@iguana.be>
|
||||
L: linux-watchdog@vger.kernel.org
|
||||
W: http://www.linux-watchdog.org/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
|
||||
S: Maintained
|
||||
F: Documentation/watchdog/
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 35
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION =
|
||||
NAME = Sheep on Meth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -71,6 +71,9 @@ targets := vmlinux vmlinux.lds \
|
|||
piggy.$(suffix_y) piggy.$(suffix_y).o \
|
||||
font.o font.c head.o misc.o $(OBJS)
|
||||
|
||||
# Make sure files are removed during clean
|
||||
extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S
|
||||
|
||||
ifeq ($(CONFIG_FUNCTION_TRACER),y)
|
||||
ORIG_CFLAGS := $(KBUILD_CFLAGS)
|
||||
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
|
||||
|
|
|
@ -1028,13 +1028,12 @@ static int sa1111_remove(struct platform_device *pdev)
|
|||
struct sa1111 *sachip = platform_get_drvdata(pdev);
|
||||
|
||||
if (sachip) {
|
||||
__sa1111_remove(sachip);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
kfree(sachip->saved_state);
|
||||
sachip->saved_state = NULL;
|
||||
#endif
|
||||
__sa1111_remove(sachip);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
/*
|
||||
* ISA I/O bus memory addresses are 1:1 with the physical address.
|
||||
|
@ -179,25 +180,38 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
|
|||
* IO port primitives for more information.
|
||||
*/
|
||||
#ifdef __mem_pci
|
||||
#define readb(c) ({ __u8 __v = __raw_readb(__mem_pci(c)); __v; })
|
||||
#define readw(c) ({ __u16 __v = le16_to_cpu((__force __le16) \
|
||||
#define readb_relaxed(c) ({ u8 __v = __raw_readb(__mem_pci(c)); __v; })
|
||||
#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \
|
||||
__raw_readw(__mem_pci(c))); __v; })
|
||||
#define readl(c) ({ __u32 __v = le32_to_cpu((__force __le32) \
|
||||
#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \
|
||||
__raw_readl(__mem_pci(c))); __v; })
|
||||
#define readb_relaxed(addr) readb(addr)
|
||||
#define readw_relaxed(addr) readw(addr)
|
||||
#define readl_relaxed(addr) readl(addr)
|
||||
|
||||
#define writeb_relaxed(v,c) ((void)__raw_writeb(v,__mem_pci(c)))
|
||||
#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \
|
||||
cpu_to_le16(v),__mem_pci(c)))
|
||||
#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \
|
||||
cpu_to_le32(v),__mem_pci(c)))
|
||||
|
||||
#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
|
||||
#define __iormb() rmb()
|
||||
#define __iowmb() wmb()
|
||||
#else
|
||||
#define __iormb() do { } while (0)
|
||||
#define __iowmb() do { } while (0)
|
||||
#endif
|
||||
|
||||
#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
|
||||
#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
|
||||
#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
|
||||
|
||||
#define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); })
|
||||
#define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); })
|
||||
#define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); })
|
||||
|
||||
#define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l)
|
||||
#define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l)
|
||||
#define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l)
|
||||
|
||||
#define writeb(v,c) __raw_writeb(v,__mem_pci(c))
|
||||
#define writew(v,c) __raw_writew((__force __u16) \
|
||||
cpu_to_le16(v),__mem_pci(c))
|
||||
#define writel(v,c) __raw_writel((__force __u32) \
|
||||
cpu_to_le32(v),__mem_pci(c))
|
||||
|
||||
#define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l)
|
||||
#define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l)
|
||||
#define writesl(p,d,l) __raw_writesl(__mem_pci(p),d,l)
|
||||
|
@ -244,13 +258,13 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
|
|||
* io{read,write}{8,16,32} macros
|
||||
*/
|
||||
#ifndef ioread8
|
||||
#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; })
|
||||
#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __v; })
|
||||
#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __v; })
|
||||
#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __iormb(); __v; })
|
||||
#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; })
|
||||
#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; })
|
||||
|
||||
#define iowrite8(v,p) __raw_writeb(v, p)
|
||||
#define iowrite16(v,p) __raw_writew((__force __u16)cpu_to_le16(v), p)
|
||||
#define iowrite32(v,p) __raw_writel((__force __u32)cpu_to_le32(v), p)
|
||||
#define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); })
|
||||
#define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); })
|
||||
#define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); })
|
||||
|
||||
#define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
|
||||
#define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.pushsection .fixup,"ax"
|
||||
.align 4
|
||||
9001: mov r4, #-EFAULT
|
||||
ldr r5, [fp, #4] @ *err_ptr
|
||||
ldr r5, [sp, #8*4] @ *err_ptr
|
||||
str r4, [r5]
|
||||
ldmia sp, {r1, r2} @ retrieve dst, len
|
||||
add r2, r2, r1
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/hardware/clps7111.h>
|
||||
|
||||
.macro addruart, rx, tmp
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/tps6507x.h>
|
||||
#include <linux/mfd/tps6507x.h>
|
||||
#include <linux/input/tps6507x-ts.h>
|
||||
|
||||
|
@ -469,6 +470,11 @@ struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* We take advantage of the fact that both defdcdc{2,3} are tied high */
|
||||
static struct tps6507x_reg_platform_data tps6507x_platform_data = {
|
||||
.defdcdc_default = true,
|
||||
};
|
||||
|
||||
struct regulator_init_data tps65070_regulator_data[] = {
|
||||
/* dcdc1 */
|
||||
{
|
||||
|
@ -494,6 +500,7 @@ struct regulator_init_data tps65070_regulator_data[] = {
|
|||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers),
|
||||
.consumer_supplies = tps65070_dcdc2_consumers,
|
||||
.driver_data = &tps6507x_platform_data,
|
||||
},
|
||||
|
||||
/* dcdc3 */
|
||||
|
@ -507,6 +514,7 @@ struct regulator_init_data tps65070_regulator_data[] = {
|
|||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers),
|
||||
.consumer_supplies = tps65070_dcdc3_consumers,
|
||||
.driver_data = &tps6507x_platform_data,
|
||||
},
|
||||
|
||||
/* ldo1 */
|
||||
|
|
|
@ -232,7 +232,7 @@ EXPORT_SYMBOL(__bus_to_virt);
|
|||
|
||||
unsigned long __pfn_to_bus(unsigned long pfn)
|
||||
{
|
||||
return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET));
|
||||
return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET);
|
||||
}
|
||||
EXPORT_SYMBOL(__pfn_to_bus);
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
.equ io_virt, IO_BASE
|
||||
.equ io_phys, IO_START
|
||||
#include <mach/hardware.h>
|
||||
|
||||
.equ io_virt, IO_VIRT
|
||||
.equ io_phys, IO_PHYS
|
||||
|
||||
.macro addruart, rx, tmp
|
||||
mrc p15, 0, \rx, c1, c0
|
||||
|
|
|
@ -77,7 +77,7 @@ struct spi_board_info __initdata qnap_tsx1x_spi_slave_info[] = {
|
|||
},
|
||||
};
|
||||
|
||||
void qnap_tsx1x_register_flash(void)
|
||||
void __init qnap_tsx1x_register_flash(void)
|
||||
{
|
||||
spi_register_board_info(qnap_tsx1x_spi_slave_info,
|
||||
ARRAY_SIZE(qnap_tsx1x_spi_slave_info));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __ARCH_KIRKWOOD_TSX1X_COMMON_H
|
||||
#define __ARCH_KIRKWOOD_TSX1X_COMMON_H
|
||||
|
||||
extern void qnap_tsx1x_register_flash(void);
|
||||
extern void __init qnap_tsx1x_register_flash(void);
|
||||
extern void qnap_tsx1x_power_off(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* the Free Software Foundation.
|
||||
*/
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/memory.h>
|
||||
|
||||
#include <mach/regs-board-a9m9750dev.h>
|
||||
|
||||
|
|
|
@ -20,50 +20,49 @@ static void putc_dummy(char c, void __iomem *base)
|
|||
/* nothing */
|
||||
}
|
||||
|
||||
static int timeout;
|
||||
|
||||
static void putc_ns9360(char c, void __iomem *base)
|
||||
{
|
||||
static int t = 0x10000;
|
||||
do {
|
||||
if (t)
|
||||
--t;
|
||||
if (timeout)
|
||||
--timeout;
|
||||
|
||||
if (__raw_readl(base + 8) & (1 << 3)) {
|
||||
__raw_writeb(c, base + 16);
|
||||
t = 0x10000;
|
||||
timeout = 0x10000;
|
||||
break;
|
||||
}
|
||||
} while (t);
|
||||
} while (timeout);
|
||||
}
|
||||
|
||||
static void putc_a9m9750dev(char c, void __iomem *base)
|
||||
{
|
||||
static int t = 0x10000;
|
||||
do {
|
||||
if (t)
|
||||
--t;
|
||||
if (timeout)
|
||||
--timeout;
|
||||
|
||||
if (__raw_readb(base + 5) & (1 << 5)) {
|
||||
__raw_writeb(c, base);
|
||||
t = 0x10000;
|
||||
timeout = 0x10000;
|
||||
break;
|
||||
}
|
||||
} while (t);
|
||||
} while (timeout);
|
||||
|
||||
}
|
||||
|
||||
static void putc_ns921x(char c, void __iomem *base)
|
||||
{
|
||||
static int t = 0x10000;
|
||||
do {
|
||||
if (t)
|
||||
--t;
|
||||
if (timeout)
|
||||
--timeout;
|
||||
|
||||
if (!(__raw_readl(base) & (1 << 11))) {
|
||||
__raw_writeb(c, base + 0x0028);
|
||||
t = 0x10000;
|
||||
timeout = 0x10000;
|
||||
break;
|
||||
}
|
||||
} while (t);
|
||||
} while (timeout);
|
||||
}
|
||||
|
||||
#define MSCS __REG(0xA0900184)
|
||||
|
@ -89,6 +88,7 @@ static void putc_ns921x(char c, void __iomem *base)
|
|||
|
||||
static void autodetect(void (**putc)(char, void __iomem *), void __iomem **base)
|
||||
{
|
||||
timeout = 0x10000;
|
||||
if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x00) {
|
||||
/* ns9360 or ns9750 */
|
||||
if (NS9360_UART_ENABLED(NS9360_UARTA)) {
|
||||
|
|
|
@ -220,10 +220,10 @@ static int board_keymap[] = {
|
|||
KEY(4, 4, KEY_LEFTCTRL),
|
||||
KEY(4, 5, KEY_RIGHTALT),
|
||||
KEY(4, 6, KEY_LEFTSHIFT),
|
||||
KEY(4, 8, KEY_10),
|
||||
KEY(4, 8, KEY_F10),
|
||||
|
||||
KEY(5, 0, KEY_Y),
|
||||
KEY(5, 8, KEY_11),
|
||||
KEY(5, 8, KEY_F11),
|
||||
|
||||
KEY(6, 0, KEY_U),
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <mach/colibri.h>
|
||||
#include <mach/ohci.h>
|
||||
#include <mach/pxafb.h>
|
||||
#include <mach/audio.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
@ -145,7 +146,7 @@ static void __init colibri_pxa300_init_lcd(void)
|
|||
static inline void colibri_pxa300_init_lcd(void) {}
|
||||
#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
|
||||
|
||||
#if defined(SND_AC97_CODEC) || defined(SND_AC97_CODEC_MODULE)
|
||||
#if defined(CONFIG_SND_AC97_CODEC) || defined(CONFIG_SND_AC97_CODEC_MODULE)
|
||||
static mfp_cfg_t colibri_pxa310_ac97_pin_config[] __initdata = {
|
||||
GPIO24_AC97_SYSCLK,
|
||||
GPIO23_AC97_nACRESET,
|
||||
|
|
|
@ -446,7 +446,7 @@ static struct platform_device corgiled_device = {
|
|||
static struct pxamci_platform_data corgi_mci_platform_data = {
|
||||
.detect_delay_ms = 250,
|
||||
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
|
||||
.gpio_card_detect = -1,
|
||||
.gpio_card_detect = CORGI_GPIO_nSD_DETECT,
|
||||
.gpio_card_ro = CORGI_GPIO_nSD_WP,
|
||||
.gpio_power = CORGI_GPIO_SD_PWR,
|
||||
};
|
||||
|
|
|
@ -256,13 +256,9 @@ static void init_sdram_rows(void)
|
|||
|
||||
static u32 mdrefr_dri(unsigned int freq)
|
||||
{
|
||||
u32 dri = 0;
|
||||
u32 interval = freq * SDRAM_TREF / sdram_rows;
|
||||
|
||||
if (cpu_is_pxa25x())
|
||||
dri = ((freq * SDRAM_TREF) / (sdram_rows * 32));
|
||||
if (cpu_is_pxa27x())
|
||||
dri = ((freq * SDRAM_TREF) / (sdram_rows - 31)) / 32;
|
||||
return dri;
|
||||
return (interval - (cpu_is_pxa27x() ? 31 : 0)) / 32;
|
||||
}
|
||||
|
||||
/* find a valid frequency point */
|
||||
|
|
|
@ -41,10 +41,10 @@ void pxa27x_clear_otgph(void)
|
|||
EXPORT_SYMBOL(pxa27x_clear_otgph);
|
||||
|
||||
static unsigned long ac97_reset_config[] = {
|
||||
GPIO95_AC97_nRESET,
|
||||
GPIO95_GPIO,
|
||||
GPIO113_AC97_nRESET,
|
||||
GPIO113_GPIO,
|
||||
GPIO113_AC97_nRESET,
|
||||
GPIO95_GPIO,
|
||||
GPIO95_AC97_nRESET,
|
||||
};
|
||||
|
||||
void pxa27x_assert_ac97reset(int reset_gpio, int on)
|
||||
|
|
|
@ -237,7 +237,7 @@ static unsigned int realview_mmc_status(struct device *dev)
|
|||
else
|
||||
mask = 2;
|
||||
|
||||
return !(readl(REALVIEW_SYSMCI) & mask);
|
||||
return readl(REALVIEW_SYSMCI) & mask;
|
||||
}
|
||||
|
||||
struct mmci_platform_data realview_mmc0_plat_data = {
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
strb \rd, [\rx]
|
||||
.endm
|
||||
|
||||
.macro waituart,rd,rx
|
||||
.endm
|
||||
|
||||
.macro busyuart,rd,rx
|
||||
mov \rd, #0
|
||||
1001: add \rd, \rd, #1
|
||||
|
|
|
@ -30,22 +30,22 @@
|
|||
static void putc(const char c)
|
||||
{
|
||||
/* Do nothing if the UART is not enabled. */
|
||||
if (!(readb(U8500_UART_CR) & 0x1))
|
||||
if (!(__raw_readb(U8500_UART_CR) & 0x1))
|
||||
return;
|
||||
|
||||
if (c == '\n')
|
||||
putc('\r');
|
||||
|
||||
while (readb(U8500_UART_FR) & (1 << 5))
|
||||
while (__raw_readb(U8500_UART_FR) & (1 << 5))
|
||||
barrier();
|
||||
writeb(c, U8500_UART_DR);
|
||||
__raw_writeb(c, U8500_UART_DR);
|
||||
}
|
||||
|
||||
static void flush(void)
|
||||
{
|
||||
if (!(readb(U8500_UART_CR) & 0x1))
|
||||
if (!(__raw_readb(U8500_UART_CR) & 0x1))
|
||||
return;
|
||||
while (readb(U8500_UART_FR) & (1 << 3))
|
||||
while (__raw_readb(U8500_UART_FR) & (1 << 3))
|
||||
barrier();
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ static struct platform_device v2m_flash_device = {
|
|||
|
||||
static unsigned int v2m_mmci_status(struct device *dev)
|
||||
{
|
||||
return !(readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0));
|
||||
return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0);
|
||||
}
|
||||
|
||||
static struct mmci_platform_data v2m_mmci_data = {
|
||||
|
|
|
@ -93,7 +93,7 @@ static struct clk_lookup nuc900_clkregs[] = {
|
|||
DEF_CLKLOOK(&clk_kpi, "nuc900-kpi", NULL),
|
||||
DEF_CLKLOOK(&clk_wdt, "nuc900-wdt", NULL),
|
||||
DEF_CLKLOOK(&clk_gdma, "nuc900-gdma", NULL),
|
||||
DEF_CLKLOOK(&clk_adc, "nuc900-adc", NULL),
|
||||
DEF_CLKLOOK(&clk_adc, "nuc900-ts", NULL),
|
||||
DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
|
||||
DEF_CLKLOOK(&clk_ext, NULL, "ext"),
|
||||
DEF_CLKLOOK(&clk_timer0, NULL, "timer0"),
|
||||
|
|
|
@ -32,14 +32,14 @@ static uint32_t l2x0_way_mask; /* Bitmask of active ways */
|
|||
static inline void cache_wait(void __iomem *reg, unsigned long mask)
|
||||
{
|
||||
/* wait for the operation to complete */
|
||||
while (readl(reg) & mask)
|
||||
while (readl_relaxed(reg) & mask)
|
||||
;
|
||||
}
|
||||
|
||||
static inline void cache_sync(void)
|
||||
{
|
||||
void __iomem *base = l2x0_base;
|
||||
writel(0, base + L2X0_CACHE_SYNC);
|
||||
writel_relaxed(0, base + L2X0_CACHE_SYNC);
|
||||
cache_wait(base + L2X0_CACHE_SYNC, 1);
|
||||
}
|
||||
|
||||
|
@ -47,14 +47,14 @@ static inline void l2x0_clean_line(unsigned long addr)
|
|||
{
|
||||
void __iomem *base = l2x0_base;
|
||||
cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
|
||||
writel(addr, base + L2X0_CLEAN_LINE_PA);
|
||||
writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
|
||||
}
|
||||
|
||||
static inline void l2x0_inv_line(unsigned long addr)
|
||||
{
|
||||
void __iomem *base = l2x0_base;
|
||||
cache_wait(base + L2X0_INV_LINE_PA, 1);
|
||||
writel(addr, base + L2X0_INV_LINE_PA);
|
||||
writel_relaxed(addr, base + L2X0_INV_LINE_PA);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PL310_ERRATA_588369
|
||||
|
@ -75,9 +75,9 @@ static inline void l2x0_flush_line(unsigned long addr)
|
|||
|
||||
/* Clean by PA followed by Invalidate by PA */
|
||||
cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
|
||||
writel(addr, base + L2X0_CLEAN_LINE_PA);
|
||||
writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
|
||||
cache_wait(base + L2X0_INV_LINE_PA, 1);
|
||||
writel(addr, base + L2X0_INV_LINE_PA);
|
||||
writel_relaxed(addr, base + L2X0_INV_LINE_PA);
|
||||
}
|
||||
#else
|
||||
|
||||
|
@ -90,7 +90,7 @@ static inline void l2x0_flush_line(unsigned long addr)
|
|||
{
|
||||
void __iomem *base = l2x0_base;
|
||||
cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
|
||||
writel(addr, base + L2X0_CLEAN_INV_LINE_PA);
|
||||
writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -109,7 +109,7 @@ static inline void l2x0_inv_all(void)
|
|||
|
||||
/* invalidate all ways */
|
||||
spin_lock_irqsave(&l2x0_lock, flags);
|
||||
writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
|
||||
writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
|
||||
cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
|
||||
cache_sync();
|
||||
spin_unlock_irqrestore(&l2x0_lock, flags);
|
||||
|
@ -215,8 +215,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
|
|||
|
||||
l2x0_base = base;
|
||||
|
||||
cache_id = readl(l2x0_base + L2X0_CACHE_ID);
|
||||
aux = readl(l2x0_base + L2X0_AUX_CTRL);
|
||||
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
|
||||
aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
|
||||
|
||||
aux &= aux_mask;
|
||||
aux |= aux_val;
|
||||
|
@ -248,15 +248,15 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
|
|||
* If you are booting from non-secure mode
|
||||
* accessing the below registers will fault.
|
||||
*/
|
||||
if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
|
||||
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
|
||||
|
||||
/* l2x0 controller is disabled */
|
||||
writel(aux, l2x0_base + L2X0_AUX_CTRL);
|
||||
writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
|
||||
|
||||
l2x0_inv_all();
|
||||
|
||||
/* enable L2X0 */
|
||||
writel(1, l2x0_base + L2X0_CTRL);
|
||||
writel_relaxed(1, l2x0_base + L2X0_CTRL);
|
||||
}
|
||||
|
||||
outer_cache.inv_range = l2x0_inv_range;
|
||||
|
|
|
@ -163,19 +163,22 @@ static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
|
|||
|
||||
void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
|
||||
{
|
||||
unsigned int idx, cpu = smp_processor_id();
|
||||
int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
|
||||
unsigned int idx, cpu;
|
||||
int *depth;
|
||||
unsigned long vaddr, flags;
|
||||
pte_t pte, *ptep;
|
||||
|
||||
if (!in_interrupt())
|
||||
preempt_disable();
|
||||
|
||||
cpu = smp_processor_id();
|
||||
depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
|
||||
|
||||
idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
|
||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
ptep = TOP_PTE(vaddr);
|
||||
pte = mk_pte(page, kmap_prot);
|
||||
|
||||
if (!in_interrupt())
|
||||
preempt_disable();
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
(*depth)++;
|
||||
if (pte_val(*ptep) == pte_val(pte)) {
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
.macro addruart, rx
|
||||
mrc p15, 0, \rx, c1, c0
|
||||
tst \rx, #1 @ MMU enabled?
|
||||
moveq \rx, =SPEAR_DBG_UART_BASE @ Physical base
|
||||
movne \rx, =VA_SPEAR_DBG_UART_BASE @ Virtual base
|
||||
moveq \rx, #SPEAR_DBG_UART_BASE @ Physical base
|
||||
movne \rx, #VA_SPEAR_DBG_UART_BASE @ Virtual base
|
||||
.endm
|
||||
|
||||
.macro senduart, rd, rx
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
|
||||
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
|
||||
|
||||
#define TIOCGRS485 0x542E
|
||||
#define TIOCSRS485 0x542F
|
||||
|
||||
#define FIONCLEX 0x5450
|
||||
#define FIOCLEX 0x5451
|
||||
#define FIOASYNC 0x5452
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#define __ASM_ARCH_BOARD_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#define GPIO_PIN_NONE (-1)
|
||||
|
||||
|
@ -35,6 +36,7 @@ struct atmel_uart_data {
|
|||
short use_dma_tx; /* use transmit DMA? */
|
||||
short use_dma_rx; /* use receive DMA? */
|
||||
void __iomem *regs; /* virtual base address, if any */
|
||||
struct serial_rs485 rs485; /* rs485 settings */
|
||||
};
|
||||
void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
|
||||
struct platform_device *at32_add_device_usart(unsigned int id);
|
||||
|
|
|
@ -435,20 +435,21 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
|
|||
static int __init au1xxx_platform_init(void)
|
||||
{
|
||||
unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
|
||||
int i;
|
||||
int err, i;
|
||||
|
||||
/* Fill up uartclk. */
|
||||
for (i = 0; au1x00_uart_data[i].flags; i++)
|
||||
au1x00_uart_data[i].uartclk = uartclk;
|
||||
|
||||
err = platform_add_devices(au1xxx_platform_devices,
|
||||
ARRAY_SIZE(au1xxx_platform_devices));
|
||||
#ifndef CONFIG_SOC_AU1100
|
||||
/* Register second MAC if enabled in pinfunc */
|
||||
if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
|
||||
if (!err && !(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
|
||||
platform_device_register(&au1xxx_eth1_device);
|
||||
#endif
|
||||
|
||||
return platform_add_devices(au1xxx_platform_devices,
|
||||
ARRAY_SIZE(au1xxx_platform_devices));
|
||||
return err;
|
||||
}
|
||||
|
||||
arch_initcall(au1xxx_platform_init);
|
||||
|
|
|
@ -67,8 +67,6 @@ static void mtx1_power_off(void)
|
|||
|
||||
void __init board_setup(void)
|
||||
{
|
||||
alchemy_gpio2_enable();
|
||||
|
||||
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
|
||||
/* Enable USB power switch */
|
||||
alchemy_gpio_direction_output(204, 0);
|
||||
|
@ -117,11 +115,11 @@ mtx1_pci_idsel(unsigned int devsel, int assert)
|
|||
|
||||
if (assert && devsel != 0)
|
||||
/* Suppress signal to Cardbus */
|
||||
gpio_set_value(1, 0); /* set EXT_IO3 OFF */
|
||||
alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */
|
||||
else
|
||||
gpio_set_value(1, 1); /* set EXT_IO3 ON */
|
||||
alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */
|
||||
|
||||
au_sync_udelay(1);
|
||||
udelay(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,9 @@ int __init bcm63xx_enet_register(int unit,
|
|||
if (unit > 1)
|
||||
return -ENODEV;
|
||||
|
||||
if (unit == 1 && BCMCPU_IS_6338())
|
||||
return -ENODEV;
|
||||
|
||||
if (!shared_device_registered) {
|
||||
shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
|
||||
shared_res[0].end = shared_res[0].start;
|
||||
|
|
|
@ -434,7 +434,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %1 # atomic64_add \n"
|
||||
" addu %0, %2 \n"
|
||||
" daddu %0, %2 \n"
|
||||
" scd %0, %1 \n"
|
||||
" beqzl %0, 1b \n"
|
||||
" .set mips0 \n"
|
||||
|
@ -446,7 +446,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %1 # atomic64_add \n"
|
||||
" addu %0, %2 \n"
|
||||
" daddu %0, %2 \n"
|
||||
" scd %0, %1 \n"
|
||||
" beqz %0, 2f \n"
|
||||
" .subsection 2 \n"
|
||||
|
@ -479,7 +479,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %1 # atomic64_sub \n"
|
||||
" subu %0, %2 \n"
|
||||
" dsubu %0, %2 \n"
|
||||
" scd %0, %1 \n"
|
||||
" beqzl %0, 1b \n"
|
||||
" .set mips0 \n"
|
||||
|
@ -491,7 +491,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %1 # atomic64_sub \n"
|
||||
" subu %0, %2 \n"
|
||||
" dsubu %0, %2 \n"
|
||||
" scd %0, %1 \n"
|
||||
" beqz %0, 2f \n"
|
||||
" .subsection 2 \n"
|
||||
|
@ -524,10 +524,10 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %1, %2 # atomic64_add_return \n"
|
||||
" addu %0, %1, %3 \n"
|
||||
" daddu %0, %1, %3 \n"
|
||||
" scd %0, %2 \n"
|
||||
" beqzl %0, 1b \n"
|
||||
" addu %0, %1, %3 \n"
|
||||
" daddu %0, %1, %3 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||
: "Ir" (i), "m" (v->counter)
|
||||
|
@ -538,10 +538,10 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %1, %2 # atomic64_add_return \n"
|
||||
" addu %0, %1, %3 \n"
|
||||
" daddu %0, %1, %3 \n"
|
||||
" scd %0, %2 \n"
|
||||
" beqz %0, 2f \n"
|
||||
" addu %0, %1, %3 \n"
|
||||
" daddu %0, %1, %3 \n"
|
||||
" .subsection 2 \n"
|
||||
"2: b 1b \n"
|
||||
" .previous \n"
|
||||
|
@ -576,10 +576,10 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %1, %2 # atomic64_sub_return \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
" dsubu %0, %1, %3 \n"
|
||||
" scd %0, %2 \n"
|
||||
" beqzl %0, 1b \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
" dsubu %0, %1, %3 \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
|
||||
: "Ir" (i), "m" (v->counter)
|
||||
|
@ -590,10 +590,10 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set mips3 \n"
|
||||
"1: lld %1, %2 # atomic64_sub_return \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
" dsubu %0, %1, %3 \n"
|
||||
" scd %0, %2 \n"
|
||||
" beqz %0, 2f \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
" dsubu %0, %1, %3 \n"
|
||||
" .subsection 2 \n"
|
||||
"2: b 1b \n"
|
||||
" .previous \n"
|
||||
|
|
|
@ -984,16 +984,17 @@
|
|||
#define __NR_perf_event_open (__NR_Linux + 296)
|
||||
#define __NR_accept4 (__NR_Linux + 297)
|
||||
#define __NR_recvmmsg (__NR_Linux + 298)
|
||||
#define __NR_getdents64 (__NR_Linux + 299)
|
||||
|
||||
/*
|
||||
* Offset of the last N32 flavoured syscall
|
||||
*/
|
||||
#define __NR_Linux_syscalls 298
|
||||
#define __NR_Linux_syscalls 299
|
||||
|
||||
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
|
||||
|
||||
#define __NR_N32_Linux 6000
|
||||
#define __NR_N32_Linux_syscalls 298
|
||||
#define __NR_N32_Linux_syscalls 299
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
|
|
@ -419,4 +419,5 @@ EXPORT(sysn32_call_table)
|
|||
PTR sys_perf_event_open
|
||||
PTR sys_accept4
|
||||
PTR compat_sys_recvmmsg
|
||||
PTR sys_getdents
|
||||
.size sysn32_call_table,.-sysn32_call_table
|
||||
|
|
|
@ -61,11 +61,9 @@ static int __init init_vdso(void)
|
|||
|
||||
vunmap(vdso);
|
||||
|
||||
pr_notice("init_vdso successfull\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(init_vdso);
|
||||
subsys_initcall(init_vdso);
|
||||
|
||||
static unsigned long vdso_addr(unsigned long start)
|
||||
{
|
||||
|
|
|
@ -247,6 +247,8 @@ void __init mips_pcibios_init(void)
|
|||
iomem_resource.end &= 0xfffffffffULL; /* 64 GB */
|
||||
ioport_resource.end = controller->io_resource->end;
|
||||
|
||||
controller->io_map_base = mips_io_port_base;
|
||||
|
||||
register_pci_controller(controller);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ extern struct pci_ops pnx8550_pci_ops;
|
|||
|
||||
static struct pci_controller pnx8550_controller = {
|
||||
.pci_ops = &pnx8550_pci_ops,
|
||||
.io_map_base = PNX8550_PORT_BASE,
|
||||
.io_resource = &pci_io_resource,
|
||||
.mem_resource = &pci_mem_resource,
|
||||
};
|
||||
|
|
|
@ -113,7 +113,7 @@ void __init plat_mem_setup(void)
|
|||
PNX8550_GLB2_ENAB_INTA_O = 0;
|
||||
|
||||
/* IO/MEM resources. */
|
||||
set_io_port_base(KSEG1);
|
||||
set_io_port_base(PNX8550_PORT_BASE);
|
||||
ioport_resource.start = 0;
|
||||
ioport_resource.end = ~0;
|
||||
iomem_resource.start = 0;
|
||||
|
|
|
@ -944,6 +944,7 @@ static struct pci_controller msp_pci_controller = {
|
|||
.pci_ops = &msp_pci_ops,
|
||||
.mem_resource = &pci_mem_resource,
|
||||
.mem_offset = 0,
|
||||
.io_map_base = MSP_PCI_IOSPACE_BASE,
|
||||
.io_resource = &pci_io_resource,
|
||||
.io_offset = 0
|
||||
};
|
||||
|
|
|
@ -54,6 +54,7 @@ static int __init pmc_yosemite_setup(void)
|
|||
panic(ioremap_failed);
|
||||
|
||||
set_io_port_base(io_v_base);
|
||||
py_controller.io_map_base = io_v_base;
|
||||
TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
|
||||
|
||||
ioport_resource.end = TITAN_IO_SIZE - 1;
|
||||
|
|
|
@ -472,6 +472,9 @@ void __init configure_platform(void)
|
|||
* it*/
|
||||
platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
|
||||
|
||||
/* Cronus and Cronus Lite have the same register map */
|
||||
set_register_map(CRONUS_IO_BASE, &cronus_register_map);
|
||||
|
||||
/* ASIC version will determine if this is a real CronusLite or
|
||||
* Castrati(Cronus) */
|
||||
chipversion = asic_read(chipver3) << 24;
|
||||
|
@ -484,8 +487,6 @@ void __init configure_platform(void)
|
|||
else
|
||||
asic = ASIC_CRONUSLITE;
|
||||
|
||||
/* Cronus and Cronus Lite have the same register map */
|
||||
set_register_map(CRONUS_IO_BASE, &cronus_register_map);
|
||||
gp_resources = non_dvr_cronuslite_resources;
|
||||
pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, "
|
||||
"chipversion=0x%08X\n",
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
* On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory
|
||||
* and therefore we can only deal with memory within this range
|
||||
*/
|
||||
#define KEXEC_SOURCE_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
|
||||
#define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
|
||||
#define KEXEC_CONTROL_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
|
||||
#define KEXEC_SOURCE_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL - 1)
|
||||
#define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL - 1)
|
||||
#define KEXEC_CONTROL_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL - 1)
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -250,7 +250,9 @@ extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
|
|||
int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
||||
pte_t *ptep, unsigned long trap, int local, int ssize,
|
||||
unsigned int shift, unsigned int mmu_psize);
|
||||
|
||||
extern void hash_failure_debug(unsigned long ea, unsigned long access,
|
||||
unsigned long vsid, unsigned long trap,
|
||||
int ssize, int psize, unsigned long pte);
|
||||
extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
|
||||
unsigned long pstart, unsigned long prot,
|
||||
int psize, int ssize);
|
||||
|
|
|
@ -566,9 +566,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
|
|||
* Finally record data if requested.
|
||||
*/
|
||||
if (record) {
|
||||
struct perf_sample_data data = {
|
||||
.period = event->hw.last_period,
|
||||
};
|
||||
struct perf_sample_data data;
|
||||
|
||||
perf_sample_data_init(&data, 0);
|
||||
|
||||
if (perf_event_overflow(event, nmi, &data, regs)) {
|
||||
/*
|
||||
|
|
|
@ -414,7 +414,7 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node)
|
|||
u64 base, size, memblock_size;
|
||||
unsigned int is_kexec_kdump = 0, rngs;
|
||||
|
||||
ls = of_get_flat_dt_prop(node, "ibm,memblock-size", &l);
|
||||
ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
|
||||
if (ls == NULL || l < dt_root_size_cells * sizeof(__be32))
|
||||
return 0;
|
||||
memblock_size = dt_mem_next_cell(dt_root_size_cells, &ls);
|
||||
|
|
|
@ -68,9 +68,6 @@ _GLOBAL(__hash_page_4K)
|
|||
std r8,STK_PARM(r8)(r1)
|
||||
std r9,STK_PARM(r9)(r1)
|
||||
|
||||
/* Add _PAGE_PRESENT to access */
|
||||
ori r4,r4,_PAGE_PRESENT
|
||||
|
||||
/* Save non-volatile registers.
|
||||
* r31 will hold "old PTE"
|
||||
* r30 is "new PTE"
|
||||
|
@ -347,9 +344,6 @@ _GLOBAL(__hash_page_4K)
|
|||
std r8,STK_PARM(r8)(r1)
|
||||
std r9,STK_PARM(r9)(r1)
|
||||
|
||||
/* Add _PAGE_PRESENT to access */
|
||||
ori r4,r4,_PAGE_PRESENT
|
||||
|
||||
/* Save non-volatile registers.
|
||||
* r31 will hold "old PTE"
|
||||
* r30 is "new PTE"
|
||||
|
@ -687,9 +681,6 @@ _GLOBAL(__hash_page_64K)
|
|||
std r8,STK_PARM(r8)(r1)
|
||||
std r9,STK_PARM(r9)(r1)
|
||||
|
||||
/* Add _PAGE_PRESENT to access */
|
||||
ori r4,r4,_PAGE_PRESENT
|
||||
|
||||
/* Save non-volatile registers.
|
||||
* r31 will hold "old PTE"
|
||||
* r30 is "new PTE"
|
||||
|
|
|
@ -871,6 +871,18 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
|
|||
}
|
||||
#endif
|
||||
|
||||
void hash_failure_debug(unsigned long ea, unsigned long access,
|
||||
unsigned long vsid, unsigned long trap,
|
||||
int ssize, int psize, unsigned long pte)
|
||||
{
|
||||
if (!printk_ratelimit())
|
||||
return;
|
||||
pr_info("mm: Hashing failure ! EA=0x%lx access=0x%lx current=%s\n",
|
||||
ea, access, current->comm);
|
||||
pr_info(" trap=0x%lx vsid=0x%lx ssize=%d psize=%d pte=0x%lx\n",
|
||||
trap, vsid, ssize, psize, pte);
|
||||
}
|
||||
|
||||
/* Result code is:
|
||||
* 0 - handled
|
||||
* 1 - normal page fault
|
||||
|
@ -955,6 +967,17 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Add _PAGE_PRESENT to the required access perm */
|
||||
access |= _PAGE_PRESENT;
|
||||
|
||||
/* Pre-check access permissions (will be re-checked atomically
|
||||
* in __hash_page_XX but this pre-check is a fast path
|
||||
*/
|
||||
if (access & ~pte_val(*ptep)) {
|
||||
DBG_LOW(" no access !\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
if (hugeshift)
|
||||
return __hash_page_huge(ea, access, vsid, ptep, trap, local,
|
||||
|
@ -967,14 +990,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
|
|||
DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep),
|
||||
pte_val(*(ptep + PTRS_PER_PTE)));
|
||||
#endif
|
||||
/* Pre-check access permissions (will be re-checked atomically
|
||||
* in __hash_page_XX but this pre-check is a fast path
|
||||
*/
|
||||
if (access & ~pte_val(*ptep)) {
|
||||
DBG_LOW(" no access !\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Do actual hashing */
|
||||
#ifdef CONFIG_PPC_64K_PAGES
|
||||
/* If _PAGE_4K_PFN is set, make sure this is a 4k segment */
|
||||
|
@ -1033,6 +1048,12 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
|
|||
local, ssize, spp);
|
||||
}
|
||||
|
||||
/* Dump some info in case of hash insertion failure, they should
|
||||
* never happen so it is really useful to know if/when they do
|
||||
*/
|
||||
if (rc == -1)
|
||||
hash_failure_debug(ea, access, vsid, trap, ssize, psize,
|
||||
pte_val(*ptep));
|
||||
#ifndef CONFIG_PPC_64K_PAGES
|
||||
DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep));
|
||||
#else
|
||||
|
@ -1051,8 +1072,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
|
|||
void *pgdir;
|
||||
pte_t *ptep;
|
||||
unsigned long flags;
|
||||
int local = 0;
|
||||
int ssize;
|
||||
int rc, ssize, local = 0;
|
||||
|
||||
BUG_ON(REGION_ID(ea) != USER_REGION_ID);
|
||||
|
||||
|
@ -1098,11 +1118,18 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
|
|||
/* Hash it in */
|
||||
#ifdef CONFIG_PPC_HAS_HASH_64K
|
||||
if (mm->context.user_psize == MMU_PAGE_64K)
|
||||
__hash_page_64K(ea, access, vsid, ptep, trap, local, ssize);
|
||||
rc = __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize);
|
||||
else
|
||||
#endif /* CONFIG_PPC_HAS_HASH_64K */
|
||||
__hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
|
||||
subpage_protection(pgdir, ea));
|
||||
rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
|
||||
subpage_protection(pgdir, ea));
|
||||
|
||||
/* Dump some info in case of hash insertion failure, they should
|
||||
* never happen so it is really useful to know if/when they do
|
||||
*/
|
||||
if (rc == -1)
|
||||
hash_failure_debug(ea, access, vsid, trap, ssize,
|
||||
mm->context.user_psize, pte_val(*ptep));
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
|
|
@ -21,21 +21,13 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
|||
unsigned long old_pte, new_pte;
|
||||
unsigned long va, rflags, pa, sz;
|
||||
long slot;
|
||||
int err = 1;
|
||||
|
||||
BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
|
||||
|
||||
/* Search the Linux page table for a match with va */
|
||||
va = hpt_va(ea, vsid, ssize);
|
||||
|
||||
/*
|
||||
* Check the user's access rights to the page. If access should be
|
||||
* prevented then send the problem up to do_page_fault.
|
||||
*/
|
||||
if (unlikely(access & ~pte_val(*ptep)))
|
||||
goto out;
|
||||
/*
|
||||
* At this point, we have a pte (old_pte) which can be used to build
|
||||
/* At this point, we have a pte (old_pte) which can be used to build
|
||||
* or update an HPTE. There are 2 cases:
|
||||
*
|
||||
* 1. There is a valid (present) pte with no associated HPTE (this is
|
||||
|
@ -49,9 +41,17 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
|||
|
||||
do {
|
||||
old_pte = pte_val(*ptep);
|
||||
if (old_pte & _PAGE_BUSY)
|
||||
goto out;
|
||||
/* If PTE busy, retry the access */
|
||||
if (unlikely(old_pte & _PAGE_BUSY))
|
||||
return 0;
|
||||
/* If PTE permissions don't match, take page fault */
|
||||
if (unlikely(access & ~old_pte))
|
||||
return 1;
|
||||
/* Try to lock the PTE, add ACCESSED and DIRTY if it was
|
||||
* a write access */
|
||||
new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
|
||||
if (access & _PAGE_RW)
|
||||
new_pte |= _PAGE_DIRTY;
|
||||
} while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
|
||||
old_pte, new_pte));
|
||||
|
||||
|
@ -121,8 +121,16 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
|||
}
|
||||
}
|
||||
|
||||
if (unlikely(slot == -2))
|
||||
panic("hash_huge_page: pte_insert failed\n");
|
||||
/*
|
||||
* Hypervisor failure. Restore old pte and return -1
|
||||
* similar to __hash_page_*
|
||||
*/
|
||||
if (unlikely(slot == -2)) {
|
||||
*ptep = __pte(old_pte);
|
||||
hash_failure_debug(ea, access, vsid, trap, ssize,
|
||||
mmu_psize, old_pte);
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX);
|
||||
}
|
||||
|
@ -131,9 +139,5 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
|||
* No need to use ldarx/stdcx here
|
||||
*/
|
||||
*ptep = __pte(new_pte & ~_PAGE_BUSY);
|
||||
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -398,15 +398,15 @@ static int of_get_drconf_memory(struct device_node *memory, const u32 **dm)
|
|||
}
|
||||
|
||||
/*
|
||||
* Retreive and validate the ibm,memblock-size property for drconf memory
|
||||
* Retreive and validate the ibm,lmb-size property for drconf memory
|
||||
* from the device tree.
|
||||
*/
|
||||
static u64 of_get_memblock_size(struct device_node *memory)
|
||||
static u64 of_get_lmb_size(struct device_node *memory)
|
||||
{
|
||||
const u32 *prop;
|
||||
u32 len;
|
||||
|
||||
prop = of_get_property(memory, "ibm,memblock-size", &len);
|
||||
prop = of_get_property(memory, "ibm,lmb-size", &len);
|
||||
if (!prop || len < sizeof(unsigned int))
|
||||
return 0;
|
||||
|
||||
|
@ -562,7 +562,7 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start,
|
|||
static inline int __init read_usm_ranges(const u32 **usm)
|
||||
{
|
||||
/*
|
||||
* For each memblock in ibm,dynamic-memory a corresponding
|
||||
* For each lmb in ibm,dynamic-memory a corresponding
|
||||
* entry in linux,drconf-usable-memory property contains
|
||||
* a counter followed by that many (base, size) duple.
|
||||
* read the counter from linux,drconf-usable-memory
|
||||
|
@ -578,7 +578,7 @@ static void __init parse_drconf_memory(struct device_node *memory)
|
|||
{
|
||||
const u32 *dm, *usm;
|
||||
unsigned int n, rc, ranges, is_kexec_kdump = 0;
|
||||
unsigned long memblock_size, base, size, sz;
|
||||
unsigned long lmb_size, base, size, sz;
|
||||
int nid;
|
||||
struct assoc_arrays aa;
|
||||
|
||||
|
@ -586,8 +586,8 @@ static void __init parse_drconf_memory(struct device_node *memory)
|
|||
if (!n)
|
||||
return;
|
||||
|
||||
memblock_size = of_get_memblock_size(memory);
|
||||
if (!memblock_size)
|
||||
lmb_size = of_get_lmb_size(memory);
|
||||
if (!lmb_size)
|
||||
return;
|
||||
|
||||
rc = of_get_assoc_arrays(memory, &aa);
|
||||
|
@ -611,7 +611,7 @@ static void __init parse_drconf_memory(struct device_node *memory)
|
|||
continue;
|
||||
|
||||
base = drmem.base_addr;
|
||||
size = memblock_size;
|
||||
size = lmb_size;
|
||||
ranges = 1;
|
||||
|
||||
if (is_kexec_kdump) {
|
||||
|
@ -1072,7 +1072,7 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
|
|||
{
|
||||
const u32 *dm;
|
||||
unsigned int drconf_cell_cnt, rc;
|
||||
unsigned long memblock_size;
|
||||
unsigned long lmb_size;
|
||||
struct assoc_arrays aa;
|
||||
int nid = -1;
|
||||
|
||||
|
@ -1080,8 +1080,8 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
|
|||
if (!drconf_cell_cnt)
|
||||
return -1;
|
||||
|
||||
memblock_size = of_get_memblock_size(memory);
|
||||
if (!memblock_size)
|
||||
lmb_size = of_get_lmb_size(memory);
|
||||
if (!lmb_size)
|
||||
return -1;
|
||||
|
||||
rc = of_get_assoc_arrays(memory, &aa);
|
||||
|
@ -1100,7 +1100,7 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
|
|||
continue;
|
||||
|
||||
if ((scn_addr < drmem.base_addr)
|
||||
|| (scn_addr >= (drmem.base_addr + memblock_size)))
|
||||
|| (scn_addr >= (drmem.base_addr + lmb_size)))
|
||||
continue;
|
||||
|
||||
nid = of_drconf_to_nid_single(&drmem, &aa);
|
||||
|
|
|
@ -69,7 +69,7 @@ static int pseries_remove_memory(struct device_node *np)
|
|||
const char *type;
|
||||
const unsigned int *regs;
|
||||
unsigned long base;
|
||||
unsigned int memblock_size;
|
||||
unsigned int lmb_size;
|
||||
int ret = -EINVAL;
|
||||
|
||||
/*
|
||||
|
@ -87,9 +87,9 @@ static int pseries_remove_memory(struct device_node *np)
|
|||
return ret;
|
||||
|
||||
base = *(unsigned long *)regs;
|
||||
memblock_size = regs[3];
|
||||
lmb_size = regs[3];
|
||||
|
||||
ret = pseries_remove_memblock(base, memblock_size);
|
||||
ret = pseries_remove_memblock(base, lmb_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ static int pseries_add_memory(struct device_node *np)
|
|||
const char *type;
|
||||
const unsigned int *regs;
|
||||
unsigned long base;
|
||||
unsigned int memblock_size;
|
||||
unsigned int lmb_size;
|
||||
int ret = -EINVAL;
|
||||
|
||||
/*
|
||||
|
@ -116,36 +116,36 @@ static int pseries_add_memory(struct device_node *np)
|
|||
return ret;
|
||||
|
||||
base = *(unsigned long *)regs;
|
||||
memblock_size = regs[3];
|
||||
lmb_size = regs[3];
|
||||
|
||||
/*
|
||||
* Update memory region to represent the memory add
|
||||
*/
|
||||
ret = memblock_add(base, memblock_size);
|
||||
ret = memblock_add(base, lmb_size);
|
||||
return (ret < 0) ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static int pseries_drconf_memory(unsigned long *base, unsigned int action)
|
||||
{
|
||||
struct device_node *np;
|
||||
const unsigned long *memblock_size;
|
||||
const unsigned long *lmb_size;
|
||||
int rc;
|
||||
|
||||
np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
|
||||
if (!np)
|
||||
return -EINVAL;
|
||||
|
||||
memblock_size = of_get_property(np, "ibm,memblock-size", NULL);
|
||||
if (!memblock_size) {
|
||||
lmb_size = of_get_property(np, "ibm,lmb-size", NULL);
|
||||
if (!lmb_size) {
|
||||
of_node_put(np);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (action == PSERIES_DRCONF_MEM_ADD) {
|
||||
rc = memblock_add(*base, *memblock_size);
|
||||
rc = memblock_add(*base, *lmb_size);
|
||||
rc = (rc < 0) ? -EINVAL : 0;
|
||||
} else if (action == PSERIES_DRCONF_MEM_REMOVE) {
|
||||
rc = pseries_remove_memblock(*base, *memblock_size);
|
||||
rc = pseries_remove_memblock(*base, *lmb_size);
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
|
|
@ -535,8 +535,16 @@ pgm_no_vtime2:
|
|||
l %r3,__LC_PGM_ILC # load program interruption code
|
||||
la %r8,0x7f
|
||||
nr %r8,%r3 # clear per-event-bit and ilc
|
||||
be BASED(pgm_exit) # only per or per+check ?
|
||||
b BASED(pgm_do_call)
|
||||
be BASED(pgm_exit2) # only per or per+check ?
|
||||
l %r7,BASED(.Ljump_table)
|
||||
sll %r8,2
|
||||
l %r7,0(%r8,%r7) # load address of handler routine
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
basr %r14,%r7 # branch to interrupt-handler
|
||||
pgm_exit2:
|
||||
TRACE_IRQS_ON
|
||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||
b BASED(sysc_return)
|
||||
|
||||
#
|
||||
# it was a single stepped SVC that is causing all the trouble
|
||||
|
|
|
@ -544,8 +544,16 @@ pgm_no_vtime2:
|
|||
lgf %r3,__LC_PGM_ILC # load program interruption code
|
||||
lghi %r8,0x7f
|
||||
ngr %r8,%r3 # clear per-event-bit and ilc
|
||||
je pgm_exit
|
||||
j pgm_do_call
|
||||
je pgm_exit2
|
||||
sll %r8,3
|
||||
larl %r1,pgm_check_table
|
||||
lg %r1,0(%r8,%r1) # load address of handler routine
|
||||
la %r2,SP_PTREGS(%r15) # address of register-save area
|
||||
basr %r14,%r1 # branch to interrupt-handler
|
||||
pgm_exit2:
|
||||
TRACE_IRQS_ON
|
||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||
j sysc_return
|
||||
|
||||
#
|
||||
# it was a single stepped SVC that is causing all the trouble
|
||||
|
|
|
@ -524,8 +524,11 @@ void etr_switch_to_local(void)
|
|||
if (!etr_eacr.sl)
|
||||
return;
|
||||
disable_sync_clock(NULL);
|
||||
set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events);
|
||||
queue_work(time_sync_wq, &etr_work);
|
||||
if (!test_and_set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events)) {
|
||||
etr_eacr.es = etr_eacr.sl = 0;
|
||||
etr_setr(&etr_eacr);
|
||||
queue_work(time_sync_wq, &etr_work);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -539,8 +542,11 @@ void etr_sync_check(void)
|
|||
if (!etr_eacr.es)
|
||||
return;
|
||||
disable_sync_clock(NULL);
|
||||
set_bit(ETR_EVENT_SYNC_CHECK, &etr_events);
|
||||
queue_work(time_sync_wq, &etr_work);
|
||||
if (!test_and_set_bit(ETR_EVENT_SYNC_CHECK, &etr_events)) {
|
||||
etr_eacr.es = 0;
|
||||
etr_setr(&etr_eacr);
|
||||
queue_work(time_sync_wq, &etr_work);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -902,7 +908,7 @@ static struct etr_eacr etr_handle_update(struct etr_aib *aib,
|
|||
* Do not try to get the alternate port aib if the clock
|
||||
* is not in sync yet.
|
||||
*/
|
||||
if (!check_sync_clock())
|
||||
if (!eacr.es || !check_sync_clock())
|
||||
return eacr;
|
||||
|
||||
/*
|
||||
|
@ -1064,7 +1070,7 @@ static void etr_work_fn(struct work_struct *work)
|
|||
* If the clock is in sync just update the eacr and return.
|
||||
* If there is no valid sync port wait for a port update.
|
||||
*/
|
||||
if (check_sync_clock() || sync_port < 0) {
|
||||
if ((eacr.es && check_sync_clock()) || sync_port < 0) {
|
||||
etr_update_eacr(eacr);
|
||||
etr_set_tolec_timeout(now);
|
||||
goto out_unlock;
|
||||
|
|
|
@ -145,6 +145,15 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
|
|||
percpu_entry->states[cx->index].eax = cx->address;
|
||||
percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
|
||||
}
|
||||
|
||||
/*
|
||||
* For _CST FFH on Intel, if GAS.access_size bit 1 is cleared,
|
||||
* then we should skip checking BM_STS for this C-state.
|
||||
* ref: "Intel Processor Vendor-Specific ACPI Interface Specification"
|
||||
*/
|
||||
if ((c->x86_vendor == X86_VENDOR_INTEL) && !(reg->access_size & 0x2))
|
||||
cx->bm_sts_skip = 1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
|
||||
|
|
|
@ -157,9 +157,14 @@ static int __init acpi_sleep_setup(char *str)
|
|||
#ifdef CONFIG_HIBERNATION
|
||||
if (strncmp(str, "s4_nohwsig", 10) == 0)
|
||||
acpi_no_s4_hw_signature();
|
||||
if (strncmp(str, "s4_nonvs", 8) == 0)
|
||||
acpi_s4_no_nvs();
|
||||
if (strncmp(str, "s4_nonvs", 8) == 0) {
|
||||
pr_warning("ACPI: acpi_sleep=s4_nonvs is deprecated, "
|
||||
"please use acpi_sleep=nonvs instead");
|
||||
acpi_nvs_nosave();
|
||||
}
|
||||
#endif
|
||||
if (strncmp(str, "nonvs", 5) == 0)
|
||||
acpi_nvs_nosave();
|
||||
if (strncmp(str, "old_ordering", 12) == 0)
|
||||
acpi_old_suspend_ordering();
|
||||
str = strchr(str, ',');
|
||||
|
|
|
@ -368,22 +368,16 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
|
|||
return -ENODEV;
|
||||
|
||||
out_obj = output.pointer;
|
||||
if (out_obj->type != ACPI_TYPE_BUFFER) {
|
||||
ret = -ENODEV;
|
||||
goto out_free;
|
||||
}
|
||||
if (out_obj->type != ACPI_TYPE_BUFFER)
|
||||
return -ENODEV;
|
||||
|
||||
errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
|
||||
if (errors) {
|
||||
ret = -ENODEV;
|
||||
goto out_free;
|
||||
}
|
||||
if (errors)
|
||||
return -ENODEV;
|
||||
|
||||
supported = *((u32 *)(out_obj->buffer.pointer + 4));
|
||||
if (!(supported & 0x1)) {
|
||||
ret = -ENODEV;
|
||||
goto out_free;
|
||||
}
|
||||
if (!(supported & 0x1))
|
||||
return -ENODEV;
|
||||
|
||||
out_free:
|
||||
kfree(output.pointer);
|
||||
|
@ -397,13 +391,17 @@ static int __init pcc_cpufreq_probe(void)
|
|||
struct pcc_memory_resource *mem_resource;
|
||||
struct pcc_register_resource *reg_resource;
|
||||
union acpi_object *out_obj, *member;
|
||||
acpi_handle handle, osc_handle;
|
||||
acpi_handle handle, osc_handle, pcch_handle;
|
||||
int ret = 0;
|
||||
|
||||
status = acpi_get_handle(NULL, "\\_SB", &handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_get_handle(handle, "PCCH", &pcch_handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_get_handle(handle, "_OSC", &osc_handle);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
ret = pcc_cpufreq_do_osc(&osc_handle);
|
||||
|
@ -543,13 +541,13 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
|||
|
||||
if (!pcch_virt_addr) {
|
||||
result = -1;
|
||||
goto pcch_null;
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = pcc_get_offset(cpu);
|
||||
if (result) {
|
||||
dprintk("init: PCCP evaluation failed\n");
|
||||
goto free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
policy->max = policy->cpuinfo.max_freq =
|
||||
|
@ -558,14 +556,15 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
|||
ioread32(&pcch_hdr->minimum_frequency) * 1000;
|
||||
policy->cur = pcc_get_freq(cpu);
|
||||
|
||||
if (!policy->cur) {
|
||||
dprintk("init: Unable to get current CPU frequency\n");
|
||||
result = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dprintk("init: policy->max is %d, policy->min is %d\n",
|
||||
policy->max, policy->min);
|
||||
|
||||
return 0;
|
||||
free:
|
||||
pcc_clear_mapping();
|
||||
free_percpu(pcc_cpu_info);
|
||||
pcch_null:
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -1023,13 +1023,12 @@ static int get_transition_latency(struct powernow_k8_data *data)
|
|||
}
|
||||
if (max_latency == 0) {
|
||||
/*
|
||||
* Fam 11h always returns 0 as transition latency.
|
||||
* This is intended and means "very fast". While cpufreq core
|
||||
* and governors currently can handle that gracefully, better
|
||||
* set it to 1 to avoid problems in the future.
|
||||
* For all others it's a BIOS bug.
|
||||
* Fam 11h and later may return 0 as transition latency. This
|
||||
* is intended and means "very fast". While cpufreq core and
|
||||
* governors currently can handle that gracefully, better set it
|
||||
* to 1 to avoid problems in the future.
|
||||
*/
|
||||
if (boot_cpu_data.x86 != 0x11)
|
||||
if (boot_cpu_data.x86 < 0x11)
|
||||
printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
|
||||
"latency\n");
|
||||
max_latency = 1;
|
||||
|
|
|
@ -964,7 +964,7 @@ fs_initcall(hpet_late_init);
|
|||
|
||||
void hpet_disable(void)
|
||||
{
|
||||
if (is_hpet_capable()) {
|
||||
if (is_hpet_capable() && hpet_virt_address) {
|
||||
unsigned int cfg = hpet_readl(HPET_CFG);
|
||||
|
||||
if (hpet_legacy_int_enabled) {
|
||||
|
|
|
@ -276,16 +276,6 @@ static struct sys_device device_i8259A = {
|
|||
.cls = &i8259_sysdev_class,
|
||||
};
|
||||
|
||||
static int __init i8259A_init_sysfs(void)
|
||||
{
|
||||
int error = sysdev_class_register(&i8259_sysdev_class);
|
||||
if (!error)
|
||||
error = sysdev_register(&device_i8259A);
|
||||
return error;
|
||||
}
|
||||
|
||||
device_initcall(i8259A_init_sysfs);
|
||||
|
||||
static void mask_8259A(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -407,3 +397,18 @@ struct legacy_pic default_legacy_pic = {
|
|||
};
|
||||
|
||||
struct legacy_pic *legacy_pic = &default_legacy_pic;
|
||||
|
||||
static int __init i8259A_init_sysfs(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (legacy_pic != &default_legacy_pic)
|
||||
return 0;
|
||||
|
||||
error = sysdev_class_register(&i8259_sysdev_class);
|
||||
if (!error)
|
||||
error = sysdev_register(&device_i8259A);
|
||||
return error;
|
||||
}
|
||||
|
||||
device_initcall(i8259A_init_sysfs);
|
||||
|
|
|
@ -572,7 +572,6 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
|
|||
return NOTIFY_STOP;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
|
||||
int kgdb_ll_trap(int cmd, const char *str,
|
||||
struct pt_regs *regs, long err, int trap, int sig)
|
||||
{
|
||||
|
@ -590,7 +589,6 @@ int kgdb_ll_trap(int cmd, const char *str,
|
|||
|
||||
return __kgdb_notify(&args, cmd);
|
||||
}
|
||||
#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
|
||||
|
||||
static int
|
||||
kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
|
||||
|
@ -625,6 +623,12 @@ int kgdb_arch_init(void)
|
|||
return register_die_notifier(&kgdb_notifier);
|
||||
}
|
||||
|
||||
static void kgdb_hw_overflow_handler(struct perf_event *event, int nmi,
|
||||
struct perf_sample_data *data, struct pt_regs *regs)
|
||||
{
|
||||
kgdb_ll_trap(DIE_DEBUG, "debug", regs, 0, 0, SIGTRAP);
|
||||
}
|
||||
|
||||
void kgdb_arch_late(void)
|
||||
{
|
||||
int i, cpu;
|
||||
|
@ -655,6 +659,7 @@ void kgdb_arch_late(void)
|
|||
for_each_online_cpu(cpu) {
|
||||
pevent = per_cpu_ptr(breakinfo[i].pev, cpu);
|
||||
pevent[0]->hw.sample_period = 1;
|
||||
pevent[0]->overflow_handler = kgdb_hw_overflow_handler;
|
||||
if (pevent[0]->destroy != NULL) {
|
||||
pevent[0]->destroy = NULL;
|
||||
release_bp_slot(*pevent);
|
||||
|
|
|
@ -342,6 +342,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
|
|||
/* advance table_gfn when emulating 1gb pages with 4k */
|
||||
if (delta == 0)
|
||||
table_gfn += PT_INDEX(addr, level);
|
||||
access &= gw->pte_access;
|
||||
} else {
|
||||
direct = 0;
|
||||
table_gfn = gw->table_gfn[level - 2];
|
||||
|
|
|
@ -1562,7 +1562,7 @@ static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs,
|
|||
|
||||
r = -ENOMEM;
|
||||
size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
|
||||
entries = vmalloc(size);
|
||||
entries = kmalloc(size, GFP_KERNEL);
|
||||
if (!entries)
|
||||
goto out;
|
||||
|
||||
|
@ -1581,7 +1581,7 @@ static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs,
|
|||
r = n;
|
||||
|
||||
out_free:
|
||||
vfree(entries);
|
||||
kfree(entries);
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
|||
acpi_status acpi_enable(void)
|
||||
{
|
||||
acpi_status status;
|
||||
int retry;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enable);
|
||||
|
||||
|
@ -98,16 +99,18 @@ acpi_status acpi_enable(void)
|
|||
|
||||
/* Sanity check that transition succeeded */
|
||||
|
||||
if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Hardware did not enter ACPI mode"));
|
||||
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
|
||||
for (retry = 0; retry < 30000; ++retry) {
|
||||
if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
|
||||
if (retry != 0)
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Platform took > %d00 usec to enter ACPI mode", retry));
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
acpi_os_stall(100); /* 100 usec */
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
|
||||
"Transition to ACPI mode successful\n"));
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
|
||||
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enable)
|
||||
|
|
|
@ -868,9 +868,15 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
|
|||
static void acpi_battery_notify(struct acpi_device *device, u32 event)
|
||||
{
|
||||
struct acpi_battery *battery = acpi_driver_data(device);
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
struct device *old;
|
||||
#endif
|
||||
|
||||
if (!battery)
|
||||
return;
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
old = battery->bat.dev;
|
||||
#endif
|
||||
acpi_battery_update(battery);
|
||||
acpi_bus_generate_proc_event(device, event,
|
||||
acpi_battery_present(battery));
|
||||
|
@ -879,7 +885,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
|
|||
acpi_battery_present(battery));
|
||||
#ifdef CONFIG_ACPI_SYSFS_POWER
|
||||
/* acpi_battery_update could remove power_supply object */
|
||||
if (battery->bat.dev)
|
||||
if (old && battery->bat.dev)
|
||||
power_supply_changed(&battery->bat);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
|
|||
.ident = "Sony VGN-SR290J",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -223,7 +223,7 @@ static bool processor_physically_present(acpi_handle handle)
|
|||
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
|
||||
cpuid = acpi_get_cpuid(handle, type, acpi_id);
|
||||
|
||||
if (cpuid == -1)
|
||||
if ((cpuid == -1) && (num_possible_cpus() > 1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -76,14 +76,19 @@ static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
|
|||
module_param(max_cstate, uint, 0000);
|
||||
static unsigned int nocst __read_mostly;
|
||||
module_param(nocst, uint, 0000);
|
||||
static int bm_check_disable __read_mostly;
|
||||
module_param(bm_check_disable, uint, 0000);
|
||||
|
||||
static unsigned int latency_factor __read_mostly = 2;
|
||||
module_param(latency_factor, uint, 0644);
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
static u64 us_to_pm_timer_ticks(s64 t)
|
||||
{
|
||||
return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
|
||||
* For now disable this. Probably a bug somewhere else.
|
||||
|
@ -763,6 +768,9 @@ static int acpi_idle_bm_check(void)
|
|||
{
|
||||
u32 bm_status = 0;
|
||||
|
||||
if (bm_check_disable)
|
||||
return 0;
|
||||
|
||||
acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
|
||||
if (bm_status)
|
||||
acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
|
||||
|
@ -947,7 +955,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
|
|||
if (acpi_idle_suspend)
|
||||
return(acpi_idle_enter_c1(dev, state));
|
||||
|
||||
if (acpi_idle_bm_check()) {
|
||||
if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
|
||||
if (dev->safe_state) {
|
||||
dev->last_state = dev->safe_state;
|
||||
return dev->safe_state->enter(dev, dev->safe_state);
|
||||
|
|
|
@ -81,6 +81,20 @@ static int acpi_sleep_prepare(u32 acpi_state)
|
|||
#ifdef CONFIG_ACPI_SLEEP
|
||||
static u32 acpi_target_sleep_state = ACPI_STATE_S0;
|
||||
|
||||
/*
|
||||
* The ACPI specification wants us to save NVS memory regions during hibernation
|
||||
* and to restore them during the subsequent resume. Windows does that also for
|
||||
* suspend to RAM. However, it is known that this mechanism does not work on
|
||||
* all machines, so we allow the user to disable it with the help of the
|
||||
* 'acpi_sleep=nonvs' kernel command line option.
|
||||
*/
|
||||
static bool nvs_nosave;
|
||||
|
||||
void __init acpi_nvs_nosave(void)
|
||||
{
|
||||
nvs_nosave = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
|
||||
* user to request that behavior by using the 'acpi_old_suspend_ordering'
|
||||
|
@ -197,8 +211,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
|
|||
u32 acpi_state = acpi_suspend_states[pm_state];
|
||||
int error = 0;
|
||||
|
||||
error = suspend_nvs_alloc();
|
||||
|
||||
error = nvs_nosave ? 0 : suspend_nvs_alloc();
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -388,20 +401,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
|
|||
#endif /* CONFIG_SUSPEND */
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
/*
|
||||
* The ACPI specification wants us to save NVS memory regions during hibernation
|
||||
* and to restore them during the subsequent resume. However, it is not certain
|
||||
* if this mechanism is going to work on all machines, so we allow the user to
|
||||
* disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
|
||||
* option.
|
||||
*/
|
||||
static bool s4_no_nvs;
|
||||
|
||||
void __init acpi_s4_no_nvs(void)
|
||||
{
|
||||
s4_no_nvs = true;
|
||||
}
|
||||
|
||||
static unsigned long s4_hardware_signature;
|
||||
static struct acpi_table_facs *facs;
|
||||
static bool nosigcheck;
|
||||
|
@ -415,7 +414,7 @@ static int acpi_hibernation_begin(void)
|
|||
{
|
||||
int error;
|
||||
|
||||
error = s4_no_nvs ? 0 : suspend_nvs_alloc();
|
||||
error = nvs_nosave ? 0 : suspend_nvs_alloc();
|
||||
if (!error) {
|
||||
acpi_target_sleep_state = ACPI_STATE_S4;
|
||||
acpi_sleep_tts_switch(acpi_target_sleep_state);
|
||||
|
@ -510,7 +509,7 @@ static int acpi_hibernation_begin_old(void)
|
|||
error = acpi_sleep_prepare(ACPI_STATE_S4);
|
||||
|
||||
if (!error) {
|
||||
if (!s4_no_nvs)
|
||||
if (!nvs_nosave)
|
||||
error = suspend_nvs_alloc();
|
||||
if (!error)
|
||||
acpi_target_sleep_state = ACPI_STATE_S4;
|
||||
|
|
|
@ -673,7 +673,7 @@ static struct kobject *get_device_parent(struct device *dev,
|
|||
*/
|
||||
if (parent == NULL)
|
||||
parent_kobj = virtual_device_parent(dev);
|
||||
else if (parent->class)
|
||||
else if (parent->class && !dev->class->ns_type)
|
||||
return &parent->kobj;
|
||||
else
|
||||
parent_kobj = &parent->kobj;
|
||||
|
|
|
@ -816,9 +816,9 @@ static const struct intel_driver_description {
|
|||
{ 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,
|
||||
"Sandybridge", NULL, &intel_i965_driver },
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG,
|
||||
"Sandybridge", NULL, &intel_i965_driver },
|
||||
"Sandybridge", NULL, &intel_gen6_driver },
|
||||
{ 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -60,6 +60,12 @@
|
|||
#define I810_PTE_LOCAL 0x00000002
|
||||
#define I810_PTE_VALID 0x00000001
|
||||
#define I830_PTE_SYSTEM_CACHED 0x00000006
|
||||
/* GT PTE cache control fields */
|
||||
#define GEN6_PTE_UNCACHED 0x00000002
|
||||
#define GEN6_PTE_LLC 0x00000004
|
||||
#define GEN6_PTE_LLC_MLC 0x00000006
|
||||
#define GEN6_PTE_GFDT 0x00000008
|
||||
|
||||
#define I810_SMRAM_MISCC 0x70
|
||||
#define I810_GFX_MEM_WIN_SIZE 0x00010000
|
||||
#define I810_GFX_MEM_WIN_32M 0x00010000
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
#define USE_PCI_DMA_API 1
|
||||
#endif
|
||||
|
||||
/* Max amount of stolen space, anything above will be returned to Linux */
|
||||
int intel_max_stolen = 32 * 1024 * 1024;
|
||||
EXPORT_SYMBOL(intel_max_stolen);
|
||||
|
||||
static const struct aper_size_info_fixed intel_i810_sizes[] =
|
||||
{
|
||||
{64, 16384, 4},
|
||||
|
@ -104,7 +108,7 @@ static int intel_agp_map_memory(struct agp_memory *mem)
|
|||
DBG("try mapping %lu pages\n", (unsigned long)mem->page_count);
|
||||
|
||||
if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
goto err;
|
||||
|
||||
mem->sg_list = sg = st.sgl;
|
||||
|
||||
|
@ -113,11 +117,14 @@ static int intel_agp_map_memory(struct agp_memory *mem)
|
|||
|
||||
mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list,
|
||||
mem->page_count, PCI_DMA_BIDIRECTIONAL);
|
||||
if (unlikely(!mem->num_sg)) {
|
||||
intel_agp_free_sglist(mem);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (unlikely(!mem->num_sg))
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
sg_free_table(&st);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void intel_agp_unmap_memory(struct agp_memory *mem)
|
||||
|
@ -176,7 +183,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
|
|||
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
|
||||
{
|
||||
cache_bits = I830_PTE_SYSTEM_CACHED;
|
||||
cache_bits = GEN6_PTE_LLC_MLC;
|
||||
}
|
||||
|
||||
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
|
||||
|
@ -710,7 +717,12 @@ static void intel_i830_init_gtt_entries(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (gtt_entries > 0) {
|
||||
if (!local && gtt_entries > intel_max_stolen) {
|
||||
dev_info(&agp_bridge->dev->dev,
|
||||
"detected %dK stolen memory, trimming to %dK\n",
|
||||
gtt_entries / KB(1), intel_max_stolen / KB(1));
|
||||
gtt_entries = intel_max_stolen / KB(4);
|
||||
} else if (gtt_entries > 0) {
|
||||
dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n",
|
||||
gtt_entries / KB(1), local ? "local" : "stolen");
|
||||
gtt_entries /= KB(4);
|
||||
|
@ -797,6 +809,10 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
|
|||
|
||||
/* we have to call this as early as possible after the MMIO base address is known */
|
||||
intel_i830_init_gtt_entries();
|
||||
if (intel_private.gtt_entries == 0) {
|
||||
iounmap(intel_private.registers);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
agp_bridge->gatt_table = NULL;
|
||||
|
||||
|
@ -1216,17 +1232,20 @@ static int intel_i915_get_gtt_size(void)
|
|||
|
||||
/* G33's GTT size defined in gmch_ctrl */
|
||||
pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
|
||||
switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
|
||||
case G33_PGETBL_SIZE_1M:
|
||||
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
|
||||
case I830_GMCH_GMS_STOLEN_512:
|
||||
size = 512;
|
||||
break;
|
||||
case I830_GMCH_GMS_STOLEN_1024:
|
||||
size = 1024;
|
||||
break;
|
||||
case G33_PGETBL_SIZE_2M:
|
||||
size = 2048;
|
||||
case I830_GMCH_GMS_STOLEN_8192:
|
||||
size = 8*1024;
|
||||
break;
|
||||
default:
|
||||
dev_info(&agp_bridge->dev->dev,
|
||||
"unknown page table size 0x%x, assuming 512KB\n",
|
||||
(gmch_ctrl & G33_PGETBL_SIZE_MASK));
|
||||
(gmch_ctrl & I830_GMCH_GMS_MASK));
|
||||
size = 512;
|
||||
}
|
||||
} else {
|
||||
|
@ -1279,6 +1298,11 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
|
|||
|
||||
/* we have to call this as early as possible after the MMIO base address is known */
|
||||
intel_i830_init_gtt_entries();
|
||||
if (intel_private.gtt_entries == 0) {
|
||||
iounmap(intel_private.gtt);
|
||||
iounmap(intel_private.registers);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
agp_bridge->gatt_table = NULL;
|
||||
|
||||
|
@ -1306,6 +1330,16 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
|
|||
return addr | bridge->driver->masks[type].mask;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Type checking must be done elsewhere */
|
||||
return addr | bridge->driver->masks[type].mask;
|
||||
}
|
||||
|
||||
static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
|
||||
{
|
||||
u16 snb_gmch_ctl;
|
||||
|
@ -1387,6 +1421,11 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
|
|||
|
||||
/* we have to call this as early as possible after the MMIO base address is known */
|
||||
intel_i830_init_gtt_entries();
|
||||
if (intel_private.gtt_entries == 0) {
|
||||
iounmap(intel_private.gtt);
|
||||
iounmap(intel_private.registers);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
agp_bridge->gatt_table = NULL;
|
||||
|
||||
|
@ -1514,6 +1553,39 @@ static const struct agp_bridge_driver intel_i965_driver = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static const struct agp_bridge_driver intel_gen6_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.aperture_sizes = intel_i830_sizes,
|
||||
.size_type = FIXED_APER_SIZE,
|
||||
.num_aperture_sizes = 4,
|
||||
.needs_scratch_page = true,
|
||||
.configure = intel_i9xx_configure,
|
||||
.fetch_size = intel_i9xx_fetch_size,
|
||||
.cleanup = intel_i915_cleanup,
|
||||
.mask_memory = intel_gen6_mask_memory,
|
||||
.masks = intel_i810_masks,
|
||||
.agp_enable = intel_i810_agp_enable,
|
||||
.cache_flush = global_cache_flush,
|
||||
.create_gatt_table = intel_i965_create_gatt_table,
|
||||
.free_gatt_table = intel_i830_free_gatt_table,
|
||||
.insert_memory = intel_i915_insert_entries,
|
||||
.remove_memory = intel_i915_remove_entries,
|
||||
.alloc_by_type = intel_i830_alloc_by_type,
|
||||
.free_by_type = intel_i810_free_by_type,
|
||||
.agp_alloc_page = agp_generic_alloc_page,
|
||||
.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,
|
||||
.chipset_flush = intel_i915_chipset_flush,
|
||||
#ifdef USE_PCI_DMA_API
|
||||
.agp_map_page = intel_agp_map_page,
|
||||
.agp_unmap_page = intel_agp_unmap_page,
|
||||
.agp_map_memory = intel_agp_map_memory,
|
||||
.agp_unmap_memory = intel_agp_unmap_memory,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct agp_bridge_driver intel_g33_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.aperture_sizes = intel_i830_sizes,
|
||||
|
|
|
@ -623,7 +623,14 @@ static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
|
|||
|
||||
static int tpm_tis_pnp_resume(struct pnp_dev *dev)
|
||||
{
|
||||
return tpm_pm_resume(&dev->dev);
|
||||
struct tpm_chip *chip = pnp_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = tpm_pm_resume(&dev->dev);
|
||||
if (!ret)
|
||||
tpm_continue_selftest(chip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
|
||||
|
|
|
@ -1077,6 +1077,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
|
|||
|
||||
err_unlock_policy:
|
||||
unlock_policy_rwsem_write(cpu);
|
||||
free_cpumask_var(policy->related_cpus);
|
||||
err_free_cpumask:
|
||||
free_cpumask_var(policy->cpus);
|
||||
err_free_policy:
|
||||
|
@ -1762,17 +1763,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
|
|||
dprintk("governor switch\n");
|
||||
|
||||
/* end old governor */
|
||||
if (data->governor) {
|
||||
/*
|
||||
* Need to release the rwsem around governor
|
||||
* stop due to lock dependency between
|
||||
* cancel_delayed_work_sync and the read lock
|
||||
* taken in the delayed work handler.
|
||||
*/
|
||||
unlock_policy_rwsem_write(data->cpu);
|
||||
if (data->governor)
|
||||
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
|
||||
lock_policy_rwsem_write(data->cpu);
|
||||
}
|
||||
|
||||
/* start new governor */
|
||||
data->governor = policy->governor;
|
||||
|
|
|
@ -1300,7 +1300,7 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
|
|||
if (devno == 0)
|
||||
return -ENODEV;
|
||||
|
||||
i7core_printk(KERN_ERR,
|
||||
i7core_printk(KERN_INFO,
|
||||
"Device not found: dev %02x.%d PCI ID %04x:%04x\n",
|
||||
dev_descr->dev, dev_descr->func,
|
||||
PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
|
||||
|
|
|
@ -336,6 +336,7 @@ static struct of_device_id mpc85xx_pci_err_of_match[] = {
|
|||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mpc85xx_pci_err_of_match);
|
||||
|
||||
static struct of_platform_driver mpc85xx_pci_err_driver = {
|
||||
.probe = mpc85xx_pci_err_probe,
|
||||
|
@ -650,6 +651,7 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = {
|
|||
{ .compatible = "fsl,p2020-l2-cache-controller", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match);
|
||||
|
||||
static struct of_platform_driver mpc85xx_l2_err_driver = {
|
||||
.probe = mpc85xx_l2_err_probe,
|
||||
|
@ -1126,6 +1128,7 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = {
|
|||
{ .compatible = "fsl,p2020-memory-controller", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
|
||||
|
||||
static struct of_platform_driver mpc85xx_mc_err_driver = {
|
||||
.probe = mpc85xx_mc_err_probe,
|
||||
|
|
|
@ -893,10 +893,12 @@ EXPORT_SYMBOL_GPL(gpio_sysfs_set_active_low);
|
|||
void gpio_unexport(unsigned gpio)
|
||||
{
|
||||
struct gpio_desc *desc;
|
||||
int status = -EINVAL;
|
||||
int status = 0;
|
||||
|
||||
if (!gpio_is_valid(gpio))
|
||||
if (!gpio_is_valid(gpio)) {
|
||||
status = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mutex_lock(&sysfs_lock);
|
||||
|
||||
|
@ -911,7 +913,6 @@ void gpio_unexport(unsigned gpio)
|
|||
clear_bit(FLAG_EXPORT, &desc->flags);
|
||||
put_device(dev);
|
||||
device_unregister(dev);
|
||||
status = 0;
|
||||
} else
|
||||
status = -ENODEV;
|
||||
}
|
||||
|
|
|
@ -864,8 +864,8 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid,
|
|||
mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0,
|
||||
false);
|
||||
mode->hdisplay = 1366;
|
||||
mode->vsync_start = mode->vsync_start - 1;
|
||||
mode->vsync_end = mode->vsync_end - 1;
|
||||
mode->hsync_start = mode->hsync_start - 1;
|
||||
mode->hsync_end = mode->hsync_end - 1;
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
|
|
@ -605,6 +605,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
|
|||
case FBC_NOT_TILED:
|
||||
seq_printf(m, "scanout buffer not tiled");
|
||||
break;
|
||||
case FBC_MULTIPLE_PIPES:
|
||||
seq_printf(m, "multiple pipes are enabled");
|
||||
break;
|
||||
default:
|
||||
seq_printf(m, "unknown reason");
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#include <linux/vga_switcheroo.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
extern int intel_max_stolen; /* from AGP driver */
|
||||
|
||||
/**
|
||||
* Sets up the hardware status page for devices that need a physical address
|
||||
* in the register.
|
||||
|
@ -1257,7 +1259,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
|
|||
drm_mm_put_block(compressed_fb);
|
||||
}
|
||||
|
||||
if (!IS_GM45(dev)) {
|
||||
if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) {
|
||||
compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096,
|
||||
4096, 0);
|
||||
if (!compressed_llb) {
|
||||
|
@ -1283,8 +1285,9 @@ static void i915_setup_compression(struct drm_device *dev, int size)
|
|||
|
||||
intel_disable_fbc(dev);
|
||||
dev_priv->compressed_fb = compressed_fb;
|
||||
|
||||
if (IS_GM45(dev)) {
|
||||
if (IS_IRONLAKE_M(dev))
|
||||
I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
|
||||
else if (IS_GM45(dev)) {
|
||||
I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
|
||||
} else {
|
||||
I915_WRITE(FBC_CFB_BASE, cfb_base);
|
||||
|
@ -1292,7 +1295,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
|
|||
dev_priv->compressed_llb = compressed_llb;
|
||||
}
|
||||
|
||||
DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
|
||||
DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
|
||||
ll_base, size >> 20);
|
||||
}
|
||||
|
||||
|
@ -1301,7 +1304,7 @@ static void i915_cleanup_compression(struct drm_device *dev)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
drm_mm_put_block(dev_priv->compressed_fb);
|
||||
if (!IS_GM45(dev))
|
||||
if (dev_priv->compressed_llb)
|
||||
drm_mm_put_block(dev_priv->compressed_llb);
|
||||
}
|
||||
|
||||
|
@ -2105,6 +2108,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
if (ret)
|
||||
goto out_iomapfree;
|
||||
|
||||
if (prealloc_size > intel_max_stolen) {
|
||||
DRM_INFO("detected %dM stolen memory, trimming to %dM\n",
|
||||
prealloc_size >> 20, intel_max_stolen >> 20);
|
||||
prealloc_size = intel_max_stolen;
|
||||
}
|
||||
|
||||
dev_priv->wq = create_singlethread_workqueue("i915");
|
||||
if (dev_priv->wq == NULL) {
|
||||
DRM_ERROR("Failed to create our workqueue.\n");
|
||||
|
|
|
@ -93,11 +93,11 @@ static const struct intel_device_info intel_i945gm_info = {
|
|||
};
|
||||
|
||||
static const struct intel_device_info intel_i965g_info = {
|
||||
.is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
|
||||
.is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i965gm_info = {
|
||||
.is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1,
|
||||
.is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1,
|
||||
.is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
|
||||
.has_hotplug = 1,
|
||||
};
|
||||
|
@ -114,7 +114,7 @@ static const struct intel_device_info intel_g45_info = {
|
|||
};
|
||||
|
||||
static const struct intel_device_info intel_gm45_info = {
|
||||
.is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1,
|
||||
.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,
|
||||
|
@ -134,7 +134,7 @@ static const struct intel_device_info intel_ironlake_d_info = {
|
|||
|
||||
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_rc6 = 1,
|
||||
.need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
|
||||
.has_hotplug = 1,
|
||||
};
|
||||
|
||||
|
@ -148,33 +148,33 @@ static const struct intel_device_info intel_sandybridge_m_info = {
|
|||
.has_hotplug = 1, .is_gen6 = 1,
|
||||
};
|
||||
|
||||
static const struct pci_device_id pciidlist[] = {
|
||||
INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
|
||||
INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
|
||||
INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
|
||||
static const struct pci_device_id pciidlist[] = { /* aka */
|
||||
INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */
|
||||
INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */
|
||||
INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), /* I855_GM */
|
||||
INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
|
||||
INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
|
||||
INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
|
||||
INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
|
||||
INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),
|
||||
INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),
|
||||
INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),
|
||||
INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),
|
||||
INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),
|
||||
INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),
|
||||
INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),
|
||||
INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),
|
||||
INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),
|
||||
INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),
|
||||
INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),
|
||||
INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),
|
||||
INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),
|
||||
INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),
|
||||
INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),
|
||||
INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),
|
||||
INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),
|
||||
INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),
|
||||
INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),
|
||||
INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), /* I865_G */
|
||||
INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), /* I915_G */
|
||||
INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), /* E7221_G */
|
||||
INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), /* I915_GM */
|
||||
INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), /* I945_G */
|
||||
INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), /* I945_GM */
|
||||
INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), /* I945_GME */
|
||||
INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), /* I946_GZ */
|
||||
INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), /* G35_G */
|
||||
INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), /* I965_Q */
|
||||
INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), /* I965_G */
|
||||
INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), /* Q35_G */
|
||||
INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), /* G33_G */
|
||||
INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), /* Q33_G */
|
||||
INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), /* I965_GM */
|
||||
INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), /* I965_GME */
|
||||
INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), /* GM45_G */
|
||||
INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), /* IGD_E_G */
|
||||
INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), /* Q45_G */
|
||||
INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */
|
||||
INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */
|
||||
INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */
|
||||
INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
|
||||
INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
|
||||
INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
|
||||
|
@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
|
|||
/*
|
||||
* Clear request list
|
||||
*/
|
||||
i915_gem_retire_requests(dev, &dev_priv->render_ring);
|
||||
i915_gem_retire_requests(dev);
|
||||
|
||||
if (need_display)
|
||||
i915_save_display(dev);
|
||||
|
@ -482,7 +482,7 @@ static int i915_pm_poweroff(struct device *dev)
|
|||
return i915_drm_freeze(drm_dev);
|
||||
}
|
||||
|
||||
const struct dev_pm_ops i915_pm_ops = {
|
||||
static const struct dev_pm_ops i915_pm_ops = {
|
||||
.suspend = i915_pm_suspend,
|
||||
.resume = i915_pm_resume,
|
||||
.freeze = i915_pm_freeze,
|
||||
|
|
|
@ -176,7 +176,8 @@ struct drm_i915_display_funcs {
|
|||
int (*get_display_clock_speed)(struct drm_device *dev);
|
||||
int (*get_fifo_size)(struct drm_device *dev, int plane);
|
||||
void (*update_wm)(struct drm_device *dev, int planea_clock,
|
||||
int planeb_clock, int sr_hdisplay, int pixel_size);
|
||||
int planeb_clock, int sr_hdisplay, int sr_htotal,
|
||||
int pixel_size);
|
||||
/* clock updates for mode set */
|
||||
/* cursor updates */
|
||||
/* render clock increase/decrease */
|
||||
|
@ -200,6 +201,8 @@ struct intel_device_info {
|
|||
u8 need_gfx_hws : 1;
|
||||
u8 is_g4x : 1;
|
||||
u8 is_pineview : 1;
|
||||
u8 is_broadwater : 1;
|
||||
u8 is_crestline : 1;
|
||||
u8 is_ironlake : 1;
|
||||
u8 is_gen6 : 1;
|
||||
u8 has_fbc : 1;
|
||||
|
@ -215,6 +218,7 @@ enum no_fbc_reason {
|
|||
FBC_MODE_TOO_LARGE, /* mode too large for compression */
|
||||
FBC_BAD_PLANE, /* fbc not supported on plane */
|
||||
FBC_NOT_TILED, /* buffer not tiled */
|
||||
FBC_MULTIPLE_PIPES, /* more than one pipe active */
|
||||
};
|
||||
|
||||
enum intel_pch {
|
||||
|
@ -222,6 +226,8 @@ enum intel_pch {
|
|||
PCH_CPT, /* Cougarpoint PCH */
|
||||
};
|
||||
|
||||
#define QUIRK_PIPEA_FORCE (1<<0)
|
||||
|
||||
struct intel_fbdev;
|
||||
|
||||
typedef struct drm_i915_private {
|
||||
|
@ -285,6 +291,8 @@ typedef struct drm_i915_private {
|
|||
struct timer_list hangcheck_timer;
|
||||
int hangcheck_count;
|
||||
uint32_t last_acthd;
|
||||
uint32_t last_instdone;
|
||||
uint32_t last_instdone1;
|
||||
|
||||
struct drm_mm vram;
|
||||
|
||||
|
@ -337,6 +345,8 @@ typedef struct drm_i915_private {
|
|||
/* PCH chipset type */
|
||||
enum intel_pch pch_type;
|
||||
|
||||
unsigned long quirks;
|
||||
|
||||
/* Register state */
|
||||
bool modeset_on_lid;
|
||||
u8 saveLBB;
|
||||
|
@ -541,6 +551,14 @@ typedef struct drm_i915_private {
|
|||
/** LRU list of objects with fence regs on them. */
|
||||
struct list_head fence_list;
|
||||
|
||||
/**
|
||||
* List of objects currently pending being freed.
|
||||
*
|
||||
* These objects are no longer in use, but due to a signal
|
||||
* we were prevented from freeing them at the appointed time.
|
||||
*/
|
||||
struct list_head deferred_free_list;
|
||||
|
||||
/**
|
||||
* We leave the user IRQ off as much as possible,
|
||||
* but this means that requests will finish and never
|
||||
|
@ -672,7 +690,7 @@ struct drm_i915_gem_object {
|
|||
*
|
||||
* Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
|
||||
*/
|
||||
int fence_reg : 5;
|
||||
signed int fence_reg : 5;
|
||||
|
||||
/**
|
||||
* Used for checking the object doesn't appear more than once
|
||||
|
@ -708,7 +726,7 @@ struct drm_i915_gem_object {
|
|||
*
|
||||
* In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
|
||||
* bits with absolutely no headroom. So use 4 bits. */
|
||||
int pin_count : 4;
|
||||
unsigned int pin_count : 4;
|
||||
#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
|
||||
|
||||
/** AGP memory structure for our GTT binding. */
|
||||
|
@ -738,7 +756,7 @@ struct drm_i915_gem_object {
|
|||
uint32_t stride;
|
||||
|
||||
/** Record of address bit 17 of each page at last unbind. */
|
||||
long *bit_17;
|
||||
unsigned long *bit_17;
|
||||
|
||||
/** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
|
||||
uint32_t agp_type;
|
||||
|
@ -950,8 +968,7 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev,
|
|||
bool i915_seqno_passed(uint32_t seq1, uint32_t seq2);
|
||||
int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
|
||||
int i915_gem_object_put_fence_reg(struct drm_gem_object *obj);
|
||||
void i915_gem_retire_requests(struct drm_device *dev,
|
||||
struct intel_ring_buffer *ring);
|
||||
void i915_gem_retire_requests(struct drm_device *dev);
|
||||
void i915_gem_retire_work_handler(struct work_struct *work);
|
||||
void i915_gem_clflush_object(struct drm_gem_object *obj);
|
||||
int i915_gem_object_set_domain(struct drm_gem_object *obj,
|
||||
|
@ -981,7 +998,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev);
|
|||
int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
|
||||
void i915_gem_object_put_pages(struct drm_gem_object *obj);
|
||||
void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
|
||||
void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
|
||||
int i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
|
||||
|
||||
void i915_gem_shrinker_init(void);
|
||||
void i915_gem_shrinker_exit(void);
|
||||
|
@ -1041,6 +1058,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
|
|||
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
|
||||
extern void i8xx_disable_fbc(struct drm_device *dev);
|
||||
extern void g4x_disable_fbc(struct drm_device *dev);
|
||||
extern void ironlake_disable_fbc(struct drm_device *dev);
|
||||
extern void intel_disable_fbc(struct drm_device *dev);
|
||||
extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
|
||||
extern bool intel_fbc_enabled(struct drm_device *dev);
|
||||
|
@ -1130,6 +1148,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
|
|||
#define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm)
|
||||
#define IS_I965G(dev) (INTEL_INFO(dev)->is_i965g)
|
||||
#define IS_I965GM(dev) (INTEL_INFO(dev)->is_i965gm)
|
||||
#define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater)
|
||||
#define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline)
|
||||
#define IS_GM45(dev) ((dev)->pci_device == 0x2A42)
|
||||
#define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x)
|
||||
#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001)
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <linux/swap.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
|
||||
static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
|
||||
static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
|
||||
static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
|
||||
static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj,
|
||||
|
@ -53,6 +53,7 @@ static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
|
|||
static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
|
||||
struct drm_i915_gem_pwrite *args,
|
||||
struct drm_file *file_priv);
|
||||
static void i915_gem_free_object_tail(struct drm_gem_object *obj);
|
||||
|
||||
static LIST_HEAD(shrink_list);
|
||||
static DEFINE_SPINLOCK(shrink_list_lock);
|
||||
|
@ -127,8 +128,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
return -ENOMEM;
|
||||
|
||||
ret = drm_gem_handle_create(file_priv, obj, &handle);
|
||||
drm_gem_object_handle_unreference_unlocked(obj);
|
||||
|
||||
drm_gem_object_unreference_unlocked(obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1709,9 +1709,9 @@ i915_get_gem_seqno(struct drm_device *dev,
|
|||
/**
|
||||
* This function clears the request list as sequence numbers are passed.
|
||||
*/
|
||||
void
|
||||
i915_gem_retire_requests(struct drm_device *dev,
|
||||
struct intel_ring_buffer *ring)
|
||||
static void
|
||||
i915_gem_retire_requests_ring(struct drm_device *dev,
|
||||
struct intel_ring_buffer *ring)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t seqno;
|
||||
|
@ -1750,6 +1750,30 @@ i915_gem_retire_requests(struct drm_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
i915_gem_retire_requests(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if (!list_empty(&dev_priv->mm.deferred_free_list)) {
|
||||
struct drm_i915_gem_object *obj_priv, *tmp;
|
||||
|
||||
/* We must be careful that during unbind() we do not
|
||||
* accidentally infinitely recurse into retire requests.
|
||||
* Currently:
|
||||
* retire -> free -> unbind -> wait -> retire_ring
|
||||
*/
|
||||
list_for_each_entry_safe(obj_priv, tmp,
|
||||
&dev_priv->mm.deferred_free_list,
|
||||
list)
|
||||
i915_gem_free_object_tail(&obj_priv->base);
|
||||
}
|
||||
|
||||
i915_gem_retire_requests_ring(dev, &dev_priv->render_ring);
|
||||
if (HAS_BSD(dev))
|
||||
i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring);
|
||||
}
|
||||
|
||||
void
|
||||
i915_gem_retire_work_handler(struct work_struct *work)
|
||||
{
|
||||
|
@ -1761,10 +1785,7 @@ i915_gem_retire_work_handler(struct work_struct *work)
|
|||
dev = dev_priv->dev;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
i915_gem_retire_requests(dev, &dev_priv->render_ring);
|
||||
|
||||
if (HAS_BSD(dev))
|
||||
i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
|
||||
i915_gem_retire_requests(dev);
|
||||
|
||||
if (!dev_priv->mm.suspended &&
|
||||
(!list_empty(&dev_priv->render_ring.request_list) ||
|
||||
|
@ -1832,7 +1853,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno,
|
|||
* a separate wait queue to handle that.
|
||||
*/
|
||||
if (ret == 0)
|
||||
i915_gem_retire_requests(dev, ring);
|
||||
i915_gem_retire_requests_ring(dev, ring);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1945,11 +1966,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
|
|||
* before we unbind.
|
||||
*/
|
||||
ret = i915_gem_object_set_to_cpu_domain(obj, 1);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("set_domain failed: %d\n", ret);
|
||||
if (ret == -ERESTARTSYS)
|
||||
return ret;
|
||||
}
|
||||
/* Continue on if we fail due to EIO, the GPU is hung so we
|
||||
* should be safe and we need to cleanup or else we might
|
||||
* cause memory corruption through use-after-free.
|
||||
*/
|
||||
|
||||
BUG_ON(obj_priv->active);
|
||||
|
||||
|
@ -1985,7 +2007,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
|
|||
|
||||
trace_i915_gem_object_unbind(obj);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct drm_gem_object *
|
||||
|
@ -2107,10 +2129,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
|
|||
struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
|
||||
struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring;
|
||||
for (;;) {
|
||||
i915_gem_retire_requests(dev, render_ring);
|
||||
|
||||
if (HAS_BSD(dev))
|
||||
i915_gem_retire_requests(dev, bsd_ring);
|
||||
i915_gem_retire_requests(dev);
|
||||
|
||||
/* If there's an inactive buffer available now, grab it
|
||||
* and be done.
|
||||
|
@ -2583,7 +2602,10 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
|
|||
if (!IS_I965G(dev)) {
|
||||
int ret;
|
||||
|
||||
i915_gem_object_flush_gpu_write_domain(obj);
|
||||
ret = i915_gem_object_flush_gpu_write_domain(obj);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = i915_gem_object_wait_rendering(obj);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
@ -2731,7 +2753,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
|
|||
}
|
||||
|
||||
/** Flushes any GPU write domain for the object if it's dirty. */
|
||||
static void
|
||||
static int
|
||||
i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
|
@ -2739,17 +2761,18 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
|
|||
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
|
||||
|
||||
if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/* Queue the GPU write cache flushing we need. */
|
||||
old_write_domain = obj->write_domain;
|
||||
i915_gem_flush(dev, 0, obj->write_domain);
|
||||
(void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring);
|
||||
BUG_ON(obj->write_domain);
|
||||
if (i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring) == 0)
|
||||
return -ENOMEM;
|
||||
|
||||
trace_i915_gem_object_change_domain(obj,
|
||||
obj->read_domains,
|
||||
old_write_domain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Flushes the GTT write domain for the object if it's dirty. */
|
||||
|
@ -2793,9 +2816,11 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
|
|||
old_write_domain);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (obj->write_domain) {
|
||||
case I915_GEM_DOMAIN_GTT:
|
||||
i915_gem_object_flush_gtt_write_domain(obj);
|
||||
|
@ -2804,9 +2829,11 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
|
|||
i915_gem_object_flush_cpu_write_domain(obj);
|
||||
break;
|
||||
default:
|
||||
i915_gem_object_flush_gpu_write_domain(obj);
|
||||
ret = i915_gem_object_flush_gpu_write_domain(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2826,7 +2853,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
|
|||
if (obj_priv->gtt_space == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
i915_gem_object_flush_gpu_write_domain(obj);
|
||||
ret = i915_gem_object_flush_gpu_write_domain(obj);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* Wait on any GPU rendering and flushing to occur. */
|
||||
ret = i915_gem_object_wait_rendering(obj);
|
||||
if (ret != 0)
|
||||
|
@ -2876,7 +2906,9 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
|
|||
if (obj_priv->gtt_space == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
i915_gem_object_flush_gpu_write_domain(obj);
|
||||
ret = i915_gem_object_flush_gpu_write_domain(obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait on any GPU rendering and flushing to occur. */
|
||||
if (obj_priv->active) {
|
||||
|
@ -2924,7 +2956,10 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
|
|||
uint32_t old_write_domain, old_read_domains;
|
||||
int ret;
|
||||
|
||||
i915_gem_object_flush_gpu_write_domain(obj);
|
||||
ret = i915_gem_object_flush_gpu_write_domain(obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait on any GPU rendering and flushing to occur. */
|
||||
ret = i915_gem_object_wait_rendering(obj);
|
||||
if (ret != 0)
|
||||
|
@ -3214,7 +3249,10 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
|
|||
if (offset == 0 && size == obj->size)
|
||||
return i915_gem_object_set_to_cpu_domain(obj, 0);
|
||||
|
||||
i915_gem_object_flush_gpu_write_domain(obj);
|
||||
ret = i915_gem_object_flush_gpu_write_domain(obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait on any GPU rendering and flushing to occur. */
|
||||
ret = i915_gem_object_wait_rendering(obj);
|
||||
if (ret != 0)
|
||||
|
@ -3645,6 +3683,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv,
|
||||
|
@ -3792,7 +3831,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
|||
unsigned long long total_size = 0;
|
||||
int num_fences = 0;
|
||||
for (i = 0; i < args->buffer_count; i++) {
|
||||
obj_priv = object_list[i]->driver_private;
|
||||
obj_priv = to_intel_bo(object_list[i]);
|
||||
|
||||
total_size += object_list[i]->size;
|
||||
num_fences +=
|
||||
|
@ -4310,7 +4349,6 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_i915_gem_busy *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_i915_gem_object *obj_priv;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL) {
|
||||
|
@ -4325,10 +4363,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
|
|||
* actually unmasked, and our working set ends up being larger than
|
||||
* required.
|
||||
*/
|
||||
i915_gem_retire_requests(dev, &dev_priv->render_ring);
|
||||
|
||||
if (HAS_BSD(dev))
|
||||
i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
|
||||
i915_gem_retire_requests(dev);
|
||||
|
||||
obj_priv = to_intel_bo(obj);
|
||||
/* Don't count being on the flushing list against the object being
|
||||
|
@ -4438,6 +4473,30 @@ int i915_gem_init_object(struct drm_gem_object *obj)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void i915_gem_free_object_tail(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
|
||||
int ret;
|
||||
|
||||
ret = i915_gem_object_unbind(obj);
|
||||
if (ret == -ERESTARTSYS) {
|
||||
list_move(&obj_priv->list,
|
||||
&dev_priv->mm.deferred_free_list);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj_priv->mmap_offset)
|
||||
i915_gem_free_mmap_offset(obj);
|
||||
|
||||
drm_gem_object_release(obj);
|
||||
|
||||
kfree(obj_priv->page_cpu_valid);
|
||||
kfree(obj_priv->bit_17);
|
||||
kfree(obj_priv);
|
||||
}
|
||||
|
||||
void i915_gem_free_object(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
|
@ -4451,16 +4510,7 @@ void i915_gem_free_object(struct drm_gem_object *obj)
|
|||
if (obj_priv->phys_obj)
|
||||
i915_gem_detach_phys_object(dev, obj);
|
||||
|
||||
i915_gem_object_unbind(obj);
|
||||
|
||||
if (obj_priv->mmap_offset)
|
||||
i915_gem_free_mmap_offset(obj);
|
||||
|
||||
drm_gem_object_release(obj);
|
||||
|
||||
kfree(obj_priv->page_cpu_valid);
|
||||
kfree(obj_priv->bit_17);
|
||||
kfree(obj_priv);
|
||||
i915_gem_free_object_tail(obj);
|
||||
}
|
||||
|
||||
/** Unbinds all inactive objects. */
|
||||
|
@ -4686,9 +4736,19 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
|
|||
BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list));
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
drm_irq_install(dev);
|
||||
ret = drm_irq_install(dev);
|
||||
if (ret)
|
||||
goto cleanup_ringbuffer;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup_ringbuffer:
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
i915_gem_cleanup_ringbuffer(dev);
|
||||
dev_priv->mm.suspended = 1;
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -4726,6 +4786,7 @@ i915_gem_load(struct drm_device *dev)
|
|||
INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.fence_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list);
|
||||
INIT_LIST_HEAD(&dev_priv->render_ring.active_list);
|
||||
INIT_LIST_HEAD(&dev_priv->render_ring.request_list);
|
||||
if (HAS_BSD(dev)) {
|
||||
|
@ -5024,10 +5085,7 @@ i915_gem_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
|
|||
continue;
|
||||
|
||||
spin_unlock(&shrink_list_lock);
|
||||
i915_gem_retire_requests(dev, &dev_priv->render_ring);
|
||||
|
||||
if (HAS_BSD(dev))
|
||||
i915_gem_retire_requests(dev, &dev_priv->bsd_ring);
|
||||
i915_gem_retire_requests(dev);
|
||||
|
||||
list_for_each_entry_safe(obj_priv, next_obj,
|
||||
&dev_priv->mm.inactive_list,
|
||||
|
|
|
@ -333,8 +333,6 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
|
|||
i915_gem_release_mmap(obj);
|
||||
|
||||
if (ret != 0) {
|
||||
WARN(ret != -ERESTARTSYS,
|
||||
"failed to reset object for tiling switch");
|
||||
args->tiling_mode = obj_priv->tiling_mode;
|
||||
args->stride = obj_priv->stride;
|
||||
goto err;
|
||||
|
|
|
@ -171,10 +171,10 @@ void intel_enable_asle (struct drm_device *dev)
|
|||
ironlake_enable_display_irq(dev_priv, DE_GSE);
|
||||
else {
|
||||
i915_enable_pipestat(dev_priv, 1,
|
||||
I915_LEGACY_BLC_EVENT_ENABLE);
|
||||
PIPE_LEGACY_BLC_EVENT_ENABLE);
|
||||
if (IS_I965G(dev))
|
||||
i915_enable_pipestat(dev_priv, 0,
|
||||
I915_LEGACY_BLC_EVENT_ENABLE);
|
||||
PIPE_LEGACY_BLC_EVENT_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -842,7 +842,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
u32 iir, new_iir;
|
||||
u32 pipea_stats, pipeb_stats;
|
||||
u32 vblank_status;
|
||||
u32 vblank_enable;
|
||||
int vblank = 0;
|
||||
unsigned long irqflags;
|
||||
int irq_received;
|
||||
|
@ -856,13 +855,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
|
||||
iir = I915_READ(IIR);
|
||||
|
||||
if (IS_I965G(dev)) {
|
||||
vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
|
||||
vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
|
||||
} else {
|
||||
vblank_status = I915_VBLANK_INTERRUPT_STATUS;
|
||||
vblank_enable = I915_VBLANK_INTERRUPT_ENABLE;
|
||||
}
|
||||
if (IS_I965G(dev))
|
||||
vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS;
|
||||
else
|
||||
vblank_status = PIPE_VBLANK_INTERRUPT_STATUS;
|
||||
|
||||
for (;;) {
|
||||
irq_received = iir != 0;
|
||||
|
@ -966,8 +962,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
intel_finish_page_flip(dev, 1);
|
||||
}
|
||||
|
||||
if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
|
||||
(pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
|
||||
if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
|
||||
(pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
|
||||
(iir & I915_ASLE_INTERRUPT))
|
||||
opregion_asle_intr(dev);
|
||||
|
||||
|
@ -1233,16 +1229,21 @@ void i915_hangcheck_elapsed(unsigned long data)
|
|||
{
|
||||
struct drm_device *dev = (struct drm_device *)data;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t acthd;
|
||||
uint32_t acthd, instdone, instdone1;
|
||||
|
||||
/* No reset support on this chip yet. */
|
||||
if (IS_GEN6(dev))
|
||||
return;
|
||||
|
||||
if (!IS_I965G(dev))
|
||||
if (!IS_I965G(dev)) {
|
||||
acthd = I915_READ(ACTHD);
|
||||
else
|
||||
instdone = I915_READ(INSTDONE);
|
||||
instdone1 = 0;
|
||||
} else {
|
||||
acthd = I915_READ(ACTHD_I965);
|
||||
instdone = I915_READ(INSTDONE_I965);
|
||||
instdone1 = I915_READ(INSTDONE1);
|
||||
}
|
||||
|
||||
/* If all work is done then ACTHD clearly hasn't advanced. */
|
||||
if (list_empty(&dev_priv->render_ring.request_list) ||
|
||||
|
@ -1253,21 +1254,24 @@ void i915_hangcheck_elapsed(unsigned long data)
|
|||
return;
|
||||
}
|
||||
|
||||
if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) {
|
||||
DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
|
||||
i915_handle_error(dev, true);
|
||||
return;
|
||||
}
|
||||
if (dev_priv->last_acthd == acthd &&
|
||||
dev_priv->last_instdone == instdone &&
|
||||
dev_priv->last_instdone1 == instdone1) {
|
||||
if (dev_priv->hangcheck_count++ > 1) {
|
||||
DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
|
||||
i915_handle_error(dev, true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
dev_priv->hangcheck_count = 0;
|
||||
|
||||
dev_priv->last_acthd = acthd;
|
||||
dev_priv->last_instdone = instdone;
|
||||
dev_priv->last_instdone1 = instdone1;
|
||||
}
|
||||
|
||||
/* Reset timer case chip hangs without another request being added */
|
||||
mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
|
||||
|
||||
if (acthd != dev_priv->last_acthd)
|
||||
dev_priv->hangcheck_count = 0;
|
||||
else
|
||||
dev_priv->hangcheck_count++;
|
||||
|
||||
dev_priv->last_acthd = acthd;
|
||||
}
|
||||
|
||||
/* drm_dma.h hooks
|
||||
|
|
|
@ -442,7 +442,7 @@
|
|||
#define GEN6_RENDER_IMR 0x20a8
|
||||
#define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8)
|
||||
#define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7)
|
||||
#define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6)
|
||||
#define GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED (1 << 6)
|
||||
#define GEN6_RENDER_L3_PARITY_ERROR (1 << 5)
|
||||
#define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4)
|
||||
#define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3)
|
||||
|
@ -530,6 +530,21 @@
|
|||
#define DPFC_CHICKEN 0x3224
|
||||
#define DPFC_HT_MODIFY (1<<31)
|
||||
|
||||
/* Framebuffer compression for Ironlake */
|
||||
#define ILK_DPFC_CB_BASE 0x43200
|
||||
#define ILK_DPFC_CONTROL 0x43208
|
||||
/* The bit 28-8 is reserved */
|
||||
#define DPFC_RESERVED (0x1FFFFF00)
|
||||
#define ILK_DPFC_RECOMP_CTL 0x4320c
|
||||
#define ILK_DPFC_STATUS 0x43210
|
||||
#define ILK_DPFC_FENCE_YOFF 0x43218
|
||||
#define ILK_DPFC_CHICKEN 0x43224
|
||||
#define ILK_FBC_RT_BASE 0x2128
|
||||
#define ILK_FBC_RT_VALID (1<<0)
|
||||
|
||||
#define ILK_DISPLAY_CHICKEN1 0x42000
|
||||
#define ILK_FBCQ_DIS (1<<22)
|
||||
|
||||
/*
|
||||
* GPIO regs
|
||||
*/
|
||||
|
@ -595,32 +610,6 @@
|
|||
#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
|
||||
#define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */
|
||||
|
||||
#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
|
||||
#define I915_CRC_ERROR_ENABLE (1UL<<29)
|
||||
#define I915_CRC_DONE_ENABLE (1UL<<28)
|
||||
#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
|
||||
#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
|
||||
#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
|
||||
#define I915_DPST_EVENT_ENABLE (1UL<<23)
|
||||
#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
|
||||
#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
|
||||
#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
|
||||
#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
|
||||
#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
|
||||
#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
|
||||
#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
|
||||
#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
|
||||
#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
|
||||
#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
|
||||
#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
|
||||
#define I915_DPST_EVENT_STATUS (1UL<<7)
|
||||
#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
|
||||
#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
|
||||
#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
|
||||
#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
|
||||
#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
|
||||
#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
|
||||
|
||||
#define SRX_INDEX 0x3c4
|
||||
#define SRX_DATA 0x3c5
|
||||
#define SR01 1
|
||||
|
@ -2166,7 +2155,8 @@
|
|||
#define I830_FIFO_LINE_SIZE 32
|
||||
|
||||
#define G4X_FIFO_SIZE 127
|
||||
#define I945_FIFO_SIZE 127 /* 945 & 965 */
|
||||
#define I965_FIFO_SIZE 512
|
||||
#define I945_FIFO_SIZE 127
|
||||
#define I915_FIFO_SIZE 95
|
||||
#define I855GM_FIFO_SIZE 127 /* In cachelines */
|
||||
#define I830_FIFO_SIZE 95
|
||||
|
@ -2185,6 +2175,9 @@
|
|||
#define PINEVIEW_CURSOR_DFT_WM 0
|
||||
#define PINEVIEW_CURSOR_GUARD_WM 5
|
||||
|
||||
#define I965_CURSOR_FIFO 64
|
||||
#define I965_CURSOR_MAX_WM 32
|
||||
#define I965_CURSOR_DFT_WM 8
|
||||
|
||||
/* define the Watermark register on Ironlake */
|
||||
#define WM0_PIPEA_ILK 0x45100
|
||||
|
@ -2212,6 +2205,9 @@
|
|||
#define ILK_DISPLAY_FIFO 128
|
||||
#define ILK_DISPLAY_MAXWM 64
|
||||
#define ILK_DISPLAY_DFTWM 8
|
||||
#define ILK_CURSOR_FIFO 32
|
||||
#define ILK_CURSOR_MAXWM 16
|
||||
#define ILK_CURSOR_DFTWM 8
|
||||
|
||||
#define ILK_DISPLAY_SR_FIFO 512
|
||||
#define ILK_DISPLAY_MAX_SRWM 0x1ff
|
||||
|
@ -2510,6 +2506,10 @@
|
|||
#define ILK_VSDPFD_FULL (1<<21)
|
||||
#define ILK_DSPCLK_GATE 0x42020
|
||||
#define ILK_DPARB_CLK_GATE (1<<5)
|
||||
/* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */
|
||||
#define ILK_CLK_FBC (1<<7)
|
||||
#define ILK_DPFC_DIS1 (1<<8)
|
||||
#define ILK_DPFC_DIS2 (1<<9)
|
||||
|
||||
#define DISP_ARB_CTL 0x45000
|
||||
#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
|
||||
|
@ -2869,6 +2869,7 @@
|
|||
|
||||
#define PCH_PP_STATUS 0xc7200
|
||||
#define PCH_PP_CONTROL 0xc7204
|
||||
#define PANEL_UNLOCK_REGS (0xabcd << 16)
|
||||
#define EDP_FORCE_VDD (1 << 3)
|
||||
#define EDP_BLC_ENABLE (1 << 2)
|
||||
#define PANEL_POWER_RESET (1 << 1)
|
||||
|
|
|
@ -602,7 +602,9 @@ void i915_save_display(struct drm_device *dev)
|
|||
|
||||
/* Only save FBC state on the platform that supports FBC */
|
||||
if (I915_HAS_FBC(dev)) {
|
||||
if (IS_GM45(dev)) {
|
||||
if (IS_IRONLAKE_M(dev)) {
|
||||
dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE);
|
||||
} else if (IS_GM45(dev)) {
|
||||
dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
|
||||
} else {
|
||||
dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
|
||||
|
@ -706,7 +708,10 @@ void i915_restore_display(struct drm_device *dev)
|
|||
|
||||
/* only restore FBC info on the platform that supports FBC*/
|
||||
if (I915_HAS_FBC(dev)) {
|
||||
if (IS_GM45(dev)) {
|
||||
if (IS_IRONLAKE_M(dev)) {
|
||||
ironlake_disable_fbc(dev);
|
||||
I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
|
||||
} else if (IS_GM45(dev)) {
|
||||
g4x_disable_fbc(dev);
|
||||
I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
|
||||
} else {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,6 +43,7 @@
|
|||
#define DP_LINK_CONFIGURATION_SIZE 9
|
||||
|
||||
#define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP)
|
||||
#define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp)
|
||||
|
||||
struct intel_dp_priv {
|
||||
uint32_t output_reg;
|
||||
|
@ -56,6 +57,7 @@ struct intel_dp_priv {
|
|||
struct intel_encoder *intel_encoder;
|
||||
struct i2c_adapter adapter;
|
||||
struct i2c_algo_dp_aux_data algo;
|
||||
bool is_pch_edp;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -128,8 +130,9 @@ intel_dp_link_required(struct drm_device *dev,
|
|||
struct intel_encoder *intel_encoder, int pixel_clock)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
|
||||
|
||||
if (IS_eDP(intel_encoder))
|
||||
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv))
|
||||
return (pixel_clock * dev_priv->edp_bpp) / 8;
|
||||
else
|
||||
return pixel_clock * 3;
|
||||
|
@ -147,9 +150,21 @@ intel_dp_mode_valid(struct drm_connector *connector,
|
|||
{
|
||||
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
||||
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
|
||||
int max_lanes = intel_dp_max_lane_count(intel_encoder);
|
||||
|
||||
if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
|
||||
dev_priv->panel_fixed_mode) {
|
||||
if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay)
|
||||
return MODE_PANEL;
|
||||
|
||||
if (mode->vdisplay > dev_priv->panel_fixed_mode->vdisplay)
|
||||
return MODE_PANEL;
|
||||
}
|
||||
|
||||
/* only refuse the mode on non eDP since we have seen some wierd eDP panels
|
||||
which are outside spec tolerances but somehow work by magic */
|
||||
if (!IS_eDP(intel_encoder) &&
|
||||
|
@ -508,11 +523,37 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
|||
{
|
||||
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
||||
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int lane_count, clock;
|
||||
int max_lane_count = intel_dp_max_lane_count(intel_encoder);
|
||||
int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
|
||||
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
|
||||
|
||||
if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
|
||||
dev_priv->panel_fixed_mode) {
|
||||
struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
|
||||
|
||||
adjusted_mode->hdisplay = fixed_mode->hdisplay;
|
||||
adjusted_mode->hsync_start = fixed_mode->hsync_start;
|
||||
adjusted_mode->hsync_end = fixed_mode->hsync_end;
|
||||
adjusted_mode->htotal = fixed_mode->htotal;
|
||||
|
||||
adjusted_mode->vdisplay = fixed_mode->vdisplay;
|
||||
adjusted_mode->vsync_start = fixed_mode->vsync_start;
|
||||
adjusted_mode->vsync_end = fixed_mode->vsync_end;
|
||||
adjusted_mode->vtotal = fixed_mode->vtotal;
|
||||
|
||||
adjusted_mode->clock = fixed_mode->clock;
|
||||
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
|
||||
|
||||
/*
|
||||
* the mode->clock is used to calculate the Data&Link M/N
|
||||
* of the pipe. For the eDP the fixed clock should be used.
|
||||
*/
|
||||
mode->clock = dev_priv->panel_fixed_mode->clock;
|
||||
}
|
||||
|
||||
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
|
||||
for (clock = 0; clock <= max_clock; clock++) {
|
||||
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
|
||||
|
@ -531,7 +572,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_eDP(intel_encoder)) {
|
||||
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
|
||||
/* okay we failed just pick the highest */
|
||||
dp_priv->lane_count = max_lane_count;
|
||||
dp_priv->link_bw = bws[max_clock];
|
||||
|
@ -563,14 +604,14 @@ intel_reduce_ratio(uint32_t *num, uint32_t *den)
|
|||
}
|
||||
|
||||
static void
|
||||
intel_dp_compute_m_n(int bytes_per_pixel,
|
||||
intel_dp_compute_m_n(int bpp,
|
||||
int nlanes,
|
||||
int pixel_clock,
|
||||
int link_clock,
|
||||
struct intel_dp_m_n *m_n)
|
||||
{
|
||||
m_n->tu = 64;
|
||||
m_n->gmch_m = pixel_clock * bytes_per_pixel;
|
||||
m_n->gmch_m = (pixel_clock * bpp) >> 3;
|
||||
m_n->gmch_n = link_clock * nlanes;
|
||||
intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
|
||||
m_n->link_m = pixel_clock;
|
||||
|
@ -578,6 +619,28 @@ intel_dp_compute_m_n(int bytes_per_pixel,
|
|||
intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
|
||||
}
|
||||
|
||||
bool intel_pch_has_edp(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct drm_encoder *encoder;
|
||||
|
||||
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_dp_priv *dp_priv;
|
||||
|
||||
if (!encoder || encoder->crtc != crtc)
|
||||
continue;
|
||||
|
||||
intel_encoder = enc_to_intel_encoder(encoder);
|
||||
dp_priv = intel_encoder->dev_priv;
|
||||
|
||||
if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT)
|
||||
return dp_priv->is_pch_edp;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
|
@ -587,7 +650,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
|||
struct drm_encoder *encoder;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int lane_count = 4;
|
||||
int lane_count = 4, bpp = 24;
|
||||
struct intel_dp_m_n m_n;
|
||||
|
||||
/*
|
||||
|
@ -605,6 +668,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
|||
|
||||
if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
|
||||
lane_count = dp_priv->lane_count;
|
||||
if (IS_PCH_eDP(dp_priv))
|
||||
bpp = dev_priv->edp_bpp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -614,7 +679,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
|||
* the number of bytes_per_pixel post-LUT, which we always
|
||||
* set up for 8-bits of R/G/B, or 3 bytes total.
|
||||
*/
|
||||
intel_dp_compute_m_n(3, lane_count,
|
||||
intel_dp_compute_m_n(bpp, lane_count,
|
||||
mode->clock, adjusted_mode->clock, &m_n);
|
||||
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
|
@ -717,6 +782,51 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
|||
}
|
||||
}
|
||||
|
||||
static void ironlake_edp_panel_on (struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(5000);
|
||||
u32 pp, pp_status;
|
||||
|
||||
pp_status = I915_READ(PCH_PP_STATUS);
|
||||
if (pp_status & PP_ON)
|
||||
return;
|
||||
|
||||
pp = I915_READ(PCH_PP_CONTROL);
|
||||
pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
do {
|
||||
pp_status = I915_READ(PCH_PP_STATUS);
|
||||
} while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout));
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status);
|
||||
|
||||
pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD);
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
}
|
||||
|
||||
static void ironlake_edp_panel_off (struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(5000);
|
||||
u32 pp, pp_status;
|
||||
|
||||
pp = I915_READ(PCH_PP_CONTROL);
|
||||
pp &= ~POWER_TARGET_ON;
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
do {
|
||||
pp_status = I915_READ(PCH_PP_STATUS);
|
||||
} while ((pp_status & PP_ON) && !time_after(jiffies, timeout));
|
||||
|
||||
if (time_after(jiffies, timeout))
|
||||
DRM_DEBUG_KMS("panel off wait timed out\n");
|
||||
|
||||
/* Make sure VDD is enabled so DP AUX will work */
|
||||
pp |= EDP_FORCE_VDD;
|
||||
I915_WRITE(PCH_PP_CONTROL, pp);
|
||||
}
|
||||
|
||||
static void ironlake_edp_backlight_on (struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
@ -751,14 +861,18 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
|
|||
if (mode != DRM_MODE_DPMS_ON) {
|
||||
if (dp_reg & DP_PORT_EN) {
|
||||
intel_dp_link_down(intel_encoder, dp_priv->DP);
|
||||
if (IS_eDP(intel_encoder))
|
||||
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
|
||||
ironlake_edp_backlight_off(dev);
|
||||
ironlake_edp_panel_off(dev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(dp_reg & DP_PORT_EN)) {
|
||||
intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
|
||||
if (IS_eDP(intel_encoder))
|
||||
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
|
||||
ironlake_edp_panel_on(dev);
|
||||
ironlake_edp_backlight_on(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
dp_priv->dpms_mode = mode;
|
||||
|
@ -1291,17 +1405,32 @@ static int intel_dp_get_modes(struct drm_connector *connector)
|
|||
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
||||
struct drm_device *dev = intel_encoder->enc.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
|
||||
int ret;
|
||||
|
||||
/* We should parse the EDID data and find out if it has an audio sink
|
||||
*/
|
||||
|
||||
ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
|
||||
!dev_priv->panel_fixed_mode) {
|
||||
struct drm_display_mode *newmode;
|
||||
list_for_each_entry(newmode, &connector->probed_modes,
|
||||
head) {
|
||||
if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
dev_priv->panel_fixed_mode =
|
||||
drm_mode_duplicate(dev, newmode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* if eDP has no EDID, try to use fixed panel mode from VBT */
|
||||
if (IS_eDP(intel_encoder)) {
|
||||
if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
|
||||
if (dev_priv->panel_fixed_mode != NULL) {
|
||||
struct drm_display_mode *mode;
|
||||
mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
|
||||
|
@ -1386,6 +1515,26 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* check the VBT to see whether the eDP is on DP-D port */
|
||||
bool intel_dpd_is_edp(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct child_device_config *p_child;
|
||||
int i;
|
||||
|
||||
if (!dev_priv->child_dev_num)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < dev_priv->child_dev_num; i++) {
|
||||
p_child = dev_priv->child_dev + i;
|
||||
|
||||
if (p_child->dvo_port == PORT_IDPD &&
|
||||
p_child->device_type == DEVICE_TYPE_eDP)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
intel_dp_init(struct drm_device *dev, int output_reg)
|
||||
{
|
||||
|
@ -1395,6 +1544,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
|
|||
struct intel_connector *intel_connector;
|
||||
struct intel_dp_priv *dp_priv;
|
||||
const char *name = NULL;
|
||||
int type;
|
||||
|
||||
intel_encoder = kcalloc(sizeof(struct intel_encoder) +
|
||||
sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
|
||||
|
@ -1409,18 +1559,24 @@ intel_dp_init(struct drm_device *dev, int output_reg)
|
|||
|
||||
dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
|
||||
|
||||
if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D))
|
||||
if (intel_dpd_is_edp(dev))
|
||||
dp_priv->is_pch_edp = true;
|
||||
|
||||
if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
|
||||
type = DRM_MODE_CONNECTOR_eDP;
|
||||
intel_encoder->type = INTEL_OUTPUT_EDP;
|
||||
} else {
|
||||
type = DRM_MODE_CONNECTOR_DisplayPort;
|
||||
intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
|
||||
}
|
||||
|
||||
connector = &intel_connector->base;
|
||||
drm_connector_init(dev, connector, &intel_dp_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_DisplayPort);
|
||||
drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
|
||||
drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
|
||||
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
||||
if (output_reg == DP_A)
|
||||
intel_encoder->type = INTEL_OUTPUT_EDP;
|
||||
else
|
||||
intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
|
||||
|
||||
if (output_reg == DP_B || output_reg == PCH_DP_B)
|
||||
intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
|
||||
else if (output_reg == DP_C || output_reg == PCH_DP_C)
|
||||
|
@ -1479,7 +1635,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
|
|||
intel_encoder->ddc_bus = &dp_priv->adapter;
|
||||
intel_encoder->hot_plug = intel_dp_hot_plug;
|
||||
|
||||
if (output_reg == DP_A) {
|
||||
if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
|
||||
/* initialize panel mode from VBT if available for eDP */
|
||||
if (dev_priv->lfp_lvds_vbt_mode) {
|
||||
dev_priv->panel_fixed_mode =
|
||||
|
|
|
@ -143,8 +143,6 @@ struct intel_crtc {
|
|||
struct drm_crtc base;
|
||||
enum pipe pipe;
|
||||
enum plane plane;
|
||||
struct drm_gem_object *cursor_bo;
|
||||
uint32_t cursor_addr;
|
||||
u8 lut_r[256], lut_g[256], lut_b[256];
|
||||
int dpms_mode;
|
||||
bool busy; /* is scanout buffer being updated frequently? */
|
||||
|
@ -153,6 +151,12 @@ struct intel_crtc {
|
|||
struct intel_overlay *overlay;
|
||||
struct intel_unpin_work *unpin_work;
|
||||
int fdi_lanes;
|
||||
|
||||
struct drm_gem_object *cursor_bo;
|
||||
uint32_t cursor_addr;
|
||||
int16_t cursor_x, cursor_y;
|
||||
int16_t cursor_width, cursor_height;
|
||||
bool cursor_visble;
|
||||
};
|
||||
|
||||
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
|
||||
|
@ -179,6 +183,8 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
|
|||
void
|
||||
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
extern bool intel_pch_has_edp(struct drm_crtc *crtc);
|
||||
extern bool intel_dpd_is_edp(struct drm_device *dev);
|
||||
extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
|
||||
|
||||
|
||||
|
@ -215,6 +221,9 @@ extern void intel_init_clock_gating(struct drm_device *dev);
|
|||
extern void ironlake_enable_drps(struct drm_device *dev);
|
||||
extern void ironlake_disable_drps(struct drm_device *dev);
|
||||
|
||||
extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
||||
struct drm_gem_object *obj);
|
||||
|
||||
extern int intel_framebuffer_init(struct drm_device *dev,
|
||||
struct intel_framebuffer *ifb,
|
||||
struct drm_mode_fb_cmd *mode_cmd,
|
||||
|
|
|
@ -98,7 +98,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
|||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
ret = i915_gem_object_pin(fbo, 64*1024);
|
||||
ret = intel_pin_and_fence_fb_obj(dev, fbo);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to pin fb: %d\n", ret);
|
||||
goto out_unref;
|
||||
|
@ -236,7 +236,7 @@ int intel_fbdev_destroy(struct drm_device *dev,
|
|||
|
||||
drm_framebuffer_cleanup(&ifb->base);
|
||||
if (ifb->obj)
|
||||
drm_gem_object_unreference_unlocked(ifb->obj);
|
||||
drm_gem_object_unreference(ifb->obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -54,10 +54,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
|
|||
struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
|
||||
u32 sdvox;
|
||||
|
||||
sdvox = SDVO_ENCODING_HDMI |
|
||||
SDVO_BORDER_ENABLE |
|
||||
SDVO_VSYNC_ACTIVE_HIGH |
|
||||
SDVO_HSYNC_ACTIVE_HIGH;
|
||||
sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE;
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
|
||||
|
||||
if (hdmi_priv->has_hdmi_sink) {
|
||||
sdvox |= SDVO_AUDIO_ENABLE;
|
||||
|
|
|
@ -156,31 +156,73 @@ static int intel_lvds_mode_valid(struct drm_connector *connector,
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
centre_horizontally(struct drm_display_mode *mode,
|
||||
int width)
|
||||
{
|
||||
u32 border, sync_pos, blank_width, sync_width;
|
||||
|
||||
/* keep the hsync and hblank widths constant */
|
||||
sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
|
||||
blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
|
||||
sync_pos = (blank_width - sync_width + 1) / 2;
|
||||
|
||||
border = (mode->hdisplay - width + 1) / 2;
|
||||
border += border & 1; /* make the border even */
|
||||
|
||||
mode->crtc_hdisplay = width;
|
||||
mode->crtc_hblank_start = width + border;
|
||||
mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
|
||||
|
||||
mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
|
||||
mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
|
||||
}
|
||||
|
||||
static void
|
||||
centre_vertically(struct drm_display_mode *mode,
|
||||
int height)
|
||||
{
|
||||
u32 border, sync_pos, blank_width, sync_width;
|
||||
|
||||
/* keep the vsync and vblank widths constant */
|
||||
sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
|
||||
blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
|
||||
sync_pos = (blank_width - sync_width + 1) / 2;
|
||||
|
||||
border = (mode->vdisplay - height + 1) / 2;
|
||||
|
||||
mode->crtc_vdisplay = height;
|
||||
mode->crtc_vblank_start = height + border;
|
||||
mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width;
|
||||
|
||||
mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
|
||||
mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
|
||||
}
|
||||
|
||||
static inline u32 panel_fitter_scaling(u32 source, u32 target)
|
||||
{
|
||||
/*
|
||||
* Floating point operation is not supported. So the FACTOR
|
||||
* is defined, which can avoid the floating point computation
|
||||
* when calculating the panel ratio.
|
||||
*/
|
||||
#define ACCURACY 12
|
||||
#define FACTOR (1 << ACCURACY)
|
||||
u32 ratio = source * FACTOR / target;
|
||||
return (FACTOR * ratio + FACTOR/2) / FACTOR;
|
||||
}
|
||||
|
||||
static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
/*
|
||||
* float point operation is not supported . So the PANEL_RATIO_FACTOR
|
||||
* is defined, which can avoid the float point computation when
|
||||
* calculating the panel ratio.
|
||||
*/
|
||||
#define PANEL_RATIO_FACTOR 8192
|
||||
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);
|
||||
struct drm_encoder *tmp_encoder;
|
||||
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
||||
struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
|
||||
u32 pfit_control = 0, pfit_pgm_ratios = 0;
|
||||
int left_border = 0, right_border = 0, top_border = 0;
|
||||
int bottom_border = 0;
|
||||
bool border = 0;
|
||||
int panel_ratio, desired_ratio, vert_scale, horiz_scale;
|
||||
int horiz_ratio, vert_ratio;
|
||||
u32 hsync_width, vsync_width;
|
||||
u32 hblank_width, vblank_width;
|
||||
u32 hsync_pos, vsync_pos;
|
||||
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
|
||||
|
||||
/* Should never happen!! */
|
||||
if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
|
||||
|
@ -200,27 +242,25 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
|||
if (dev_priv->panel_fixed_mode == NULL)
|
||||
return true;
|
||||
/*
|
||||
* If we have timings from the BIOS for the panel, put them in
|
||||
* We have timings from the BIOS for the panel, put them in
|
||||
* to the adjusted mode. The CRTC will be set up for this mode,
|
||||
* with the panel scaling set up to source from the H/VDisplay
|
||||
* of the original mode.
|
||||
*/
|
||||
if (dev_priv->panel_fixed_mode != NULL) {
|
||||
adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
|
||||
adjusted_mode->hsync_start =
|
||||
dev_priv->panel_fixed_mode->hsync_start;
|
||||
adjusted_mode->hsync_end =
|
||||
dev_priv->panel_fixed_mode->hsync_end;
|
||||
adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
|
||||
adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
|
||||
adjusted_mode->vsync_start =
|
||||
dev_priv->panel_fixed_mode->vsync_start;
|
||||
adjusted_mode->vsync_end =
|
||||
dev_priv->panel_fixed_mode->vsync_end;
|
||||
adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
|
||||
adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
|
||||
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
|
||||
}
|
||||
adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
|
||||
adjusted_mode->hsync_start =
|
||||
dev_priv->panel_fixed_mode->hsync_start;
|
||||
adjusted_mode->hsync_end =
|
||||
dev_priv->panel_fixed_mode->hsync_end;
|
||||
adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
|
||||
adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
|
||||
adjusted_mode->vsync_start =
|
||||
dev_priv->panel_fixed_mode->vsync_start;
|
||||
adjusted_mode->vsync_end =
|
||||
dev_priv->panel_fixed_mode->vsync_end;
|
||||
adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
|
||||
adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
|
||||
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
|
||||
|
||||
/* Make sure pre-965s set dither correctly */
|
||||
if (!IS_I965G(dev)) {
|
||||
|
@ -230,11 +270,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
|||
|
||||
/* Native modes don't need fitting */
|
||||
if (adjusted_mode->hdisplay == mode->hdisplay &&
|
||||
adjusted_mode->vdisplay == mode->vdisplay) {
|
||||
pfit_pgm_ratios = 0;
|
||||
border = 0;
|
||||
adjusted_mode->vdisplay == mode->vdisplay)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* full screen scale for now */
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
|
@ -242,25 +279,9 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
|||
|
||||
/* 965+ wants fuzzy fitting */
|
||||
if (IS_I965G(dev))
|
||||
pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) |
|
||||
PFIT_FILTER_FUZZY;
|
||||
pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
|
||||
PFIT_FILTER_FUZZY);
|
||||
|
||||
hsync_width = adjusted_mode->crtc_hsync_end -
|
||||
adjusted_mode->crtc_hsync_start;
|
||||
vsync_width = adjusted_mode->crtc_vsync_end -
|
||||
adjusted_mode->crtc_vsync_start;
|
||||
hblank_width = adjusted_mode->crtc_hblank_end -
|
||||
adjusted_mode->crtc_hblank_start;
|
||||
vblank_width = adjusted_mode->crtc_vblank_end -
|
||||
adjusted_mode->crtc_vblank_start;
|
||||
/*
|
||||
* Deal with panel fitting options. Figure out how to stretch the
|
||||
* image based on its aspect ratio & the current panel fitting mode.
|
||||
*/
|
||||
panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR /
|
||||
adjusted_mode->vdisplay;
|
||||
desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR /
|
||||
mode->vdisplay;
|
||||
/*
|
||||
* Enable automatic panel scaling for non-native modes so that they fill
|
||||
* the screen. Should be enabled before the pipe is enabled, according
|
||||
|
@ -278,170 +299,63 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
|||
* For centered modes, we have to calculate border widths &
|
||||
* heights and modify the values programmed into the CRTC.
|
||||
*/
|
||||
left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2;
|
||||
right_border = left_border;
|
||||
if (mode->hdisplay & 1)
|
||||
right_border++;
|
||||
top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2;
|
||||
bottom_border = top_border;
|
||||
if (mode->vdisplay & 1)
|
||||
bottom_border++;
|
||||
/* Set active & border values */
|
||||
adjusted_mode->crtc_hdisplay = mode->hdisplay;
|
||||
/* Keep the boder be even */
|
||||
if (right_border & 1)
|
||||
right_border++;
|
||||
/* use the border directly instead of border minuse one */
|
||||
adjusted_mode->crtc_hblank_start = mode->hdisplay +
|
||||
right_border;
|
||||
/* keep the blank width constant */
|
||||
adjusted_mode->crtc_hblank_end =
|
||||
adjusted_mode->crtc_hblank_start + hblank_width;
|
||||
/* get the hsync pos relative to hblank start */
|
||||
hsync_pos = (hblank_width - hsync_width) / 2;
|
||||
/* keep the hsync pos be even */
|
||||
if (hsync_pos & 1)
|
||||
hsync_pos++;
|
||||
adjusted_mode->crtc_hsync_start =
|
||||
adjusted_mode->crtc_hblank_start + hsync_pos;
|
||||
/* keep the hsync width constant */
|
||||
adjusted_mode->crtc_hsync_end =
|
||||
adjusted_mode->crtc_hsync_start + hsync_width;
|
||||
adjusted_mode->crtc_vdisplay = mode->vdisplay;
|
||||
/* use the border instead of border minus one */
|
||||
adjusted_mode->crtc_vblank_start = mode->vdisplay +
|
||||
bottom_border;
|
||||
/* keep the vblank width constant */
|
||||
adjusted_mode->crtc_vblank_end =
|
||||
adjusted_mode->crtc_vblank_start + vblank_width;
|
||||
/* get the vsync start postion relative to vblank start */
|
||||
vsync_pos = (vblank_width - vsync_width) / 2;
|
||||
adjusted_mode->crtc_vsync_start =
|
||||
adjusted_mode->crtc_vblank_start + vsync_pos;
|
||||
/* keep the vsync width constant */
|
||||
adjusted_mode->crtc_vsync_end =
|
||||
adjusted_mode->crtc_vsync_start + vsync_width;
|
||||
border = 1;
|
||||
centre_horizontally(adjusted_mode, mode->hdisplay);
|
||||
centre_vertically(adjusted_mode, mode->vdisplay);
|
||||
border = LVDS_BORDER_ENABLE;
|
||||
break;
|
||||
|
||||
case DRM_MODE_SCALE_ASPECT:
|
||||
/* Scale but preserve the spect ratio */
|
||||
pfit_control |= PFIT_ENABLE;
|
||||
/* Scale but preserve the aspect ratio */
|
||||
if (IS_I965G(dev)) {
|
||||
u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
|
||||
u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
|
||||
|
||||
pfit_control |= PFIT_ENABLE;
|
||||
/* 965+ is easy, it does everything in hw */
|
||||
if (panel_ratio > desired_ratio)
|
||||
if (scaled_width > scaled_height)
|
||||
pfit_control |= PFIT_SCALING_PILLAR;
|
||||
else if (panel_ratio < desired_ratio)
|
||||
else if (scaled_width < scaled_height)
|
||||
pfit_control |= PFIT_SCALING_LETTER;
|
||||
else
|
||||
pfit_control |= PFIT_SCALING_AUTO;
|
||||
} else {
|
||||
u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
|
||||
u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
|
||||
/*
|
||||
* For earlier chips we have to calculate the scaling
|
||||
* ratio by hand and program it into the
|
||||
* PFIT_PGM_RATIO register
|
||||
*/
|
||||
u32 horiz_bits, vert_bits, bits = 12;
|
||||
horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/
|
||||
adjusted_mode->hdisplay;
|
||||
vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/
|
||||
adjusted_mode->vdisplay;
|
||||
horiz_scale = adjusted_mode->hdisplay *
|
||||
PANEL_RATIO_FACTOR / mode->hdisplay;
|
||||
vert_scale = adjusted_mode->vdisplay *
|
||||
PANEL_RATIO_FACTOR / mode->vdisplay;
|
||||
if (scaled_width > scaled_height) { /* pillar */
|
||||
centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay);
|
||||
|
||||
/* retain aspect ratio */
|
||||
if (panel_ratio > desired_ratio) { /* Pillar */
|
||||
u32 scaled_width;
|
||||
scaled_width = mode->hdisplay * vert_scale /
|
||||
PANEL_RATIO_FACTOR;
|
||||
horiz_ratio = vert_ratio;
|
||||
pfit_control |= (VERT_AUTO_SCALE |
|
||||
border = LVDS_BORDER_ENABLE;
|
||||
if (mode->vdisplay != adjusted_mode->vdisplay) {
|
||||
u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay);
|
||||
pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
|
||||
bits << PFIT_VERT_SCALE_SHIFT);
|
||||
pfit_control |= (PFIT_ENABLE |
|
||||
VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR);
|
||||
}
|
||||
} else if (scaled_width < scaled_height) { /* letter */
|
||||
centre_vertically(adjusted_mode, scaled_width / mode->hdisplay);
|
||||
|
||||
border = LVDS_BORDER_ENABLE;
|
||||
if (mode->hdisplay != adjusted_mode->hdisplay) {
|
||||
u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay);
|
||||
pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
|
||||
bits << PFIT_VERT_SCALE_SHIFT);
|
||||
pfit_control |= (PFIT_ENABLE |
|
||||
VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR);
|
||||
}
|
||||
} else
|
||||
/* Aspects match, Let hw scale both directions */
|
||||
pfit_control |= (PFIT_ENABLE |
|
||||
VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR);
|
||||
/* Pillar will have left/right borders */
|
||||
left_border = (adjusted_mode->hdisplay -
|
||||
scaled_width) / 2;
|
||||
right_border = left_border;
|
||||
if (mode->hdisplay & 1) /* odd resolutions */
|
||||
right_border++;
|
||||
/* keep the border be even */
|
||||
if (right_border & 1)
|
||||
right_border++;
|
||||
adjusted_mode->crtc_hdisplay = scaled_width;
|
||||
/* use border instead of border minus one */
|
||||
adjusted_mode->crtc_hblank_start =
|
||||
scaled_width + right_border;
|
||||
/* keep the hblank width constant */
|
||||
adjusted_mode->crtc_hblank_end =
|
||||
adjusted_mode->crtc_hblank_start +
|
||||
hblank_width;
|
||||
/*
|
||||
* get the hsync start pos relative to
|
||||
* hblank start
|
||||
*/
|
||||
hsync_pos = (hblank_width - hsync_width) / 2;
|
||||
/* keep the hsync_pos be even */
|
||||
if (hsync_pos & 1)
|
||||
hsync_pos++;
|
||||
adjusted_mode->crtc_hsync_start =
|
||||
adjusted_mode->crtc_hblank_start +
|
||||
hsync_pos;
|
||||
/* keept hsync width constant */
|
||||
adjusted_mode->crtc_hsync_end =
|
||||
adjusted_mode->crtc_hsync_start +
|
||||
hsync_width;
|
||||
border = 1;
|
||||
} else if (panel_ratio < desired_ratio) { /* letter */
|
||||
u32 scaled_height = mode->vdisplay *
|
||||
horiz_scale / PANEL_RATIO_FACTOR;
|
||||
vert_ratio = horiz_ratio;
|
||||
pfit_control |= (HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR);
|
||||
/* Letterbox will have top/bottom border */
|
||||
top_border = (adjusted_mode->vdisplay -
|
||||
scaled_height) / 2;
|
||||
bottom_border = top_border;
|
||||
if (mode->vdisplay & 1)
|
||||
bottom_border++;
|
||||
adjusted_mode->crtc_vdisplay = scaled_height;
|
||||
/* use border instead of border minus one */
|
||||
adjusted_mode->crtc_vblank_start =
|
||||
scaled_height + bottom_border;
|
||||
/* keep the vblank width constant */
|
||||
adjusted_mode->crtc_vblank_end =
|
||||
adjusted_mode->crtc_vblank_start +
|
||||
vblank_width;
|
||||
/*
|
||||
* get the vsync start pos relative to
|
||||
* vblank start
|
||||
*/
|
||||
vsync_pos = (vblank_width - vsync_width) / 2;
|
||||
adjusted_mode->crtc_vsync_start =
|
||||
adjusted_mode->crtc_vblank_start +
|
||||
vsync_pos;
|
||||
/* keep the vsync width constant */
|
||||
adjusted_mode->crtc_vsync_end =
|
||||
adjusted_mode->crtc_vsync_start +
|
||||
vsync_width;
|
||||
border = 1;
|
||||
} else {
|
||||
/* Aspects match, Let hw scale both directions */
|
||||
pfit_control |= (VERT_AUTO_SCALE |
|
||||
HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR);
|
||||
}
|
||||
horiz_bits = (1 << bits) * horiz_ratio /
|
||||
PANEL_RATIO_FACTOR;
|
||||
vert_bits = (1 << bits) * vert_ratio /
|
||||
PANEL_RATIO_FACTOR;
|
||||
pfit_pgm_ratios =
|
||||
((vert_bits << PFIT_VERT_SCALE_SHIFT) &
|
||||
PFIT_VERT_SCALE_MASK) |
|
||||
((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) &
|
||||
PFIT_HORIZ_SCALE_MASK);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -458,6 +372,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
|||
VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -465,14 +380,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
|||
out:
|
||||
lvds_priv->pfit_control = pfit_control;
|
||||
lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios;
|
||||
/*
|
||||
* When there exists the border, it means that the LVDS_BORDR
|
||||
* should be enabled.
|
||||
*/
|
||||
if (border)
|
||||
dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE;
|
||||
else
|
||||
dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE);
|
||||
dev_priv->lvds_border_bits = border;
|
||||
|
||||
/*
|
||||
* XXX: It would be nice to support lower refresh rates on the
|
||||
* panels to reduce power consumption, and perhaps match the
|
||||
|
@ -599,6 +508,26 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
|
||||
{
|
||||
DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The GPU hangs up on these systems if modeset is performed on LID open */
|
||||
static const struct dmi_system_id intel_no_modeset_on_lid[] = {
|
||||
{
|
||||
.callback = intel_no_modeset_on_lid_dmi_callback,
|
||||
.ident = "Toshiba Tecra A11",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
|
||||
},
|
||||
},
|
||||
|
||||
{ } /* terminating entry */
|
||||
};
|
||||
|
||||
/*
|
||||
* Lid events. Note the use of 'modeset_on_lid':
|
||||
* - we set it on lid close, and reset it on open
|
||||
|
@ -622,6 +551,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
|||
*/
|
||||
if (connector)
|
||||
connector->status = connector->funcs->detect(connector);
|
||||
/* Don't force modeset on machines where it causes a GPU lockup */
|
||||
if (dmi_check_system(intel_no_modeset_on_lid))
|
||||
return NOTIFY_OK;
|
||||
if (!acpi_lid_open()) {
|
||||
dev_priv->modeset_on_lid = 1;
|
||||
return NOTIFY_OK;
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
#define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */
|
||||
#define OCMD_TVSYNCFLIP_PARITY (0x1<<9)
|
||||
#define OCMD_TVSYNCFLIP_ENABLE (0x1<<7)
|
||||
#define OCMD_BUF_TYPE_MASK (Ox1<<5)
|
||||
#define OCMD_BUF_TYPE_MASK (0x1<<5)
|
||||
#define OCMD_BUF_TYPE_FRAME (0x0<<5)
|
||||
#define OCMD_BUF_TYPE_FIELD (0x1<<5)
|
||||
#define OCMD_TEST_MODE (0x1<<4)
|
||||
|
@ -958,7 +958,7 @@ static int check_overlay_src(struct drm_device *dev,
|
|||
|| rec->src_width < N_HORIZ_Y_TAPS*4)
|
||||
return -EINVAL;
|
||||
|
||||
/* check alingment constrains */
|
||||
/* check alignment constraints */
|
||||
switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
|
||||
case I915_OVERLAY_RGB:
|
||||
/* not implemented */
|
||||
|
@ -990,7 +990,10 @@ static int check_overlay_src(struct drm_device *dev,
|
|||
return -EINVAL;
|
||||
|
||||
/* stride checking */
|
||||
stride_mask = 63;
|
||||
if (IS_I830(dev) || IS_845G(dev))
|
||||
stride_mask = 255;
|
||||
else
|
||||
stride_mask = 63;
|
||||
|
||||
if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -1237,9 +1237,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
|
|||
|
||||
/* Set the SDVO control regs. */
|
||||
if (IS_I965G(dev)) {
|
||||
sdvox |= SDVO_BORDER_ENABLE |
|
||||
SDVO_VSYNC_ACTIVE_HIGH |
|
||||
SDVO_HSYNC_ACTIVE_HIGH;
|
||||
sdvox |= SDVO_BORDER_ENABLE;
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
|
||||
} else {
|
||||
sdvox |= I915_READ(sdvo_priv->sdvo_reg);
|
||||
switch (sdvo_priv->sdvo_reg) {
|
||||
|
|
|
@ -476,7 +476,7 @@ static const struct tv_mode tv_modes[] = {
|
|||
.vi_end_f1 = 20, .vi_end_f2 = 21,
|
||||
.nbr_end = 240,
|
||||
|
||||
.burst_ena = 8,
|
||||
.burst_ena = true,
|
||||
.hburst_start = 72, .hburst_len = 34,
|
||||
.vburst_start_f1 = 9, .vburst_end_f1 = 240,
|
||||
.vburst_start_f2 = 10, .vburst_end_f2 = 240,
|
||||
|
@ -896,8 +896,6 @@ static const struct tv_mode tv_modes[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0])
|
||||
|
||||
static void
|
||||
intel_tv_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
|
@ -1512,7 +1510,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
|
|||
tv_priv->margin[TV_MARGIN_BOTTOM] = val;
|
||||
changed = true;
|
||||
} else if (property == dev->mode_config.tv_mode_property) {
|
||||
if (val >= NUM_TV_MODES) {
|
||||
if (val >= ARRAY_SIZE(tv_modes)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1693,13 +1691,13 @@ intel_tv_init(struct drm_device *dev)
|
|||
connector->doublescan_allowed = false;
|
||||
|
||||
/* Create TV properties then attach current values */
|
||||
tv_format_names = kmalloc(sizeof(char *) * NUM_TV_MODES,
|
||||
tv_format_names = kmalloc(sizeof(char *) * ARRAY_SIZE(tv_modes),
|
||||
GFP_KERNEL);
|
||||
if (!tv_format_names)
|
||||
goto out;
|
||||
for (i = 0; i < NUM_TV_MODES; i++)
|
||||
for (i = 0; i < ARRAY_SIZE(tv_modes); i++)
|
||||
tv_format_names[i] = tv_modes[i].name;
|
||||
drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
|
||||
drm_mode_create_tv_properties(dev, ARRAY_SIZE(tv_modes), tv_format_names);
|
||||
|
||||
drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
|
||||
initial_mode);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue