mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 16:24:13 +08:00
Merge intel drm-intel-next branch
Merge remote branch 'anholt/drm-intel-next' of ../anholt-2.6 into drm-next Conflicts: drivers/gpu/drm/i915/intel_display.c drivers/gpu/drm/i915/intel_drv.h drivers/gpu/drm/i915/intel_sdvo.c
This commit is contained in:
commit
11670d3c93
@ -123,6 +123,9 @@ available from the same CVS repository.
|
||||
There are user and developer mailing lists available through the v9fs project
|
||||
on sourceforge (http://sourceforge.net/projects/v9fs).
|
||||
|
||||
A stand-alone version of the module (which should build for any 2.6 kernel)
|
||||
is available via (http://github.com/ericvh/9p-sac/tree/master)
|
||||
|
||||
News and other information is maintained on SWiK (http://swik.net/v9fs).
|
||||
|
||||
Bug reports may be issued through the kernel.org bugzilla
|
||||
|
@ -2239,8 +2239,7 @@ S: Maintained
|
||||
F: drivers/media/video/gspca/pac207.c
|
||||
|
||||
GSPCA SN9C20X SUBDRIVER
|
||||
P: Brian Johnson
|
||||
M: brijohn@gmail.com
|
||||
M: Brian Johnson <brijohn@gmail.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
|
||||
S: Maintained
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 31
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc8
|
||||
NAME = Man-Eating Seals of Antiquity
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -629,7 +629,7 @@ CONFIG_SCSI_LOWLEVEL=y
|
||||
CONFIG_ATA=y
|
||||
# CONFIG_ATA_NONSTANDARD is not set
|
||||
CONFIG_SATA_PMP=y
|
||||
# CONFIG_SATA_AHCI is not set
|
||||
CONFIG_SATA_AHCI=y
|
||||
# CONFIG_SATA_SIL24 is not set
|
||||
CONFIG_ATA_SFF=y
|
||||
# CONFIG_SATA_SVW is not set
|
||||
|
@ -206,6 +206,15 @@ static void __init qnap_ts219_init(void)
|
||||
|
||||
}
|
||||
|
||||
static int __init ts219_pci_init(void)
|
||||
{
|
||||
if (machine_is_ts219())
|
||||
kirkwood_pcie_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(ts219_pci_init);
|
||||
|
||||
MACHINE_START(TS219, "QNAP TS-119/TS-219")
|
||||
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
|
||||
.phys_io = KIRKWOOD_REGS_PHYS_BASE,
|
||||
|
@ -11,6 +11,8 @@
|
||||
#ifndef __PLAT_GPIO_H
|
||||
#define __PLAT_GPIO_H
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
/*
|
||||
* GENERIC_GPIO primitives.
|
||||
*/
|
||||
|
@ -72,6 +72,10 @@ static struct ads7846_platform_data ads7843_data = {
|
||||
.debounce_max = 20,
|
||||
.debounce_rep = 4,
|
||||
.debounce_tol = 5,
|
||||
|
||||
.keep_vref_on = true,
|
||||
.settle_delay_usecs = 500,
|
||||
.penirq_recheck_delay_usecs = 100,
|
||||
};
|
||||
|
||||
static struct spi_board_info __initdata spi1_board_info[] = {
|
||||
|
@ -24,8 +24,8 @@ memcpy:
|
||||
brne 1f
|
||||
|
||||
/* At this point, "from" is word-aligned */
|
||||
2: sub r10, 4
|
||||
mov r9, r12
|
||||
2: mov r9, r12
|
||||
5: sub r10, 4
|
||||
brlt 4f
|
||||
|
||||
3: ld.w r8, r11++
|
||||
@ -49,6 +49,7 @@ memcpy:
|
||||
|
||||
/* Handle unaligned "from" pointer */
|
||||
1: sub r10, 4
|
||||
movlt r9, r12
|
||||
brlt 4b
|
||||
add r10, r9
|
||||
lsl r9, 2
|
||||
@ -59,4 +60,13 @@ memcpy:
|
||||
st.b r12++, r8
|
||||
ld.ub r8, r11++
|
||||
st.b r12++, r8
|
||||
rjmp 2b
|
||||
mov r8, r12
|
||||
add pc, pc, r9
|
||||
sub r8, 1
|
||||
nop
|
||||
sub r8, 1
|
||||
nop
|
||||
sub r8, 1
|
||||
nop
|
||||
mov r9, r8
|
||||
rjmp 5b
|
||||
|
@ -574,10 +574,11 @@ static int a2000_hwclk(int op, struct rtc_time *t)
|
||||
|
||||
tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD;
|
||||
|
||||
while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
|
||||
while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) {
|
||||
tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
|
||||
udelay(70);
|
||||
tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (!cnt)
|
||||
@ -649,10 +650,11 @@ static int amiga_set_clock_mmss(unsigned long nowtime)
|
||||
|
||||
tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
|
||||
|
||||
while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
|
||||
while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) {
|
||||
tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
|
||||
udelay(70);
|
||||
tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (!cnt)
|
||||
|
@ -36,12 +36,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addres
|
||||
return NULL;
|
||||
|
||||
pte = kmap(page);
|
||||
if (pte) {
|
||||
__flush_page_to_ram(pte);
|
||||
flush_tlb_kernel_page(pte);
|
||||
nocache_page(pte);
|
||||
}
|
||||
kunmap(pte);
|
||||
__flush_page_to_ram(pte);
|
||||
flush_tlb_kernel_page(pte);
|
||||
nocache_page(pte);
|
||||
kunmap(page);
|
||||
pgtable_page_ctor(page);
|
||||
return page;
|
||||
}
|
||||
|
@ -135,8 +135,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
/*
|
||||
* Macro to mark a page protection value as "uncacheable".
|
||||
*/
|
||||
@ -154,6 +152,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
|
||||
? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
|
||||
: (prot)))
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
|
@ -334,10 +334,12 @@
|
||||
#define __NR_inotify_init1 328
|
||||
#define __NR_preadv 329
|
||||
#define __NR_pwritev 330
|
||||
#define __NR_rt_tgsigqueueinfo 331
|
||||
#define __NR_perf_counter_open 332
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define NR_syscalls 331
|
||||
#define NR_syscalls 333
|
||||
|
||||
#define __ARCH_WANT_IPC_PARSE_VERSION
|
||||
#define __ARCH_WANT_OLD_READDIR
|
||||
|
@ -755,4 +755,6 @@ sys_call_table:
|
||||
.long sys_inotify_init1
|
||||
.long sys_preadv
|
||||
.long sys_pwritev /* 330 */
|
||||
.long sys_rt_tgsigqueueinfo
|
||||
.long sys_perf_counter_open
|
||||
|
||||
|
@ -349,6 +349,8 @@ ENTRY(sys_call_table)
|
||||
.long sys_inotify_init1
|
||||
.long sys_preadv
|
||||
.long sys_pwritev /* 330 */
|
||||
.long sys_rt_tgsigqueueinfo
|
||||
.long sys_perf_counter_open
|
||||
|
||||
.rept NR_syscalls-(.-sys_call_table)/4
|
||||
.long sys_ni_syscall
|
||||
|
@ -532,7 +532,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
|
||||
/* Kill the user process later */
|
||||
regs->iaoq[0] = 0 | 3;
|
||||
regs->iaoq[1] = regs->iaoq[0] + 4;
|
||||
regs->iasq[0] = regs->iasq[0] = regs->sr[7];
|
||||
regs->iasq[0] = regs->iasq[1] = regs->sr[7];
|
||||
regs->gr[0] &= ~PSW_B;
|
||||
return;
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.30-rc5
|
||||
# Fri May 15 10:37:00 2009
|
||||
# Linux kernel version: 2.6.31-rc7
|
||||
# Mon Aug 24 17:38:50 2009
|
||||
#
|
||||
CONFIG_PPC64=y
|
||||
|
||||
#
|
||||
# Processor support
|
||||
#
|
||||
CONFIG_PPC_BOOK3S_64=y
|
||||
CONFIG_PPC_BOOK3S=y
|
||||
# CONFIG_POWER4_ONLY is not set
|
||||
CONFIG_POWER3=y
|
||||
@ -20,6 +21,7 @@ CONFIG_PPC_STD_MMU=y
|
||||
CONFIG_PPC_STD_MMU_64=y
|
||||
CONFIG_PPC_MM_SLICES=y
|
||||
CONFIG_VIRT_CPU_ACCOUNTING=y
|
||||
CONFIG_PPC_HAVE_PMU_SUPPORT=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_NR_CPUS=2
|
||||
CONFIG_64BIT=y
|
||||
@ -31,6 +33,7 @@ CONFIG_GENERIC_TIME=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
|
||||
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
|
||||
CONFIG_IRQ_PER_CPU=y
|
||||
CONFIG_STACKTRACE_SUPPORT=y
|
||||
@ -41,7 +44,6 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||
CONFIG_ARCH_HAS_ILOG2_U32=y
|
||||
CONFIG_ARCH_HAS_ILOG2_U64=y
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||
CONFIG_ARCH_NO_VIRT_TO_BUS=y
|
||||
CONFIG_PPC=y
|
||||
@ -62,6 +64,7 @@ CONFIG_DTC=y
|
||||
# CONFIG_PPC_DCR_MMIO is not set
|
||||
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
CONFIG_CONSTRUCTORS=y
|
||||
|
||||
#
|
||||
# General setup
|
||||
@ -113,7 +116,6 @@ CONFIG_SYSCTL_SYSCALL=y
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_KALLSYMS_EXTRA_PASS=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_HOTPLUG=y
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
@ -126,7 +128,14 @@ CONFIG_TIMERFD=y
|
||||
CONFIG_EVENTFD=y
|
||||
CONFIG_SHMEM=y
|
||||
CONFIG_AIO=y
|
||||
CONFIG_HAVE_PERF_COUNTERS=y
|
||||
|
||||
#
|
||||
# Performance Counters
|
||||
#
|
||||
# CONFIG_PERF_COUNTERS is not set
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_SLAB=y
|
||||
# CONFIG_SLUB is not set
|
||||
@ -145,6 +154,11 @@ CONFIG_HAVE_KRETPROBES=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
CONFIG_HAVE_DMA_ATTRS=y
|
||||
CONFIG_USE_GENERIC_SMP_HELPERS=y
|
||||
|
||||
#
|
||||
# GCOV-based kernel profiling
|
||||
#
|
||||
# CONFIG_GCOV_KERNEL is not set
|
||||
# CONFIG_SLOW_WORK is not set
|
||||
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
|
||||
CONFIG_SLABINFO=y
|
||||
@ -210,7 +224,7 @@ CONFIG_PPC_CELL=y
|
||||
#
|
||||
# Cell Broadband Engine options
|
||||
#
|
||||
CONFIG_SPU_FS=y
|
||||
CONFIG_SPU_FS=m
|
||||
CONFIG_SPU_FS_64K_LS=y
|
||||
# CONFIG_SPU_TRACE is not set
|
||||
CONFIG_SPU_BASE=y
|
||||
@ -255,6 +269,7 @@ CONFIG_BINFMT_MISC=y
|
||||
CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
|
||||
# CONFIG_IOMMU_VMERGE is not set
|
||||
CONFIG_IOMMU_HELPER=y
|
||||
# CONFIG_SWIOTLB is not set
|
||||
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
|
||||
CONFIG_ARCH_HAS_WALK_MEMORY=y
|
||||
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
|
||||
@ -285,9 +300,9 @@ CONFIG_MIGRATION=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_ZONE_DMA_FLAG=1
|
||||
CONFIG_BOUNCE=y
|
||||
CONFIG_UNEVICTABLE_LRU=y
|
||||
CONFIG_HAVE_MLOCK=y
|
||||
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
|
||||
CONFIG_ARCH_MEMORY_PROBE=y
|
||||
CONFIG_PPC_HAS_HASH_64K=y
|
||||
CONFIG_PPC_4K_PAGES=y
|
||||
@ -399,6 +414,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
|
||||
# CONFIG_ECONET is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
# CONFIG_PHONET is not set
|
||||
# CONFIG_IEEE802154 is not set
|
||||
# CONFIG_NET_SCHED is not set
|
||||
# CONFIG_DCB is not set
|
||||
|
||||
@ -433,11 +449,14 @@ CONFIG_BT_HCIBTUSB=m
|
||||
CONFIG_WIRELESS=y
|
||||
CONFIG_CFG80211=m
|
||||
# CONFIG_CFG80211_REG_DEBUG is not set
|
||||
# CONFIG_CFG80211_DEBUGFS is not set
|
||||
# CONFIG_WIRELESS_OLD_REGULATORY is not set
|
||||
CONFIG_WIRELESS_EXT=y
|
||||
# CONFIG_WIRELESS_EXT_SYSFS is not set
|
||||
# CONFIG_LIB80211 is not set
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_DEFAULT_PS=y
|
||||
CONFIG_MAC80211_DEFAULT_PS_VALUE=1
|
||||
|
||||
#
|
||||
# Rate control algorithm selection
|
||||
@ -447,7 +466,6 @@ CONFIG_MAC80211_RC_PID=y
|
||||
CONFIG_MAC80211_RC_DEFAULT_PID=y
|
||||
# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
|
||||
CONFIG_MAC80211_RC_DEFAULT="pid"
|
||||
# CONFIG_MAC80211_MESH is not set
|
||||
# CONFIG_MAC80211_LEDS is not set
|
||||
# CONFIG_MAC80211_DEBUGFS is not set
|
||||
# CONFIG_MAC80211_DEBUG_MENU is not set
|
||||
@ -472,77 +490,7 @@ CONFIG_EXTRA_FIRMWARE=""
|
||||
# CONFIG_DEBUG_DEVRES is not set
|
||||
# CONFIG_SYS_HYPERVISOR is not set
|
||||
# CONFIG_CONNECTOR is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_DEBUG=y
|
||||
CONFIG_MTD_DEBUG_VERBOSE=0
|
||||
# CONFIG_MTD_CONCAT is not set
|
||||
# CONFIG_MTD_PARTITIONS is not set
|
||||
# CONFIG_MTD_TESTS is not set
|
||||
|
||||
#
|
||||
# User Modules And Translation Layers
|
||||
#
|
||||
# CONFIG_MTD_CHAR is not set
|
||||
CONFIG_MTD_BLKDEVS=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
# CONFIG_FTL is not set
|
||||
# CONFIG_NFTL is not set
|
||||
# CONFIG_INFTL is not set
|
||||
# CONFIG_RFD_FTL is not set
|
||||
# CONFIG_SSFDC is not set
|
||||
# CONFIG_MTD_OOPS is not set
|
||||
|
||||
#
|
||||
# RAM/ROM/Flash chip drivers
|
||||
#
|
||||
# CONFIG_MTD_CFI is not set
|
||||
# CONFIG_MTD_JEDECPROBE is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_1=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_2=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_4=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
|
||||
CONFIG_MTD_CFI_I1=y
|
||||
CONFIG_MTD_CFI_I2=y
|
||||
# CONFIG_MTD_CFI_I4 is not set
|
||||
# CONFIG_MTD_CFI_I8 is not set
|
||||
# CONFIG_MTD_RAM is not set
|
||||
# CONFIG_MTD_ROM is not set
|
||||
# CONFIG_MTD_ABSENT is not set
|
||||
|
||||
#
|
||||
# Mapping drivers for chip access
|
||||
#
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
# CONFIG_MTD_PLATRAM is not set
|
||||
|
||||
#
|
||||
# Self-contained MTD device drivers
|
||||
#
|
||||
# CONFIG_MTD_SLRAM is not set
|
||||
# CONFIG_MTD_PHRAM is not set
|
||||
# CONFIG_MTD_MTDRAM is not set
|
||||
# CONFIG_MTD_BLOCK2MTD is not set
|
||||
|
||||
#
|
||||
# Disk-On-Chip Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_DOC2000 is not set
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
# CONFIG_MTD_NAND is not set
|
||||
# CONFIG_MTD_ONENAND is not set
|
||||
|
||||
#
|
||||
# LPDDR flash memory drivers
|
||||
#
|
||||
# CONFIG_MTD_LPDDR is not set
|
||||
|
||||
#
|
||||
# UBI - Unsorted block images
|
||||
#
|
||||
# CONFIG_MTD_UBI is not set
|
||||
# CONFIG_MTD is not set
|
||||
CONFIG_OF_DEVICE=y
|
||||
# CONFIG_PARPORT is not set
|
||||
CONFIG_BLK_DEV=y
|
||||
@ -590,10 +538,6 @@ CONFIG_BLK_DEV_SR=y
|
||||
# CONFIG_BLK_DEV_SR_VENDOR is not set
|
||||
CONFIG_CHR_DEV_SG=m
|
||||
# CONFIG_CHR_DEV_SCH is not set
|
||||
|
||||
#
|
||||
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
|
||||
#
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
# CONFIG_SCSI_CONSTANTS is not set
|
||||
# CONFIG_SCSI_LOGGING is not set
|
||||
@ -626,7 +570,6 @@ CONFIG_BLK_DEV_DM=m
|
||||
# CONFIG_DM_UEVENT is not set
|
||||
# CONFIG_MACINTOSH_DRIVERS is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_COMPAT_NET_DEV_OPS=y
|
||||
# CONFIG_DUMMY is not set
|
||||
# CONFIG_BONDING is not set
|
||||
# CONFIG_MACVLAN is not set
|
||||
@ -646,10 +589,11 @@ CONFIG_MII=m
|
||||
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
|
||||
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
|
||||
# CONFIG_B44 is not set
|
||||
# CONFIG_KS8842 is not set
|
||||
CONFIG_NETDEV_1000=y
|
||||
CONFIG_GELIC_NET=y
|
||||
CONFIG_GELIC_WIRELESS=y
|
||||
CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y
|
||||
# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set
|
||||
# CONFIG_NETDEV_10000 is not set
|
||||
|
||||
#
|
||||
@ -669,8 +613,7 @@ CONFIG_WLAN_80211=y
|
||||
# CONFIG_HOSTAP is not set
|
||||
# CONFIG_B43 is not set
|
||||
# CONFIG_B43LEGACY is not set
|
||||
CONFIG_ZD1211RW=m
|
||||
# CONFIG_ZD1211RW_DEBUG is not set
|
||||
# CONFIG_ZD1211RW is not set
|
||||
# CONFIG_RT2X00 is not set
|
||||
|
||||
#
|
||||
@ -682,7 +625,7 @@ CONFIG_ZD1211RW=m
|
||||
#
|
||||
# CONFIG_USB_CATC is not set
|
||||
# CONFIG_USB_KAWETH is not set
|
||||
CONFIG_USB_PEGASUS=m
|
||||
# CONFIG_USB_PEGASUS is not set
|
||||
# CONFIG_USB_RTL8150 is not set
|
||||
CONFIG_USB_USBNET=m
|
||||
CONFIG_USB_NET_AX8817X=m
|
||||
@ -693,10 +636,11 @@ CONFIG_USB_NET_AX8817X=m
|
||||
# CONFIG_USB_NET_GL620A is not set
|
||||
# CONFIG_USB_NET_NET1080 is not set
|
||||
# CONFIG_USB_NET_PLUSB is not set
|
||||
CONFIG_USB_NET_MCS7830=m
|
||||
# CONFIG_USB_NET_MCS7830 is not set
|
||||
# CONFIG_USB_NET_RNDIS_HOST is not set
|
||||
# CONFIG_USB_NET_CDC_SUBSET is not set
|
||||
# CONFIG_USB_NET_ZAURUS is not set
|
||||
# CONFIG_USB_NET_INT51X1 is not set
|
||||
# CONFIG_WAN is not set
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_MULTILINK=y
|
||||
@ -771,8 +715,7 @@ CONFIG_DEVKMEM=y
|
||||
#
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
|
||||
CONFIG_LEGACY_PTYS=y
|
||||
CONFIG_LEGACY_PTY_COUNT=16
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_HVC_UDBG is not set
|
||||
# CONFIG_IPMI_HANDLER is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
@ -782,6 +725,11 @@ CONFIG_LEGACY_PTY_COUNT=16
|
||||
# CONFIG_TCG_TPM is not set
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_SPI is not set
|
||||
|
||||
#
|
||||
# PPS support
|
||||
#
|
||||
# CONFIG_PPS is not set
|
||||
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
|
||||
# CONFIG_GPIOLIB is not set
|
||||
# CONFIG_W1 is not set
|
||||
@ -805,22 +753,7 @@ CONFIG_SSB_POSSIBLE=y
|
||||
# CONFIG_HTC_PASIC3 is not set
|
||||
# CONFIG_MFD_TMIO is not set
|
||||
# CONFIG_REGULATOR is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
|
||||
#
|
||||
# Multimedia core support
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
# CONFIG_DVB_CORE is not set
|
||||
# CONFIG_VIDEO_MEDIA is not set
|
||||
|
||||
#
|
||||
# Multimedia drivers
|
||||
#
|
||||
# CONFIG_DAB is not set
|
||||
# CONFIG_MEDIA_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
@ -898,6 +831,11 @@ CONFIG_SND_SUPPORT_OLD_API=y
|
||||
CONFIG_SND_VERBOSE_PROCFS=y
|
||||
# CONFIG_SND_VERBOSE_PRINTK is not set
|
||||
# CONFIG_SND_DEBUG is not set
|
||||
# CONFIG_SND_RAWMIDI_SEQ is not set
|
||||
# CONFIG_SND_OPL3_LIB_SEQ is not set
|
||||
# CONFIG_SND_OPL4_LIB_SEQ is not set
|
||||
# CONFIG_SND_SBAWE_SEQ is not set
|
||||
# CONFIG_SND_EMU10K1_SEQ is not set
|
||||
# CONFIG_SND_DRIVERS is not set
|
||||
CONFIG_SND_PPC=y
|
||||
CONFIG_SND_PS3=m
|
||||
@ -930,29 +868,34 @@ CONFIG_USB_HIDDEV=y
|
||||
# Special HID drivers
|
||||
#
|
||||
# CONFIG_HID_A4TECH is not set
|
||||
# CONFIG_HID_APPLE is not set
|
||||
# CONFIG_HID_BELKIN is not set
|
||||
# CONFIG_HID_CHERRY is not set
|
||||
CONFIG_HID_APPLE=m
|
||||
CONFIG_HID_BELKIN=m
|
||||
CONFIG_HID_CHERRY=m
|
||||
# CONFIG_HID_CHICONY is not set
|
||||
# CONFIG_HID_CYPRESS is not set
|
||||
# CONFIG_DRAGONRISE_FF is not set
|
||||
# CONFIG_HID_EZKEY is not set
|
||||
# CONFIG_HID_DRAGONRISE is not set
|
||||
CONFIG_HID_EZKEY=m
|
||||
# CONFIG_HID_KYE is not set
|
||||
# CONFIG_HID_GYRATION is not set
|
||||
# CONFIG_HID_KENSINGTON is not set
|
||||
# CONFIG_HID_LOGITECH is not set
|
||||
# CONFIG_HID_MICROSOFT is not set
|
||||
CONFIG_HID_LOGITECH=m
|
||||
# CONFIG_LOGITECH_FF is not set
|
||||
# CONFIG_LOGIRUMBLEPAD2_FF is not set
|
||||
CONFIG_HID_MICROSOFT=m
|
||||
# CONFIG_HID_MONTEREY is not set
|
||||
# CONFIG_HID_NTRIG is not set
|
||||
# CONFIG_HID_PANTHERLORD is not set
|
||||
# CONFIG_HID_PETALYNX is not set
|
||||
# CONFIG_HID_SAMSUNG is not set
|
||||
CONFIG_HID_SONY=m
|
||||
# CONFIG_HID_SUNPLUS is not set
|
||||
# CONFIG_GREENASIA_FF is not set
|
||||
CONFIG_HID_SUNPLUS=m
|
||||
# CONFIG_HID_GREENASIA is not set
|
||||
CONFIG_HID_SMARTJOYPLUS=m
|
||||
# CONFIG_SMARTJOYPLUS_FF is not set
|
||||
# CONFIG_HID_TOPSEED is not set
|
||||
# CONFIG_THRUSTMASTER_FF is not set
|
||||
# CONFIG_ZEROPLUS_FF is not set
|
||||
# CONFIG_HID_THRUSTMASTER is not set
|
||||
# CONFIG_HID_WACOM is not set
|
||||
# CONFIG_HID_ZEROPLUS is not set
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USB_ARCH_HAS_HCD=y
|
||||
CONFIG_USB_ARCH_HAS_OHCI=y
|
||||
@ -988,6 +931,8 @@ CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
|
||||
# CONFIG_USB_ISP116X_HCD is not set
|
||||
# CONFIG_USB_ISP1760_HCD is not set
|
||||
CONFIG_USB_OHCI_HCD=m
|
||||
# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
|
||||
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
|
||||
# CONFIG_USB_OHCI_HCD_PPC_OF is not set
|
||||
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
|
||||
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
|
||||
@ -1115,6 +1060,10 @@ CONFIG_RTC_DRV_PS3=m
|
||||
# CONFIG_DMADEVICES is not set
|
||||
# CONFIG_AUXDISPLAY is not set
|
||||
# CONFIG_UIO is not set
|
||||
|
||||
#
|
||||
# TI VLYNQ
|
||||
#
|
||||
# CONFIG_STAGING is not set
|
||||
|
||||
#
|
||||
@ -1141,11 +1090,12 @@ CONFIG_FS_MBCACHE=y
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
CONFIG_FILE_LOCKING=y
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_BTRFS_FS is not set
|
||||
CONFIG_FILE_LOCKING=y
|
||||
CONFIG_FSNOTIFY=y
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_INOTIFY=y
|
||||
CONFIG_INOTIFY_USER=y
|
||||
@ -1205,7 +1155,6 @@ CONFIG_MISC_FILESYSTEMS=y
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
# CONFIG_JFFS2_FS is not set
|
||||
# CONFIG_CRAMFS is not set
|
||||
# CONFIG_SQUASHFS is not set
|
||||
# CONFIG_VXFS_FS is not set
|
||||
@ -1222,6 +1171,7 @@ CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V3=y
|
||||
# CONFIG_NFS_V3_ACL is not set
|
||||
CONFIG_NFS_V4=y
|
||||
# CONFIG_NFS_V4_1 is not set
|
||||
CONFIG_ROOT_NFS=y
|
||||
# CONFIG_NFSD is not set
|
||||
CONFIG_LOCKD=y
|
||||
@ -1359,7 +1309,6 @@ CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
# CONFIG_DEBUG_SG is not set
|
||||
# CONFIG_DEBUG_NOTIFIERS is not set
|
||||
# CONFIG_BOOT_PRINTK_DELAY is not set
|
||||
# CONFIG_RCU_TORTURE_TEST is not set
|
||||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
||||
# CONFIG_BACKTRACE_SELF_TEST is not set
|
||||
@ -1374,31 +1323,21 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||
CONFIG_RING_BUFFER=y
|
||||
CONFIG_EVENT_TRACING=y
|
||||
CONFIG_CONTEXT_SWITCH_TRACER=y
|
||||
CONFIG_TRACING=y
|
||||
CONFIG_TRACING_SUPPORT=y
|
||||
|
||||
#
|
||||
# Tracers
|
||||
#
|
||||
# CONFIG_FUNCTION_TRACER is not set
|
||||
# CONFIG_IRQSOFF_TRACER is not set
|
||||
# CONFIG_SCHED_TRACER is not set
|
||||
# CONFIG_CONTEXT_SWITCH_TRACER is not set
|
||||
# CONFIG_EVENT_TRACER is not set
|
||||
# CONFIG_BOOT_TRACER is not set
|
||||
# CONFIG_TRACE_BRANCH_PROFILING is not set
|
||||
# CONFIG_STACK_TRACER is not set
|
||||
# CONFIG_KMEMTRACE is not set
|
||||
# CONFIG_WORKQUEUE_TRACER is not set
|
||||
# CONFIG_BLK_DEV_IO_TRACE is not set
|
||||
# CONFIG_FTRACE_STARTUP_TEST is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
# CONFIG_DYNAMIC_DEBUG is not set
|
||||
# CONFIG_SAMPLES is not set
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
# CONFIG_KGDB is not set
|
||||
# CONFIG_PPC_DISABLE_WERROR is not set
|
||||
CONFIG_PPC_WERROR=y
|
||||
CONFIG_PRINT_STACK_DEPTH=64
|
||||
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
# CONFIG_PPC_EMULATED_STATS is not set
|
||||
# CONFIG_CODE_PATCHING_SELFTEST is not set
|
||||
# CONFIG_FTR_FIXUP_SELFTEST is not set
|
||||
# CONFIG_MSI_BITMAP_SELFTEST is not set
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/rtc.h>
|
||||
#include <asm/lv1call.h>
|
||||
#include <asm/ps3.h>
|
||||
@ -84,6 +85,9 @@ static int __init ps3_rtc_init(void)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
|
||||
if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
|
||||
return -ENODEV;
|
||||
|
||||
pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
@ -154,6 +154,20 @@ static int __init condev_setup(char *str)
|
||||
|
||||
__setup("condev=", condev_setup);
|
||||
|
||||
static void __init set_preferred_console(void)
|
||||
{
|
||||
if (MACHINE_IS_KVM) {
|
||||
add_preferred_console("hvc", 0, NULL);
|
||||
s390_virtio_console_init();
|
||||
return;
|
||||
}
|
||||
|
||||
if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
|
||||
add_preferred_console("ttyS", 0, NULL);
|
||||
if (CONSOLE_IS_3270)
|
||||
add_preferred_console("tty3270", 0, NULL);
|
||||
}
|
||||
|
||||
static int __init conmode_setup(char *str)
|
||||
{
|
||||
#if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
|
||||
@ -168,6 +182,7 @@ static int __init conmode_setup(char *str)
|
||||
if (strncmp(str, "3270", 5) == 0)
|
||||
SET_CONSOLE_3270;
|
||||
#endif
|
||||
set_preferred_console();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -780,9 +795,6 @@ static void __init setup_hwcaps(void)
|
||||
void __init
|
||||
setup_arch(char **cmdline_p)
|
||||
{
|
||||
/* set up preferred console */
|
||||
add_preferred_console("ttyS", 0, NULL);
|
||||
|
||||
/*
|
||||
* print what head.S has found out about the machine
|
||||
*/
|
||||
@ -802,11 +814,9 @@ setup_arch(char **cmdline_p)
|
||||
if (MACHINE_IS_VM)
|
||||
pr_info("Linux is running as a z/VM "
|
||||
"guest operating system in 64-bit mode\n");
|
||||
else if (MACHINE_IS_KVM) {
|
||||
else if (MACHINE_IS_KVM)
|
||||
pr_info("Linux is running under KVM in 64-bit mode\n");
|
||||
add_preferred_console("hvc", 0, NULL);
|
||||
s390_virtio_console_init();
|
||||
} else
|
||||
else
|
||||
pr_info("Linux is running natively in 64-bit mode\n");
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
@ -851,6 +861,7 @@ setup_arch(char **cmdline_p)
|
||||
|
||||
/* Setup default console */
|
||||
conmode_default();
|
||||
set_preferred_console();
|
||||
|
||||
/* Setup zfcpdump support */
|
||||
setup_zfcpdump(console_devno);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.30-rc2
|
||||
# Fri Apr 17 04:04:46 2009
|
||||
# Linux kernel version: 2.6.31-rc1
|
||||
# Tue Aug 18 23:45:52 2009
|
||||
#
|
||||
# CONFIG_64BIT is not set
|
||||
CONFIG_SPARC=y
|
||||
@ -17,6 +17,7 @@ CONFIG_GENERIC_ISA_DMA=y
|
||||
CONFIG_ARCH_NO_VIRT_TO_BUS=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
CONFIG_CONSTRUCTORS=y
|
||||
|
||||
#
|
||||
# General setup
|
||||
@ -74,7 +75,6 @@ CONFIG_SYSCTL_SYSCALL=y
|
||||
CONFIG_KALLSYMS=y
|
||||
# CONFIG_KALLSYMS_ALL is not set
|
||||
# CONFIG_KALLSYMS_EXTRA_PASS is not set
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_HOTPLUG=y
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
@ -87,8 +87,13 @@ CONFIG_TIMERFD=y
|
||||
CONFIG_EVENTFD=y
|
||||
CONFIG_SHMEM=y
|
||||
CONFIG_AIO=y
|
||||
|
||||
#
|
||||
# Performance Counters
|
||||
#
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_PCI_QUIRKS=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_COMPAT_BRK=y
|
||||
CONFIG_SLAB=y
|
||||
# CONFIG_SLUB is not set
|
||||
@ -97,6 +102,10 @@ CONFIG_SLAB=y
|
||||
# CONFIG_MARKERS is not set
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
|
||||
#
|
||||
# GCOV-based kernel profiling
|
||||
#
|
||||
# CONFIG_SLOW_WORK is not set
|
||||
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
|
||||
CONFIG_SLABINFO=y
|
||||
@ -109,7 +118,7 @@ CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_MODVERSIONS is not set
|
||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||
CONFIG_BLOCK=y
|
||||
# CONFIG_LBD is not set
|
||||
CONFIG_LBDAF=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_BLK_DEV_INTEGRITY is not set
|
||||
|
||||
@ -154,9 +163,9 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
# CONFIG_PHYS_ADDR_T_64BIT is not set
|
||||
CONFIG_ZONE_DMA_FLAG=1
|
||||
CONFIG_BOUNCE=y
|
||||
CONFIG_UNEVICTABLE_LRU=y
|
||||
CONFIG_HAVE_MLOCK=y
|
||||
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
|
||||
CONFIG_SUN_PM=y
|
||||
# CONFIG_SPARC_LED is not set
|
||||
CONFIG_SERIAL_CONSOLE=y
|
||||
@ -264,6 +273,7 @@ CONFIG_IPV6_TUNNEL=m
|
||||
# CONFIG_ECONET is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
# CONFIG_PHONET is not set
|
||||
# CONFIG_IEEE802154 is not set
|
||||
# CONFIG_NET_SCHED is not set
|
||||
# CONFIG_DCB is not set
|
||||
|
||||
@ -281,7 +291,11 @@ CONFIG_WIRELESS=y
|
||||
CONFIG_WIRELESS_OLD_REGULATORY=y
|
||||
# CONFIG_WIRELESS_EXT is not set
|
||||
# CONFIG_LIB80211 is not set
|
||||
# CONFIG_MAC80211 is not set
|
||||
|
||||
#
|
||||
# CFG80211 needs to be enabled for MAC80211
|
||||
#
|
||||
CONFIG_MAC80211_DEFAULT_PS_VALUE=0
|
||||
# CONFIG_WIMAX is not set
|
||||
# CONFIG_RFKILL is not set
|
||||
# CONFIG_NET_9P is not set
|
||||
@ -335,6 +349,7 @@ CONFIG_MISC_DEVICES=y
|
||||
# EEPROM support
|
||||
#
|
||||
# CONFIG_EEPROM_93CX6 is not set
|
||||
# CONFIG_CB710_CORE is not set
|
||||
CONFIG_HAVE_IDE=y
|
||||
# CONFIG_IDE is not set
|
||||
|
||||
@ -358,10 +373,6 @@ CONFIG_BLK_DEV_SR=m
|
||||
# CONFIG_BLK_DEV_SR_VENDOR is not set
|
||||
CONFIG_CHR_DEV_SG=m
|
||||
# CONFIG_CHR_DEV_SCH is not set
|
||||
|
||||
#
|
||||
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
|
||||
#
|
||||
# CONFIG_SCSI_MULTI_LUN is not set
|
||||
# CONFIG_SCSI_CONSTANTS is not set
|
||||
# CONFIG_SCSI_LOGGING is not set
|
||||
@ -379,6 +390,7 @@ CONFIG_SCSI_SPI_ATTRS=y
|
||||
CONFIG_SCSI_LOWLEVEL=y
|
||||
# CONFIG_ISCSI_TCP is not set
|
||||
# CONFIG_SCSI_CXGB3_ISCSI is not set
|
||||
# CONFIG_SCSI_BNX2_ISCSI is not set
|
||||
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
|
||||
# CONFIG_SCSI_3W_9XXX is not set
|
||||
# CONFIG_SCSI_ACARD is not set
|
||||
@ -387,6 +399,7 @@ CONFIG_SCSI_LOWLEVEL=y
|
||||
# CONFIG_SCSI_AIC7XXX_OLD is not set
|
||||
# CONFIG_SCSI_AIC79XX is not set
|
||||
# CONFIG_SCSI_AIC94XX is not set
|
||||
# CONFIG_SCSI_MVSAS is not set
|
||||
# CONFIG_SCSI_ARCMSR is not set
|
||||
# CONFIG_MEGARAID_NEWGEN is not set
|
||||
# CONFIG_MEGARAID_LEGACY is not set
|
||||
@ -401,7 +414,6 @@ CONFIG_SCSI_LOWLEVEL=y
|
||||
# CONFIG_SCSI_IPS is not set
|
||||
# CONFIG_SCSI_INITIO is not set
|
||||
# CONFIG_SCSI_INIA100 is not set
|
||||
# CONFIG_SCSI_MVSAS is not set
|
||||
# CONFIG_SCSI_STEX is not set
|
||||
# CONFIG_SCSI_SYM53C8XX_2 is not set
|
||||
# CONFIG_SCSI_QLOGIC_1280 is not set
|
||||
@ -426,13 +438,16 @@ CONFIG_SCSI_SUNESP=y
|
||||
#
|
||||
|
||||
#
|
||||
# Enable only one of the two stacks, unless you know what you are doing
|
||||
# You can enable one or both FireWire driver stacks.
|
||||
#
|
||||
|
||||
#
|
||||
# See the help texts for more information.
|
||||
#
|
||||
# CONFIG_FIREWIRE is not set
|
||||
# CONFIG_IEEE1394 is not set
|
||||
# CONFIG_I2O is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_COMPAT_NET_DEV_OPS=y
|
||||
CONFIG_DUMMY=m
|
||||
# CONFIG_BONDING is not set
|
||||
# CONFIG_MACVLAN is not set
|
||||
@ -463,6 +478,7 @@ CONFIG_SUNQE=m
|
||||
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
|
||||
# CONFIG_NET_PCI is not set
|
||||
# CONFIG_B44 is not set
|
||||
# CONFIG_KS8842 is not set
|
||||
# CONFIG_ATL2 is not set
|
||||
CONFIG_NETDEV_1000=y
|
||||
# CONFIG_ACENIC is not set
|
||||
@ -482,6 +498,7 @@ CONFIG_NETDEV_1000=y
|
||||
# CONFIG_VIA_VELOCITY is not set
|
||||
# CONFIG_TIGON3 is not set
|
||||
# CONFIG_BNX2 is not set
|
||||
# CONFIG_CNIC is not set
|
||||
# CONFIG_QLA3XXX is not set
|
||||
# CONFIG_ATL1 is not set
|
||||
# CONFIG_ATL1E is not set
|
||||
@ -629,6 +646,11 @@ CONFIG_HW_RANDOM=m
|
||||
CONFIG_DEVPORT=y
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_SPI is not set
|
||||
|
||||
#
|
||||
# PPS support
|
||||
#
|
||||
# CONFIG_PPS is not set
|
||||
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
|
||||
# CONFIG_GPIOLIB is not set
|
||||
# CONFIG_W1 is not set
|
||||
@ -668,22 +690,7 @@ CONFIG_SSB_POSSIBLE=y
|
||||
# CONFIG_HTC_PASIC3 is not set
|
||||
# CONFIG_MFD_TMIO is not set
|
||||
# CONFIG_REGULATOR is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
|
||||
#
|
||||
# Multimedia core support
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
# CONFIG_DVB_CORE is not set
|
||||
# CONFIG_VIDEO_MEDIA is not set
|
||||
|
||||
#
|
||||
# Multimedia drivers
|
||||
#
|
||||
# CONFIG_DAB is not set
|
||||
# CONFIG_MEDIA_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
@ -776,6 +783,10 @@ CONFIG_RTC_DRV_M48T59=y
|
||||
# CONFIG_DMADEVICES is not set
|
||||
# CONFIG_AUXDISPLAY is not set
|
||||
# CONFIG_UIO is not set
|
||||
|
||||
#
|
||||
# TI VLYNQ
|
||||
#
|
||||
# CONFIG_STAGING is not set
|
||||
|
||||
#
|
||||
@ -799,10 +810,12 @@ CONFIG_FS_MBCACHE=y
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
CONFIG_FILE_LOCKING=y
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_BTRFS_FS is not set
|
||||
CONFIG_FILE_LOCKING=y
|
||||
CONFIG_FSNOTIFY=y
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_INOTIFY=y
|
||||
CONFIG_INOTIFY_USER=y
|
||||
@ -985,6 +998,7 @@ CONFIG_KGDB=y
|
||||
CONFIG_KGDB_SERIAL_CONSOLE=y
|
||||
CONFIG_KGDB_TESTS=y
|
||||
# CONFIG_KGDB_TESTS_ON_BOOT is not set
|
||||
# CONFIG_KMEMCHECK is not set
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
# CONFIG_STACK_DEBUG is not set
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.30
|
||||
# Tue Jun 16 04:59:36 2009
|
||||
# Linux kernel version: 2.6.31-rc1
|
||||
# Tue Aug 18 23:56:02 2009
|
||||
#
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_SPARC=y
|
||||
@ -26,6 +26,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
CONFIG_CONSTRUCTORS=y
|
||||
|
||||
#
|
||||
# General setup
|
||||
@ -119,6 +120,11 @@ CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_HAVE_KRETPROBES=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
CONFIG_USE_GENERIC_SMP_HELPERS=y
|
||||
|
||||
#
|
||||
# GCOV-based kernel profiling
|
||||
#
|
||||
# CONFIG_GCOV_KERNEL is not set
|
||||
# CONFIG_SLOW_WORK is not set
|
||||
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
|
||||
CONFIG_SLABINFO=y
|
||||
@ -204,7 +210,6 @@ CONFIG_MIGRATION=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
||||
CONFIG_NR_QUICK=1
|
||||
CONFIG_UNEVICTABLE_LRU=y
|
||||
CONFIG_HAVE_MLOCK=y
|
||||
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=8192
|
||||
@ -410,6 +415,7 @@ CONFIG_MISC_DEVICES=y
|
||||
#
|
||||
# CONFIG_EEPROM_AT24 is not set
|
||||
# CONFIG_EEPROM_LEGACY is not set
|
||||
# CONFIG_EEPROM_MAX6875 is not set
|
||||
# CONFIG_EEPROM_93CX6 is not set
|
||||
# CONFIG_CB710_CORE is not set
|
||||
CONFIG_HAVE_IDE=y
|
||||
@ -562,6 +568,7 @@ CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
# CONFIG_DM_LOG_USERSPACE is not set
|
||||
CONFIG_DM_ZERO=m
|
||||
# CONFIG_DM_MULTIPATH is not set
|
||||
# CONFIG_DM_DELAY is not set
|
||||
@ -573,7 +580,11 @@ CONFIG_DM_ZERO=m
|
||||
#
|
||||
|
||||
#
|
||||
# Enable only one of the two stacks, unless you know what you are doing
|
||||
# You can enable one or both FireWire driver stacks.
|
||||
#
|
||||
|
||||
#
|
||||
# See the help texts for more information.
|
||||
#
|
||||
# CONFIG_FIREWIRE is not set
|
||||
# CONFIG_IEEE1394 is not set
|
||||
@ -667,6 +678,7 @@ CONFIG_E1000E=m
|
||||
# CONFIG_VIA_VELOCITY is not set
|
||||
CONFIG_TIGON3=m
|
||||
CONFIG_BNX2=m
|
||||
# CONFIG_CNIC is not set
|
||||
# CONFIG_QLA3XXX is not set
|
||||
# CONFIG_ATL1 is not set
|
||||
# CONFIG_ATL1E is not set
|
||||
@ -773,6 +785,7 @@ CONFIG_MOUSE_SERIAL=y
|
||||
# CONFIG_MOUSE_APPLETOUCH is not set
|
||||
# CONFIG_MOUSE_BCM5974 is not set
|
||||
# CONFIG_MOUSE_VSXXXAA is not set
|
||||
# CONFIG_MOUSE_SYNAPTICS_I2C is not set
|
||||
# CONFIG_INPUT_JOYSTICK is not set
|
||||
# CONFIG_INPUT_TABLET is not set
|
||||
# CONFIG_INPUT_TOUCHSCREEN is not set
|
||||
@ -870,6 +883,7 @@ CONFIG_I2C_ALGOBIT=y
|
||||
#
|
||||
# I2C system bus drivers (mostly embedded / system-on-chip)
|
||||
#
|
||||
# CONFIG_I2C_DESIGNWARE is not set
|
||||
# CONFIG_I2C_OCORES is not set
|
||||
# CONFIG_I2C_SIMTEC is not set
|
||||
|
||||
@ -898,13 +912,17 @@ CONFIG_I2C_ALGOBIT=y
|
||||
# CONFIG_SENSORS_PCF8574 is not set
|
||||
# CONFIG_PCF8575 is not set
|
||||
# CONFIG_SENSORS_PCA9539 is not set
|
||||
# CONFIG_SENSORS_MAX6875 is not set
|
||||
# CONFIG_SENSORS_TSL2550 is not set
|
||||
# CONFIG_I2C_DEBUG_CORE is not set
|
||||
# CONFIG_I2C_DEBUG_ALGO is not set
|
||||
# CONFIG_I2C_DEBUG_BUS is not set
|
||||
# CONFIG_I2C_DEBUG_CHIP is not set
|
||||
# CONFIG_SPI is not set
|
||||
|
||||
#
|
||||
# PPS support
|
||||
#
|
||||
# CONFIG_PPS is not set
|
||||
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
|
||||
# CONFIG_GPIOLIB is not set
|
||||
# CONFIG_W1 is not set
|
||||
@ -959,6 +977,7 @@ CONFIG_HWMON=y
|
||||
# CONFIG_SENSORS_SMSC47B397 is not set
|
||||
# CONFIG_SENSORS_ADS7828 is not set
|
||||
# CONFIG_SENSORS_THMC50 is not set
|
||||
# CONFIG_SENSORS_TMP401 is not set
|
||||
# CONFIG_SENSORS_VIA686A is not set
|
||||
# CONFIG_SENSORS_VT1211 is not set
|
||||
# CONFIG_SENSORS_VT8231 is not set
|
||||
@ -994,23 +1013,9 @@ CONFIG_SSB_POSSIBLE=y
|
||||
# CONFIG_MFD_WM8400 is not set
|
||||
# CONFIG_MFD_WM8350_I2C is not set
|
||||
# CONFIG_MFD_PCF50633 is not set
|
||||
# CONFIG_AB3100_CORE is not set
|
||||
# CONFIG_REGULATOR is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
|
||||
#
|
||||
# Multimedia core support
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
# CONFIG_DVB_CORE is not set
|
||||
# CONFIG_VIDEO_MEDIA is not set
|
||||
|
||||
#
|
||||
# Multimedia drivers
|
||||
#
|
||||
# CONFIG_DAB is not set
|
||||
# CONFIG_MEDIA_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
@ -1284,7 +1289,6 @@ CONFIG_USB=y
|
||||
#
|
||||
# Miscellaneous USB options
|
||||
#
|
||||
CONFIG_USB_DEVICEFS=y
|
||||
# CONFIG_USB_DEVICE_CLASS is not set
|
||||
# CONFIG_USB_DYNAMIC_MINORS is not set
|
||||
# CONFIG_USB_OTG is not set
|
||||
@ -1296,6 +1300,7 @@ CONFIG_USB_DEVICEFS=y
|
||||
# USB Host Controller Drivers
|
||||
#
|
||||
# CONFIG_USB_C67X00_HCD is not set
|
||||
# CONFIG_USB_XHCI_HCD is not set
|
||||
CONFIG_USB_EHCI_HCD=m
|
||||
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
|
||||
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
|
||||
@ -1374,7 +1379,6 @@ CONFIG_USB_STORAGE=m
|
||||
# CONFIG_USB_LD is not set
|
||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||
# CONFIG_USB_IOWARRIOR is not set
|
||||
# CONFIG_USB_TEST is not set
|
||||
# CONFIG_USB_ISIGHTFW is not set
|
||||
# CONFIG_USB_VST is not set
|
||||
# CONFIG_USB_GADGET is not set
|
||||
@ -1420,6 +1424,7 @@ CONFIG_RTC_INTF_DEV=y
|
||||
# CONFIG_RTC_DRV_S35390A is not set
|
||||
# CONFIG_RTC_DRV_FM3130 is not set
|
||||
# CONFIG_RTC_DRV_RX8581 is not set
|
||||
# CONFIG_RTC_DRV_RX8025 is not set
|
||||
|
||||
#
|
||||
# SPI RTC drivers
|
||||
@ -1448,6 +1453,10 @@ CONFIG_RTC_DRV_STARFIRE=y
|
||||
# CONFIG_DMADEVICES is not set
|
||||
# CONFIG_AUXDISPLAY is not set
|
||||
# CONFIG_UIO is not set
|
||||
|
||||
#
|
||||
# TI VLYNQ
|
||||
#
|
||||
# CONFIG_STAGING is not set
|
||||
|
||||
#
|
||||
@ -1480,11 +1489,11 @@ CONFIG_FS_MBCACHE=y
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
CONFIG_FILE_LOCKING=y
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_BTRFS_FS is not set
|
||||
CONFIG_FILE_LOCKING=y
|
||||
CONFIG_FSNOTIFY=y
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_INOTIFY=y
|
||||
@ -1560,7 +1569,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
CONFIG_SUN_PARTITION=y
|
||||
CONFIG_NLS=m
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_DEFAULT="iso8859-1"
|
||||
# CONFIG_NLS_CODEPAGE_437 is not set
|
||||
# CONFIG_NLS_CODEPAGE_737 is not set
|
||||
|
@ -726,11 +726,17 @@ extern unsigned long pte_file(pte_t);
|
||||
extern pte_t pgoff_to_pte(unsigned long);
|
||||
#define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL)
|
||||
|
||||
extern unsigned long *sparc64_valid_addr_bitmap;
|
||||
extern unsigned long sparc64_valid_addr_bitmap[];
|
||||
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
#define kern_addr_valid(addr) \
|
||||
(test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
|
||||
static inline bool kern_addr_valid(unsigned long addr)
|
||||
{
|
||||
unsigned long paddr = __pa(addr);
|
||||
|
||||
if ((paddr >> 41UL) != 0UL)
|
||||
return false;
|
||||
return test_bit(paddr >> 22, sparc64_valid_addr_bitmap);
|
||||
}
|
||||
|
||||
extern int page_in_phys_avail(unsigned long paddr);
|
||||
|
||||
|
@ -151,12 +151,46 @@ kvmap_dtlb_4v:
|
||||
* Must preserve %g1 and %g6 (TAG).
|
||||
*/
|
||||
kvmap_dtlb_tsb4m_miss:
|
||||
sethi %hi(kpte_linear_bitmap), %g2
|
||||
/* Clear the PAGE_OFFSET top virtual bits, shift
|
||||
* down to get PFN, and make sure PFN is in range.
|
||||
*/
|
||||
sllx %g4, 21, %g5
|
||||
|
||||
/* Check to see if we know about valid memory at the 4MB
|
||||
* chunk this physical address will reside within.
|
||||
*/
|
||||
srlx %g5, 21 + 41, %g2
|
||||
brnz,pn %g2, kvmap_dtlb_longpath
|
||||
nop
|
||||
|
||||
/* This unconditional branch and delay-slot nop gets patched
|
||||
* by the sethi sequence once the bitmap is properly setup.
|
||||
*/
|
||||
.globl valid_addr_bitmap_insn
|
||||
valid_addr_bitmap_insn:
|
||||
ba,pt %xcc, 2f
|
||||
nop
|
||||
.subsection 2
|
||||
.globl valid_addr_bitmap_patch
|
||||
valid_addr_bitmap_patch:
|
||||
sethi %hi(sparc64_valid_addr_bitmap), %g7
|
||||
or %g7, %lo(sparc64_valid_addr_bitmap), %g7
|
||||
.previous
|
||||
|
||||
srlx %g5, 21 + 22, %g2
|
||||
srlx %g2, 6, %g5
|
||||
and %g2, 63, %g2
|
||||
sllx %g5, 3, %g5
|
||||
ldx [%g7 + %g5], %g5
|
||||
mov 1, %g7
|
||||
sllx %g7, %g2, %g7
|
||||
andcc %g5, %g7, %g0
|
||||
be,pn %xcc, kvmap_dtlb_longpath
|
||||
|
||||
2: sethi %hi(kpte_linear_bitmap), %g2
|
||||
or %g2, %lo(kpte_linear_bitmap), %g2
|
||||
|
||||
/* Clear the PAGE_OFFSET top virtual bits, then shift
|
||||
* down to get a 256MB physical address index.
|
||||
*/
|
||||
/* Get the 256MB physical address index. */
|
||||
sllx %g4, 21, %g5
|
||||
mov 1, %g7
|
||||
srlx %g5, 21 + 28, %g5
|
||||
|
@ -162,9 +162,6 @@ extern void cpu_panic(void);
|
||||
*/
|
||||
|
||||
extern struct linux_prom_registers smp_penguin_ctable;
|
||||
extern unsigned long trapbase_cpu1[];
|
||||
extern unsigned long trapbase_cpu2[];
|
||||
extern unsigned long trapbase_cpu3[];
|
||||
|
||||
void __init smp4d_boot_cpus(void)
|
||||
{
|
||||
@ -235,25 +232,6 @@ void __init smp4d_smp_done(void)
|
||||
*prev = first;
|
||||
local_flush_cache_all();
|
||||
|
||||
/* Free unneeded trap tables */
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu1));
|
||||
init_page_count(virt_to_page(trapbase_cpu1));
|
||||
free_page((unsigned long)trapbase_cpu1);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu2));
|
||||
init_page_count(virt_to_page(trapbase_cpu2));
|
||||
free_page((unsigned long)trapbase_cpu2);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu3));
|
||||
init_page_count(virt_to_page(trapbase_cpu3));
|
||||
free_page((unsigned long)trapbase_cpu3);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
||||
/* Ok, they are spinning and ready to go. */
|
||||
smp_processors_ready = 1;
|
||||
sun4d_distribute_irqs();
|
||||
|
@ -121,9 +121,6 @@ void __cpuinit smp4m_callin(void)
|
||||
*/
|
||||
|
||||
extern struct linux_prom_registers smp_penguin_ctable;
|
||||
extern unsigned long trapbase_cpu1[];
|
||||
extern unsigned long trapbase_cpu2[];
|
||||
extern unsigned long trapbase_cpu3[];
|
||||
|
||||
void __init smp4m_boot_cpus(void)
|
||||
{
|
||||
@ -193,29 +190,6 @@ void __init smp4m_smp_done(void)
|
||||
*prev = first;
|
||||
local_flush_cache_all();
|
||||
|
||||
/* Free unneeded trap tables */
|
||||
if (!cpu_isset(1, cpu_present_map)) {
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu1));
|
||||
init_page_count(virt_to_page(trapbase_cpu1));
|
||||
free_page((unsigned long)trapbase_cpu1);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
}
|
||||
if (!cpu_isset(2, cpu_present_map)) {
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu2));
|
||||
init_page_count(virt_to_page(trapbase_cpu2));
|
||||
free_page((unsigned long)trapbase_cpu2);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
}
|
||||
if (!cpu_isset(3, cpu_present_map)) {
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu3));
|
||||
init_page_count(virt_to_page(trapbase_cpu3));
|
||||
free_page((unsigned long)trapbase_cpu3);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
}
|
||||
|
||||
/* Ok, they are spinning and ready to go. */
|
||||
}
|
||||
|
||||
|
@ -134,10 +134,12 @@ SIGN1(sys32_getpeername, sys_getpeername, %o0)
|
||||
SIGN1(sys32_getsockname, sys_getsockname, %o0)
|
||||
SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
|
||||
SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
|
||||
SIGN2(sys32_splice, sys_splice, %o0, %o1)
|
||||
SIGN2(sys32_splice, sys_splice, %o0, %o2)
|
||||
SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
|
||||
SIGN2(sys32_tee, sys_tee, %o0, %o1)
|
||||
SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0)
|
||||
SIGN1(sys32_truncate, sys_truncate, %o1)
|
||||
SIGN1(sys32_ftruncate, sys_ftruncate, %o1)
|
||||
|
||||
.globl sys32_mmap2
|
||||
sys32_mmap2:
|
||||
|
@ -43,8 +43,8 @@ sys_call_table32:
|
||||
/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
|
||||
.word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
|
||||
/*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod
|
||||
.word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
|
||||
/*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
|
||||
.word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys32_truncate
|
||||
/*130*/ .word sys32_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
|
||||
.word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
|
||||
/*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
|
||||
.word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write
|
||||
|
@ -319,9 +319,10 @@ no_context:
|
||||
*/
|
||||
out_of_memory:
|
||||
up_read(&mm->mmap_sem);
|
||||
printk("VM: killing process %s\n", tsk->comm);
|
||||
if (from_user)
|
||||
do_group_exit(SIGKILL);
|
||||
if (from_user) {
|
||||
pagefault_out_of_memory();
|
||||
return;
|
||||
}
|
||||
goto no_context;
|
||||
|
||||
do_sigbus:
|
||||
|
@ -447,9 +447,10 @@ handle_kernel_fault:
|
||||
out_of_memory:
|
||||
insn = get_fault_insn(regs, insn);
|
||||
up_read(&mm->mmap_sem);
|
||||
printk("VM: killing process %s\n", current->comm);
|
||||
if (!(regs->tstate & TSTATE_PRIV))
|
||||
do_group_exit(SIGKILL);
|
||||
if (!(regs->tstate & TSTATE_PRIV)) {
|
||||
pagefault_out_of_memory();
|
||||
return;
|
||||
}
|
||||
goto handle_kernel_fault;
|
||||
|
||||
intr_or_no_mm:
|
||||
|
@ -145,7 +145,8 @@ static void __init read_obp_memory(const char *property,
|
||||
cmp_p64, NULL);
|
||||
}
|
||||
|
||||
unsigned long *sparc64_valid_addr_bitmap __read_mostly;
|
||||
unsigned long sparc64_valid_addr_bitmap[VALID_ADDR_BITMAP_BYTES /
|
||||
sizeof(unsigned long)];
|
||||
EXPORT_SYMBOL(sparc64_valid_addr_bitmap);
|
||||
|
||||
/* Kernel physical address base and size in bytes. */
|
||||
@ -1874,7 +1875,7 @@ static int pavail_rescan_ents __initdata;
|
||||
* memory list again, and make sure it provides at least as much
|
||||
* memory as 'pavail' does.
|
||||
*/
|
||||
static void __init setup_valid_addr_bitmap_from_pavail(void)
|
||||
static void __init setup_valid_addr_bitmap_from_pavail(unsigned long *bitmap)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1897,8 +1898,7 @@ static void __init setup_valid_addr_bitmap_from_pavail(void)
|
||||
|
||||
if (new_start <= old_start &&
|
||||
new_end >= (old_start + PAGE_SIZE)) {
|
||||
set_bit(old_start >> 22,
|
||||
sparc64_valid_addr_bitmap);
|
||||
set_bit(old_start >> 22, bitmap);
|
||||
goto do_next_page;
|
||||
}
|
||||
}
|
||||
@ -1919,20 +1919,21 @@ static void __init setup_valid_addr_bitmap_from_pavail(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void __init patch_tlb_miss_handler_bitmap(void)
|
||||
{
|
||||
extern unsigned int valid_addr_bitmap_insn[];
|
||||
extern unsigned int valid_addr_bitmap_patch[];
|
||||
|
||||
valid_addr_bitmap_insn[1] = valid_addr_bitmap_patch[1];
|
||||
mb();
|
||||
valid_addr_bitmap_insn[0] = valid_addr_bitmap_patch[0];
|
||||
flushi(&valid_addr_bitmap_insn[0]);
|
||||
}
|
||||
|
||||
void __init mem_init(void)
|
||||
{
|
||||
unsigned long codepages, datapages, initpages;
|
||||
unsigned long addr, last;
|
||||
int i;
|
||||
|
||||
i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
|
||||
i += 1;
|
||||
sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3);
|
||||
if (sparc64_valid_addr_bitmap == NULL) {
|
||||
prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n");
|
||||
prom_halt();
|
||||
}
|
||||
memset(sparc64_valid_addr_bitmap, 0, i << 3);
|
||||
|
||||
addr = PAGE_OFFSET + kern_base;
|
||||
last = PAGE_ALIGN(kern_size) + addr;
|
||||
@ -1941,15 +1942,19 @@ void __init mem_init(void)
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
setup_valid_addr_bitmap_from_pavail();
|
||||
setup_valid_addr_bitmap_from_pavail(sparc64_valid_addr_bitmap);
|
||||
patch_tlb_miss_handler_bitmap();
|
||||
|
||||
high_memory = __va(last_valid_pfn << PAGE_SHIFT);
|
||||
|
||||
#ifdef CONFIG_NEED_MULTIPLE_NODES
|
||||
for_each_online_node(i) {
|
||||
if (NODE_DATA(i)->node_spanned_pages != 0) {
|
||||
totalram_pages +=
|
||||
free_all_bootmem_node(NODE_DATA(i));
|
||||
{
|
||||
int i;
|
||||
for_each_online_node(i) {
|
||||
if (NODE_DATA(i)->node_spanned_pages != 0) {
|
||||
totalram_pages +=
|
||||
free_all_bootmem_node(NODE_DATA(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -5,10 +5,13 @@
|
||||
* marked non-static so that assembler code can get at them.
|
||||
*/
|
||||
|
||||
#define MAX_PHYS_ADDRESS (1UL << 42UL)
|
||||
#define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL)
|
||||
#define MAX_PHYS_ADDRESS (1UL << 41UL)
|
||||
#define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL)
|
||||
#define KPTE_BITMAP_BYTES \
|
||||
((MAX_PHYS_ADDRESS / KPTE_BITMAP_CHUNK_SZ) / 8)
|
||||
#define VALID_ADDR_BITMAP_CHUNK_SZ (4UL * 1024UL * 1024UL)
|
||||
#define VALID_ADDR_BITMAP_BYTES \
|
||||
((MAX_PHYS_ADDRESS / VALID_ADDR_BITMAP_CHUNK_SZ) / 8)
|
||||
|
||||
extern unsigned long kern_linear_pte_xor[2];
|
||||
extern unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
|
||||
|
@ -4,7 +4,7 @@
|
||||
# create a compressed vmlinux image from the original vmlinux
|
||||
#
|
||||
|
||||
targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o
|
||||
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o
|
||||
|
||||
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
|
||||
KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _ASM_X86_PGTABLE_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/e820.h>
|
||||
|
||||
#include <asm/pgtable_types.h>
|
||||
|
||||
@ -269,9 +270,16 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
|
||||
|
||||
#define canon_pgprot(p) __pgprot(massage_pgprot(p))
|
||||
|
||||
static inline int is_new_memtype_allowed(unsigned long flags,
|
||||
unsigned long new_flags)
|
||||
static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
|
||||
unsigned long flags,
|
||||
unsigned long new_flags)
|
||||
{
|
||||
/*
|
||||
* PAT type is always WB for ISA. So no need to check.
|
||||
*/
|
||||
if (is_ISA_range(paddr, paddr + size - 1))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Certain new memtypes are not allowed with certain
|
||||
* requested memtype:
|
||||
|
@ -106,6 +106,9 @@ void default_send_IPI_mask_logical(const struct cpumask *cpumask, int vector)
|
||||
unsigned long mask = cpumask_bits(cpumask)[0];
|
||||
unsigned long flags;
|
||||
|
||||
if (WARN_ONCE(!mask, "empty IPI mask"))
|
||||
return;
|
||||
|
||||
local_irq_save(flags);
|
||||
WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]);
|
||||
__default_send_IPI_dest_field(mask, vector, apic->dest_logical);
|
||||
|
@ -44,6 +44,11 @@ static struct apic *apic_probe[] __initdata = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int apicid_phys_pkg_id(int initial_apic_id, int index_msb)
|
||||
{
|
||||
return hard_smp_processor_id() >> index_msb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
|
||||
*/
|
||||
@ -69,6 +74,11 @@ void __init default_setup_apic_routing(void)
|
||||
printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
|
||||
}
|
||||
|
||||
if (is_vsmp_box()) {
|
||||
/* need to update phys_pkg_id */
|
||||
apic->phys_pkg_id = apicid_phys_pkg_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that apic routing model is selected, configure the
|
||||
* fault handling for intr remapping.
|
||||
|
@ -7,6 +7,10 @@ ifdef CONFIG_FUNCTION_TRACER
|
||||
CFLAGS_REMOVE_common.o = -pg
|
||||
endif
|
||||
|
||||
# Make sure load_percpu_segment has no stackprotector
|
||||
nostackp := $(call cc-option, -fno-stack-protector)
|
||||
CFLAGS_common.o := $(nostackp)
|
||||
|
||||
obj-y := intel_cacheinfo.o addon_cpuid_features.o
|
||||
obj-y += proc.o capflags.o powerflags.o common.o
|
||||
obj-y += vmware.o hypervisor.o
|
||||
|
@ -261,9 +261,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
|
||||
* which will be freed later
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_HOTPLUG_CPU
|
||||
.section .init.text,"ax",@progbits
|
||||
#endif
|
||||
__CPUINIT
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
ENTRY(startup_32_smp)
|
||||
@ -602,11 +600,7 @@ ignore_int:
|
||||
#endif
|
||||
iret
|
||||
|
||||
#ifndef CONFIG_HOTPLUG_CPU
|
||||
__CPUINITDATA
|
||||
#else
|
||||
__REFDATA
|
||||
#endif
|
||||
.align 4
|
||||
ENTRY(initial_code)
|
||||
.long i386_start_kernel
|
||||
|
@ -519,16 +519,12 @@ static void c1e_idle(void)
|
||||
if (!cpumask_test_cpu(cpu, c1e_mask)) {
|
||||
cpumask_set_cpu(cpu, c1e_mask);
|
||||
/*
|
||||
* Force broadcast so ACPI can not interfere. Needs
|
||||
* to run with interrupts enabled as it uses
|
||||
* smp_function_call.
|
||||
* Force broadcast so ACPI can not interfere.
|
||||
*/
|
||||
local_irq_enable();
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
|
||||
&cpu);
|
||||
printk(KERN_INFO "Switch to broadcast mode on CPU%d\n",
|
||||
cpu);
|
||||
local_irq_disable();
|
||||
}
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
|
||||
|
||||
|
@ -46,11 +46,10 @@ PHDRS {
|
||||
data PT_LOAD FLAGS(7); /* RWE */
|
||||
#ifdef CONFIG_X86_64
|
||||
user PT_LOAD FLAGS(7); /* RWE */
|
||||
data.init PT_LOAD FLAGS(7); /* RWE */
|
||||
#ifdef CONFIG_SMP
|
||||
percpu PT_LOAD FLAGS(7); /* RWE */
|
||||
#endif
|
||||
data.init2 PT_LOAD FLAGS(7); /* RWE */
|
||||
init PT_LOAD FLAGS(7); /* RWE */
|
||||
#endif
|
||||
note PT_NOTE FLAGS(0); /* ___ */
|
||||
}
|
||||
@ -103,65 +102,43 @@ SECTIONS
|
||||
__stop___ex_table = .;
|
||||
} :text = 0x9090
|
||||
|
||||
RODATA
|
||||
RO_DATA(PAGE_SIZE)
|
||||
|
||||
/* Data */
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
.data : AT(ADDR(.data) - LOAD_OFFSET) {
|
||||
/* Start of data section */
|
||||
_sdata = .;
|
||||
|
||||
/* init_task */
|
||||
INIT_TASK_DATA(THREAD_SIZE)
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/* 32 bit has nosave before _edata */
|
||||
NOSAVE_DATA
|
||||
#endif
|
||||
|
||||
PAGE_ALIGNED_DATA(PAGE_SIZE)
|
||||
*(.data.idt)
|
||||
|
||||
CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES)
|
||||
|
||||
DATA_DATA
|
||||
CONSTRUCTORS
|
||||
} :data
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/* 32 bit has nosave before _edata */
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
|
||||
__nosave_begin = .;
|
||||
*(.data.nosave)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__nosave_end = .;
|
||||
}
|
||||
#endif
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
|
||||
*(.data.page_aligned)
|
||||
*(.data.idt)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
. = ALIGN(32);
|
||||
#else
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
|
||||
#endif
|
||||
.data.cacheline_aligned :
|
||||
AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
|
||||
*(.data.cacheline_aligned)
|
||||
}
|
||||
|
||||
/* rarely changed data like cpu maps */
|
||||
#ifdef CONFIG_X86_32
|
||||
. = ALIGN(32);
|
||||
#else
|
||||
. = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
|
||||
#endif
|
||||
.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
|
||||
*(.data.read_mostly)
|
||||
/* rarely changed data like cpu maps */
|
||||
READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES)
|
||||
|
||||
/* End of data section */
|
||||
_edata = .;
|
||||
}
|
||||
} :data
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
#define VSYSCALL_ADDR (-10*1024*1024)
|
||||
#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + \
|
||||
SIZEOF(.data.read_mostly) + 4095) & ~(4095))
|
||||
#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + \
|
||||
SIZEOF(.data.read_mostly) + 4095) & ~(4095))
|
||||
#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data) + SIZEOF(.data) + \
|
||||
PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
|
||||
#define VSYSCALL_VIRT_ADDR ((ADDR(.data) + SIZEOF(.data) + \
|
||||
PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
|
||||
|
||||
#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
|
||||
#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
|
||||
@ -227,35 +204,29 @@ SECTIONS
|
||||
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
/* init_task */
|
||||
. = ALIGN(THREAD_SIZE);
|
||||
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
|
||||
*(.data.init_task)
|
||||
}
|
||||
#ifdef CONFIG_X86_64
|
||||
:data.init
|
||||
#endif
|
||||
|
||||
/*
|
||||
* smp_locks might be freed after init
|
||||
* start/end must be page aligned
|
||||
*/
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
|
||||
__smp_locks = .;
|
||||
*(.smp_locks)
|
||||
__smp_locks_end = .;
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Init code and data - will be freed after init */
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
|
||||
.init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
|
||||
__init_begin = .; /* paired with __init_end */
|
||||
}
|
||||
|
||||
#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
|
||||
/*
|
||||
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
|
||||
* output PHDR, so the next output section - .init.text - should
|
||||
* start another segment - init.
|
||||
*/
|
||||
PERCPU_VADDR(0, :percpu)
|
||||
#endif
|
||||
|
||||
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
|
||||
_sinittext = .;
|
||||
INIT_TEXT
|
||||
_einittext = .;
|
||||
}
|
||||
#ifdef CONFIG_X86_64
|
||||
:init
|
||||
#endif
|
||||
|
||||
.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
|
||||
INIT_DATA
|
||||
@ -326,17 +297,7 @@ SECTIONS
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
|
||||
/*
|
||||
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
|
||||
* output PHDR, so the next output section - __data_nosave - should
|
||||
* start another section data.init2. Also, pda should be at the head of
|
||||
* percpu area. Preallocate it and define the percpu offset symbol
|
||||
* so that it can be accessed as a percpu variable.
|
||||
*/
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
PERCPU_VADDR(0, :percpu)
|
||||
#else
|
||||
#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
|
||||
PERCPU(PAGE_SIZE)
|
||||
#endif
|
||||
|
||||
@ -347,15 +308,22 @@ SECTIONS
|
||||
__init_end = .;
|
||||
}
|
||||
|
||||
/*
|
||||
* smp_locks might be freed after init
|
||||
* start/end must be page aligned
|
||||
*/
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
|
||||
__smp_locks = .;
|
||||
*(.smp_locks)
|
||||
__smp_locks_end = .;
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__nosave_begin = .;
|
||||
*(.data.nosave)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__nosave_end = .;
|
||||
} :data.init2
|
||||
/* use another section data.init2, see PERCPU_VADDR() above */
|
||||
NOSAVE_DATA
|
||||
}
|
||||
#endif
|
||||
|
||||
/* BSS */
|
||||
|
@ -796,7 +796,7 @@ int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
|
||||
return ret;
|
||||
|
||||
#else
|
||||
reserve_bootmem(phys, len, BOOTMEM_DEFAULT);
|
||||
reserve_bootmem(phys, len, flags);
|
||||
#endif
|
||||
|
||||
if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
|
||||
|
@ -623,7 +623,8 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
|
||||
return ret;
|
||||
|
||||
if (flags != want_flags) {
|
||||
if (strict_prot || !is_new_memtype_allowed(want_flags, flags)) {
|
||||
if (strict_prot ||
|
||||
!is_new_memtype_allowed(paddr, size, want_flags, flags)) {
|
||||
free_memtype(paddr, paddr + size);
|
||||
printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
|
||||
" for %Lx-%Lx, got %s\n",
|
||||
|
@ -183,18 +183,17 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask,
|
||||
|
||||
f->flush_mm = mm;
|
||||
f->flush_va = va;
|
||||
cpumask_andnot(to_cpumask(f->flush_cpumask),
|
||||
cpumask, cpumask_of(smp_processor_id()));
|
||||
if (cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id()))) {
|
||||
/*
|
||||
* We have to send the IPI only to
|
||||
* CPUs affected.
|
||||
*/
|
||||
apic->send_IPI_mask(to_cpumask(f->flush_cpumask),
|
||||
INVALIDATE_TLB_VECTOR_START + sender);
|
||||
|
||||
/*
|
||||
* We have to send the IPI only to
|
||||
* CPUs affected.
|
||||
*/
|
||||
apic->send_IPI_mask(to_cpumask(f->flush_cpumask),
|
||||
INVALIDATE_TLB_VECTOR_START + sender);
|
||||
|
||||
while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
|
||||
cpu_relax();
|
||||
while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
f->flush_mm = NULL;
|
||||
f->flush_va = 0;
|
||||
|
@ -5,6 +5,10 @@ CFLAGS_REMOVE_time.o = -pg
|
||||
CFLAGS_REMOVE_irq.o = -pg
|
||||
endif
|
||||
|
||||
# Make sure early boot has no stackprotector
|
||||
nostackp := $(call cc-option, -fno-stack-protector)
|
||||
CFLAGS_enlighten.o := $(nostackp)
|
||||
|
||||
obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
|
||||
time.o xen-asm.o xen-asm_$(BITS).o \
|
||||
grant-table.o suspend.o
|
||||
|
@ -215,6 +215,7 @@ static __init void xen_init_cpuid_mask(void)
|
||||
(1 << X86_FEATURE_ACPI)); /* disable ACPI */
|
||||
|
||||
ax = 1;
|
||||
cx = 0;
|
||||
xen_cpuid(&ax, &bx, &cx, &dx);
|
||||
|
||||
/* cpuid claims we support xsave; try enabling it to see what happens */
|
||||
@ -974,10 +975,6 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
|
||||
xen_domain_type = XEN_PV_DOMAIN;
|
||||
|
||||
BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0);
|
||||
|
||||
xen_setup_features();
|
||||
|
||||
/* Install Xen paravirt ops */
|
||||
pv_info = xen_info;
|
||||
pv_init_ops = xen_init_ops;
|
||||
@ -986,8 +983,15 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
pv_apic_ops = xen_apic_ops;
|
||||
pv_mmu_ops = xen_mmu_ops;
|
||||
|
||||
xen_init_irq_ops();
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Setup percpu state. We only need to do this for 64-bit
|
||||
* because 32-bit already has %fs set properly.
|
||||
*/
|
||||
load_percpu_segment(0);
|
||||
#endif
|
||||
|
||||
xen_init_irq_ops();
|
||||
xen_init_cpuid_mask();
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
@ -997,6 +1001,8 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
set_xen_basic_apic_ops();
|
||||
#endif
|
||||
|
||||
xen_setup_features();
|
||||
|
||||
if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
|
||||
pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
|
||||
pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
|
||||
@ -1004,13 +1010,6 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
|
||||
machine_ops = xen_machine_ops;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Setup percpu state. We only need to do this for 64-bit
|
||||
* because 32-bit already has %fs set properly.
|
||||
*/
|
||||
load_percpu_segment(0);
|
||||
#endif
|
||||
/*
|
||||
* The only reliable way to retain the initial address of the
|
||||
* percpu gdt_page is to remember it here, so we can go and
|
||||
@ -1061,6 +1060,7 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
/* set up basic CPUID stuff */
|
||||
cpu_detect(&new_cpu_data);
|
||||
new_cpu_data.hard_math = 1;
|
||||
new_cpu_data.wp_works_ok = 1;
|
||||
new_cpu_data.x86_capability[0] = cpuid_edx(1);
|
||||
#endif
|
||||
|
||||
|
@ -70,6 +70,12 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
|
||||
|
||||
/* If Source and Target are the same, just return */
|
||||
|
||||
if (source_desc == target_desc) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/* We know that source_desc is a buffer by now */
|
||||
|
||||
buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
|
||||
@ -161,6 +167,12 @@ acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
|
||||
|
||||
/* If Source and Target are the same, just return */
|
||||
|
||||
if (source_desc == target_desc) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/* We know that source_desc is a string by now */
|
||||
|
||||
buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
|
||||
|
@ -1151,6 +1151,9 @@ static int __init acpi_processor_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (acpi_disabled)
|
||||
return 0;
|
||||
|
||||
memset(&errata, 0, sizeof(errata));
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@ -1197,6 +1200,9 @@ out_proc:
|
||||
|
||||
static void __exit acpi_processor_exit(void)
|
||||
{
|
||||
if (acpi_disabled)
|
||||
return;
|
||||
|
||||
acpi_processor_ppc_exit();
|
||||
|
||||
acpi_thermal_cpufreq_exit();
|
||||
|
@ -162,8 +162,9 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
|
||||
pr->power.timer_broadcast_on_state = state;
|
||||
}
|
||||
|
||||
static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)
|
||||
static void lapic_timer_propagate_broadcast(void *arg)
|
||||
{
|
||||
struct acpi_processor *pr = (struct acpi_processor *) arg;
|
||||
unsigned long reason;
|
||||
|
||||
reason = pr->power.timer_broadcast_on_state < INT_MAX ?
|
||||
@ -635,7 +636,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
|
||||
working++;
|
||||
}
|
||||
|
||||
lapic_timer_propagate_broadcast(pr);
|
||||
smp_call_function_single(pr->id, lapic_timer_propagate_broadcast,
|
||||
pr, 1);
|
||||
|
||||
return (working);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ static int acpi_processor_apply_limit(struct acpi_processor *pr)
|
||||
if (pr->limit.thermal.tx > tx)
|
||||
tx = pr->limit.thermal.tx;
|
||||
|
||||
result = acpi_processor_set_throttling(pr, tx);
|
||||
result = acpi_processor_set_throttling(pr, tx, false);
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
@ -421,12 +421,12 @@ processor_set_cur_state(struct thermal_cooling_device *cdev,
|
||||
|
||||
if (state <= max_pstate) {
|
||||
if (pr->flags.throttling && pr->throttling.state)
|
||||
result = acpi_processor_set_throttling(pr, 0);
|
||||
result = acpi_processor_set_throttling(pr, 0, false);
|
||||
cpufreq_set_cur_state(pr->id, state);
|
||||
} else {
|
||||
cpufreq_set_cur_state(pr->id, max_pstate);
|
||||
result = acpi_processor_set_throttling(pr,
|
||||
state - max_pstate);
|
||||
state - max_pstate, false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -62,7 +62,8 @@ struct throttling_tstate {
|
||||
#define THROTTLING_POSTCHANGE (2)
|
||||
|
||||
static int acpi_processor_get_throttling(struct acpi_processor *pr);
|
||||
int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
|
||||
int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||
int state, bool force);
|
||||
|
||||
static int acpi_processor_update_tsd_coord(void)
|
||||
{
|
||||
@ -361,7 +362,7 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
|
||||
*/
|
||||
target_state = throttling_limit;
|
||||
}
|
||||
return acpi_processor_set_throttling(pr, target_state);
|
||||
return acpi_processor_set_throttling(pr, target_state, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -839,10 +840,10 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
|
||||
if (ret >= 0) {
|
||||
state = acpi_get_throttling_state(pr, value);
|
||||
if (state == -1) {
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Invalid throttling state, reset"));
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Invalid throttling state, reset\n"));
|
||||
state = 0;
|
||||
ret = acpi_processor_set_throttling(pr, state);
|
||||
ret = acpi_processor_set_throttling(pr, state, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -915,7 +916,7 @@ static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
|
||||
}
|
||||
|
||||
static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
|
||||
int state)
|
||||
int state, bool force)
|
||||
{
|
||||
u32 value = 0;
|
||||
u32 duty_mask = 0;
|
||||
@ -930,7 +931,7 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
|
||||
if (!pr->flags.throttling)
|
||||
return -ENODEV;
|
||||
|
||||
if (state == pr->throttling.state)
|
||||
if (!force && (state == pr->throttling.state))
|
||||
return 0;
|
||||
|
||||
if (state < pr->throttling_platform_limit)
|
||||
@ -988,7 +989,7 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
|
||||
}
|
||||
|
||||
static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
|
||||
int state)
|
||||
int state, bool force)
|
||||
{
|
||||
int ret;
|
||||
acpi_integer value;
|
||||
@ -1002,7 +1003,7 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
|
||||
if (!pr->flags.throttling)
|
||||
return -ENODEV;
|
||||
|
||||
if (state == pr->throttling.state)
|
||||
if (!force && (state == pr->throttling.state))
|
||||
return 0;
|
||||
|
||||
if (state < pr->throttling_platform_limit)
|
||||
@ -1018,7 +1019,8 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
|
||||
int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||
int state, bool force)
|
||||
{
|
||||
cpumask_var_t saved_mask;
|
||||
int ret = 0;
|
||||
@ -1070,7 +1072,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
|
||||
/* FIXME: use work_on_cpu() */
|
||||
set_cpus_allowed_ptr(current, cpumask_of(pr->id));
|
||||
ret = p_throttling->acpi_processor_set_throttling(pr,
|
||||
t_state.target_state);
|
||||
t_state.target_state, force);
|
||||
} else {
|
||||
/*
|
||||
* When the T-state coordination is SW_ALL or HW_ALL,
|
||||
@ -1103,7 +1105,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
|
||||
set_cpus_allowed_ptr(current, cpumask_of(i));
|
||||
ret = match_pr->throttling.
|
||||
acpi_processor_set_throttling(
|
||||
match_pr, t_state.target_state);
|
||||
match_pr, t_state.target_state, force);
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -1201,7 +1203,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Disabling throttling (was T%d)\n",
|
||||
pr->throttling.state));
|
||||
result = acpi_processor_set_throttling(pr, 0);
|
||||
result = acpi_processor_set_throttling(pr, 0, false);
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
@ -1307,7 +1309,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
|
||||
if (strcmp(tmpbuf, charp) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
result = acpi_processor_set_throttling(pr, state_val);
|
||||
result = acpi_processor_set_throttling(pr, state_val, false);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
|
@ -2004,8 +2004,11 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
|
||||
status = acpi_remove_notify_handler(device->dev->handle,
|
||||
ACPI_DEVICE_NOTIFY,
|
||||
acpi_video_device_notify);
|
||||
sysfs_remove_link(&device->backlight->dev.kobj, "device");
|
||||
backlight_device_unregister(device->backlight);
|
||||
if (device->backlight) {
|
||||
sysfs_remove_link(&device->backlight->dev.kobj, "device");
|
||||
backlight_device_unregister(device->backlight);
|
||||
device->backlight = NULL;
|
||||
}
|
||||
if (device->cdev) {
|
||||
sysfs_remove_link(&device->dev->dev.kobj,
|
||||
"thermal_cooling");
|
||||
|
@ -664,6 +664,8 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
|
||||
return ata_sff_prereset(link, deadline);
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(piix_lock);
|
||||
|
||||
/**
|
||||
* piix_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
@ -677,8 +679,9 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
|
||||
|
||||
static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
unsigned int pio = adev->pio_mode - XFER_PIO_0;
|
||||
struct pci_dev *dev = to_pci_dev(ap->host->dev);
|
||||
unsigned long flags;
|
||||
unsigned int pio = adev->pio_mode - XFER_PIO_0;
|
||||
unsigned int is_slave = (adev->devno != 0);
|
||||
unsigned int master_port= ap->port_no ? 0x42 : 0x40;
|
||||
unsigned int slave_port = 0x44;
|
||||
@ -708,6 +711,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
if (adev->class == ATA_DEV_ATA)
|
||||
control |= 4; /* PPE enable */
|
||||
|
||||
spin_lock_irqsave(&piix_lock, flags);
|
||||
|
||||
/* PIO configuration clears DTE unconditionally. It will be
|
||||
* programmed in set_dmamode which is guaranteed to be called
|
||||
* after set_piomode if any DMA mode is available.
|
||||
@ -747,6 +752,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
udma_enable &= ~(1 << (2 * ap->port_no + adev->devno));
|
||||
pci_write_config_byte(dev, 0x48, udma_enable);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&piix_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -764,6 +771,7 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, int isich)
|
||||
{
|
||||
struct pci_dev *dev = to_pci_dev(ap->host->dev);
|
||||
unsigned long flags;
|
||||
u8 master_port = ap->port_no ? 0x42 : 0x40;
|
||||
u16 master_data;
|
||||
u8 speed = adev->dma_mode;
|
||||
@ -777,6 +785,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
|
||||
{ 2, 1 },
|
||||
{ 2, 3 }, };
|
||||
|
||||
spin_lock_irqsave(&piix_lock, flags);
|
||||
|
||||
pci_read_config_word(dev, master_port, &master_data);
|
||||
if (ap->udma_mask)
|
||||
pci_read_config_byte(dev, 0x48, &udma_enable);
|
||||
@ -867,6 +877,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
|
||||
/* Don't scribble on 0x48 if the controller does not support UDMA */
|
||||
if (ap->udma_mask)
|
||||
pci_write_config_byte(dev, 0x48, udma_enable);
|
||||
|
||||
spin_unlock_irqrestore(&piix_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,6 +49,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040
|
||||
#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042
|
||||
#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044
|
||||
#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062
|
||||
#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046
|
||||
|
||||
/* cover 915 and 945 variants */
|
||||
@ -81,7 +82,8 @@
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB)
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
|
||||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB)
|
||||
|
||||
extern int agp_memory_reserved;
|
||||
|
||||
@ -1216,6 +1218,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
|
||||
case PCI_DEVICE_ID_INTEL_G41_HB:
|
||||
case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
|
||||
case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
|
||||
case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
|
||||
*gtt_offset = *gtt_size = MB(2);
|
||||
break;
|
||||
default:
|
||||
@ -2195,6 +2198,8 @@ static const struct intel_driver_description {
|
||||
"IGDNG/D", NULL, &intel_i965_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
|
||||
"IGDNG/M", NULL, &intel_i965_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
|
||||
"IGDNG/MA", NULL, &intel_i965_driver },
|
||||
{ 0, 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -2398,6 +2403,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
|
||||
ID(PCI_DEVICE_ID_INTEL_G41_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -508,8 +508,9 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
|
||||
* be obtained while the delayed work queue halt ensures that no more
|
||||
* data is fed to the ldisc.
|
||||
*
|
||||
* In order to wait for any existing references to complete see
|
||||
* tty_ldisc_wait_idle.
|
||||
* You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex)
|
||||
* in order to make sure any currently executing ldisc work is also
|
||||
* flushed.
|
||||
*/
|
||||
|
||||
static int tty_ldisc_halt(struct tty_struct *tty)
|
||||
@ -753,11 +754,14 @@ void tty_ldisc_hangup(struct tty_struct *tty)
|
||||
* N_TTY.
|
||||
*/
|
||||
if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
|
||||
/* Make sure the old ldisc is quiescent */
|
||||
tty_ldisc_halt(tty);
|
||||
flush_scheduled_work();
|
||||
|
||||
/* Avoid racing set_ldisc or tty_ldisc_release */
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
if (tty->ldisc) { /* Not yet closed */
|
||||
/* Switch back to N_TTY */
|
||||
tty_ldisc_halt(tty);
|
||||
tty_ldisc_reinit(tty);
|
||||
/* At this point we have a closed ldisc and we want to
|
||||
reopen it. We could defer this to the next open but
|
||||
|
@ -23,44 +23,50 @@
|
||||
#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
|
||||
#define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
|
||||
|
||||
static struct device_type drm_sysfs_device_minor = {
|
||||
.name = "drm_minor"
|
||||
};
|
||||
|
||||
/**
|
||||
* drm_sysfs_suspend - DRM class suspend hook
|
||||
* drm_class_suspend - DRM class suspend hook
|
||||
* @dev: Linux device to suspend
|
||||
* @state: power state to enter
|
||||
*
|
||||
* Just figures out what the actual struct drm_device associated with
|
||||
* @dev is and calls its suspend hook, if present.
|
||||
*/
|
||||
static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
|
||||
static int drm_class_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct drm_minor *drm_minor = to_drm_minor(dev);
|
||||
struct drm_device *drm_dev = drm_minor->dev;
|
||||
|
||||
if (drm_minor->type == DRM_MINOR_LEGACY &&
|
||||
!drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
|
||||
drm_dev->driver->suspend)
|
||||
return drm_dev->driver->suspend(drm_dev, state);
|
||||
if (dev->type == &drm_sysfs_device_minor) {
|
||||
struct drm_minor *drm_minor = to_drm_minor(dev);
|
||||
struct drm_device *drm_dev = drm_minor->dev;
|
||||
|
||||
if (drm_minor->type == DRM_MINOR_LEGACY &&
|
||||
!drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
|
||||
drm_dev->driver->suspend)
|
||||
return drm_dev->driver->suspend(drm_dev, state);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_sysfs_resume - DRM class resume hook
|
||||
* drm_class_resume - DRM class resume hook
|
||||
* @dev: Linux device to resume
|
||||
*
|
||||
* Just figures out what the actual struct drm_device associated with
|
||||
* @dev is and calls its resume hook, if present.
|
||||
*/
|
||||
static int drm_sysfs_resume(struct device *dev)
|
||||
static int drm_class_resume(struct device *dev)
|
||||
{
|
||||
struct drm_minor *drm_minor = to_drm_minor(dev);
|
||||
struct drm_device *drm_dev = drm_minor->dev;
|
||||
|
||||
if (drm_minor->type == DRM_MINOR_LEGACY &&
|
||||
!drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
|
||||
drm_dev->driver->resume)
|
||||
return drm_dev->driver->resume(drm_dev);
|
||||
if (dev->type == &drm_sysfs_device_minor) {
|
||||
struct drm_minor *drm_minor = to_drm_minor(dev);
|
||||
struct drm_device *drm_dev = drm_minor->dev;
|
||||
|
||||
if (drm_minor->type == DRM_MINOR_LEGACY &&
|
||||
!drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
|
||||
drm_dev->driver->resume)
|
||||
return drm_dev->driver->resume(drm_dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -100,8 +106,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
class->suspend = drm_sysfs_suspend;
|
||||
class->resume = drm_sysfs_resume;
|
||||
class->suspend = drm_class_suspend;
|
||||
class->resume = drm_class_resume;
|
||||
|
||||
err = class_create_file(class, &class_attr_version);
|
||||
if (err)
|
||||
@ -484,6 +490,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
|
||||
minor->kdev.class = drm_class;
|
||||
minor->kdev.release = drm_sysfs_device_release;
|
||||
minor->kdev.devt = minor->device;
|
||||
minor->kdev.type = &drm_sysfs_device_minor;
|
||||
if (minor->type == DRM_MINOR_CONTROL)
|
||||
minor_str = "controlD%d";
|
||||
else if (minor->type == DRM_MINOR_RENDER)
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
ccflags-y := -Iinclude/drm
|
||||
i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
|
||||
i915_debugfs.o \
|
||||
i915_suspend.o \
|
||||
i915_gem.o \
|
||||
i915_gem_debug.o \
|
||||
i915_gem_debugfs.o \
|
||||
i915_gem_tiling.o \
|
||||
intel_display.o \
|
||||
intel_crt.o \
|
||||
|
@ -158,16 +158,37 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
seq_printf(m, "Interrupt enable: %08x\n",
|
||||
I915_READ(IER));
|
||||
seq_printf(m, "Interrupt identity: %08x\n",
|
||||
I915_READ(IIR));
|
||||
seq_printf(m, "Interrupt mask: %08x\n",
|
||||
I915_READ(IMR));
|
||||
seq_printf(m, "Pipe A stat: %08x\n",
|
||||
I915_READ(PIPEASTAT));
|
||||
seq_printf(m, "Pipe B stat: %08x\n",
|
||||
I915_READ(PIPEBSTAT));
|
||||
if (!IS_IGDNG(dev)) {
|
||||
seq_printf(m, "Interrupt enable: %08x\n",
|
||||
I915_READ(IER));
|
||||
seq_printf(m, "Interrupt identity: %08x\n",
|
||||
I915_READ(IIR));
|
||||
seq_printf(m, "Interrupt mask: %08x\n",
|
||||
I915_READ(IMR));
|
||||
seq_printf(m, "Pipe A stat: %08x\n",
|
||||
I915_READ(PIPEASTAT));
|
||||
seq_printf(m, "Pipe B stat: %08x\n",
|
||||
I915_READ(PIPEBSTAT));
|
||||
} else {
|
||||
seq_printf(m, "North Display Interrupt enable: %08x\n",
|
||||
I915_READ(DEIER));
|
||||
seq_printf(m, "North Display Interrupt identity: %08x\n",
|
||||
I915_READ(DEIIR));
|
||||
seq_printf(m, "North Display Interrupt mask: %08x\n",
|
||||
I915_READ(DEIMR));
|
||||
seq_printf(m, "South Display Interrupt enable: %08x\n",
|
||||
I915_READ(SDEIER));
|
||||
seq_printf(m, "South Display Interrupt identity: %08x\n",
|
||||
I915_READ(SDEIIR));
|
||||
seq_printf(m, "South Display Interrupt mask: %08x\n",
|
||||
I915_READ(SDEIMR));
|
||||
seq_printf(m, "Graphics Interrupt enable: %08x\n",
|
||||
I915_READ(GTIER));
|
||||
seq_printf(m, "Graphics Interrupt identity: %08x\n",
|
||||
I915_READ(GTIIR));
|
||||
seq_printf(m, "Graphics Interrupt mask: %08x\n",
|
||||
I915_READ(GTIMR));
|
||||
}
|
||||
seq_printf(m, "Interrupts received: %d\n",
|
||||
atomic_read(&dev_priv->irq_received));
|
||||
if (dev_priv->hw_status_page != NULL) {
|
||||
@ -312,15 +333,13 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
unsigned int head, tail, mask;
|
||||
unsigned int head, tail;
|
||||
|
||||
head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
|
||||
tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
|
||||
mask = dev_priv->ring.tail_mask;
|
||||
|
||||
seq_printf(m, "RingHead : %08x\n", head);
|
||||
seq_printf(m, "RingTail : %08x\n", tail);
|
||||
seq_printf(m, "RingMask : %08x\n", mask);
|
||||
seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size);
|
||||
seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
|
||||
|
||||
@ -363,7 +382,37 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_info_list i915_gem_debugfs_list[] = {
|
||||
static int i915_registers_info(struct seq_file *m, void *data) {
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t reg;
|
||||
|
||||
#define DUMP_RANGE(start, end) \
|
||||
for (reg=start; reg < end; reg += 4) \
|
||||
seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg));
|
||||
|
||||
DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */
|
||||
DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */
|
||||
DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */
|
||||
DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */
|
||||
DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */
|
||||
DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */
|
||||
DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */
|
||||
DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */
|
||||
DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */
|
||||
DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */
|
||||
DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */
|
||||
DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */
|
||||
DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */
|
||||
DUMP_RANGE(0x73000, 0x73fff); /* performance counters */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct drm_info_list i915_debugfs_list[] = {
|
||||
{"i915_regs", i915_registers_info, 0},
|
||||
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
|
||||
{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
|
||||
{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
|
||||
@ -377,19 +426,19 @@ static struct drm_info_list i915_gem_debugfs_list[] = {
|
||||
{"i915_batchbuffers", i915_batchbuffer_info, 0},
|
||||
{"i915_error_state", i915_error_state, 0},
|
||||
};
|
||||
#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
|
||||
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
|
||||
|
||||
int i915_gem_debugfs_init(struct drm_minor *minor)
|
||||
int i915_debugfs_init(struct drm_minor *minor)
|
||||
{
|
||||
return drm_debugfs_create_files(i915_gem_debugfs_list,
|
||||
I915_GEM_DEBUGFS_ENTRIES,
|
||||
return drm_debugfs_create_files(i915_debugfs_list,
|
||||
I915_DEBUGFS_ENTRIES,
|
||||
minor->debugfs_root, minor);
|
||||
}
|
||||
|
||||
void i915_gem_debugfs_cleanup(struct drm_minor *minor)
|
||||
void i915_debugfs_cleanup(struct drm_minor *minor)
|
||||
{
|
||||
drm_debugfs_remove_files(i915_gem_debugfs_list,
|
||||
I915_GEM_DEBUGFS_ENTRIES, minor);
|
||||
drm_debugfs_remove_files(i915_debugfs_list,
|
||||
I915_DEBUGFS_ENTRIES, minor);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
@ -79,6 +79,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* As a ringbuffer is only allowed to wrap between instructions, fill
|
||||
* the tail with NOOPs.
|
||||
*/
|
||||
int i915_wrap_ring(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
volatile unsigned int *virt;
|
||||
int rem;
|
||||
|
||||
rem = dev_priv->ring.Size - dev_priv->ring.tail;
|
||||
if (dev_priv->ring.space < rem) {
|
||||
int ret = i915_wait_ring(dev, rem, __func__);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
dev_priv->ring.space -= rem;
|
||||
|
||||
virt = (unsigned int *)
|
||||
(dev_priv->ring.virtual_start + dev_priv->ring.tail);
|
||||
rem /= 4;
|
||||
while (rem--)
|
||||
*virt++ = MI_NOOP;
|
||||
|
||||
dev_priv->ring.tail = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the hardware status page for devices that need a physical address
|
||||
* in the register.
|
||||
@ -198,7 +226,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
|
||||
}
|
||||
|
||||
dev_priv->ring.Size = init->ring_size;
|
||||
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
|
||||
|
||||
dev_priv->ring.map.offset = init->ring_start;
|
||||
dev_priv->ring.map.size = init->ring_size;
|
||||
|
@ -37,12 +37,15 @@
|
||||
#include <linux/console.h>
|
||||
#include "drm_crtc_helper.h"
|
||||
|
||||
static unsigned int i915_modeset = -1;
|
||||
static int i915_modeset = -1;
|
||||
module_param_named(modeset, i915_modeset, int, 0400);
|
||||
|
||||
unsigned int i915_fbpercrtc = 0;
|
||||
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
|
||||
|
||||
unsigned int i915_powersave = 1;
|
||||
module_param_named(powersave, i915_powersave, int, 0400);
|
||||
|
||||
static struct drm_driver driver;
|
||||
|
||||
static struct pci_device_id pciidlist[] = {
|
||||
@ -188,8 +191,8 @@ static struct drm_driver driver = {
|
||||
.master_create = i915_master_create,
|
||||
.master_destroy = i915_master_destroy,
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
.debugfs_init = i915_gem_debugfs_init,
|
||||
.debugfs_cleanup = i915_gem_debugfs_cleanup,
|
||||
.debugfs_init = i915_debugfs_init,
|
||||
.debugfs_cleanup = i915_debugfs_cleanup,
|
||||
#endif
|
||||
.gem_init_object = i915_gem_init_object,
|
||||
.gem_free_object = i915_gem_free_object,
|
||||
|
@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object {
|
||||
};
|
||||
|
||||
typedef struct _drm_i915_ring_buffer {
|
||||
int tail_mask;
|
||||
unsigned long Size;
|
||||
u8 *virtual_start;
|
||||
int head;
|
||||
@ -222,6 +221,7 @@ typedef struct drm_i915_private {
|
||||
unsigned int edp_support:1;
|
||||
int lvds_ssc_freq;
|
||||
|
||||
int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */
|
||||
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
|
||||
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
|
||||
int num_fence_regs; /* 8 on pre-965, 16 otherwise */
|
||||
@ -310,7 +310,7 @@ typedef struct drm_i915_private {
|
||||
u32 saveIMR;
|
||||
u32 saveCACHE_MODE_0;
|
||||
u32 saveD_STATE;
|
||||
u32 saveCG_2D_DIS;
|
||||
u32 saveDSPCLK_GATE_D;
|
||||
u32 saveMI_ARB_STATE;
|
||||
u32 saveSWF0[16];
|
||||
u32 saveSWF1[16];
|
||||
@ -384,6 +384,9 @@ typedef struct drm_i915_private {
|
||||
*/
|
||||
struct list_head inactive_list;
|
||||
|
||||
/** LRU list of objects with fence regs on them. */
|
||||
struct list_head fence_list;
|
||||
|
||||
/**
|
||||
* List of breadcrumbs associated with GPU requests currently
|
||||
* outstanding.
|
||||
@ -439,6 +442,14 @@ typedef struct drm_i915_private {
|
||||
struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
|
||||
} mm;
|
||||
struct sdvo_device_mapping sdvo_mappings[2];
|
||||
|
||||
/* Reclocking support */
|
||||
bool render_reclock_avail;
|
||||
bool lvds_downclock_avail;
|
||||
struct work_struct idle_work;
|
||||
struct timer_list idle_timer;
|
||||
bool busy;
|
||||
u16 orig_clock;
|
||||
} drm_i915_private_t;
|
||||
|
||||
/** driver private structure attached to each drm_gem_object */
|
||||
@ -451,6 +462,9 @@ struct drm_i915_gem_object {
|
||||
/** This object's place on the active/flushing/inactive lists */
|
||||
struct list_head list;
|
||||
|
||||
/** This object's place on the fenced object LRU */
|
||||
struct list_head fence_list;
|
||||
|
||||
/**
|
||||
* This is set if the object is on the active or flushing lists
|
||||
* (has pending rendering), and is not set if it's on inactive (ready
|
||||
@ -568,6 +582,7 @@ enum intel_chip_family {
|
||||
extern struct drm_ioctl_desc i915_ioctls[];
|
||||
extern int i915_max_ioctl;
|
||||
extern unsigned int i915_fbpercrtc;
|
||||
extern unsigned int i915_powersave;
|
||||
|
||||
extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
|
||||
extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
|
||||
@ -723,8 +738,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len,
|
||||
void i915_dump_lru(struct drm_device *dev, const char *where);
|
||||
|
||||
/* i915_debugfs.c */
|
||||
int i915_gem_debugfs_init(struct drm_minor *minor);
|
||||
void i915_gem_debugfs_cleanup(struct drm_minor *minor);
|
||||
int i915_debugfs_init(struct drm_minor *minor);
|
||||
void i915_debugfs_cleanup(struct drm_minor *minor);
|
||||
|
||||
/* i915_suspend.c */
|
||||
extern int i915_save_state(struct drm_device *dev);
|
||||
@ -774,33 +789,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
|
||||
|
||||
#define I915_VERBOSE 0
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
|
||||
volatile char *virt;
|
||||
#define RING_LOCALS volatile unsigned int *ring_virt__;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I915_VERBOSE) \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \
|
||||
if (dev_priv->ring.space < (n)*4) \
|
||||
i915_wait_ring(dev, (n)*4, __func__); \
|
||||
outcount = 0; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
int bytes__ = 4*(n); \
|
||||
if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \
|
||||
/* a wrap must occur between instructions so pad beforehand */ \
|
||||
if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \
|
||||
i915_wrap_ring(dev); \
|
||||
if (unlikely (dev_priv->ring.space < bytes__)) \
|
||||
i915_wait_ring(dev, bytes__, __func__); \
|
||||
ring_virt__ = (unsigned int *) \
|
||||
(dev_priv->ring.virtual_start + dev_priv->ring.tail); \
|
||||
dev_priv->ring.tail += bytes__; \
|
||||
dev_priv->ring.tail &= dev_priv->ring.Size - 1; \
|
||||
dev_priv->ring.space -= bytes__; \
|
||||
} while (0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
#define OUT_RING(n) do { \
|
||||
if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = (n); \
|
||||
outcount++; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
*ring_virt__++ = (n); \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
dev_priv->ring.space -= outcount * 4; \
|
||||
I915_WRITE(PRB0_TAIL, outring); \
|
||||
if (I915_VERBOSE) \
|
||||
DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \
|
||||
I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
@ -823,6 +837,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
|
||||
#define I915_GEM_HWS_INDEX 0x20
|
||||
#define I915_BREADCRUMB_INDEX 0x21
|
||||
|
||||
extern int i915_wrap_ring(struct drm_device * dev);
|
||||
extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
|
||||
|
||||
#define IS_I830(dev) ((dev)->pci_device == 0x3577)
|
||||
@ -896,6 +911,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
|
||||
/* dsparb controlled by hw only */
|
||||
#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
|
||||
|
||||
#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
|
||||
#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
|
||||
|
||||
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
|
||||
|
||||
#endif
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "drm.h"
|
||||
#include "i915_drm.h"
|
||||
#include "i915_drv.h"
|
||||
#include "intel_drv.h"
|
||||
#include <linux/swap.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
@ -979,8 +980,10 @@ int
|
||||
i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_set_domain *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_i915_gem_object *obj_priv;
|
||||
uint32_t read_domains = args->read_domains;
|
||||
uint32_t write_domain = args->write_domain;
|
||||
int ret;
|
||||
@ -1004,8 +1007,12 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL)
|
||||
return -EBADF;
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
intel_mark_busy(dev, obj);
|
||||
|
||||
#if WATCH_BUF
|
||||
DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n",
|
||||
obj, obj->size, read_domains, write_domain);
|
||||
@ -1013,6 +1020,14 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
if (read_domains & I915_GEM_DOMAIN_GTT) {
|
||||
ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
|
||||
|
||||
/* Update the LRU on the fence for the CPU access that's
|
||||
* about to occur.
|
||||
*/
|
||||
if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
|
||||
list_move_tail(&obj_priv->fence_list,
|
||||
&dev_priv->mm.fence_list);
|
||||
}
|
||||
|
||||
/* Silently promote "you're not bound, there was nothing to do"
|
||||
* to success, since the client was just asking us to
|
||||
* make sure everything was done.
|
||||
@ -1156,8 +1171,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
}
|
||||
|
||||
/* Need a new fence register? */
|
||||
if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
|
||||
obj_priv->tiling_mode != I915_TILING_NONE) {
|
||||
if (obj_priv->tiling_mode != I915_TILING_NONE) {
|
||||
ret = i915_gem_object_get_fence_reg(obj);
|
||||
if (ret) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
@ -2209,6 +2223,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
|
||||
struct drm_i915_gem_object *old_obj_priv = NULL;
|
||||
int i, ret, avail;
|
||||
|
||||
/* Just update our place in the LRU if our fence is getting used. */
|
||||
if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
|
||||
list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (obj_priv->tiling_mode) {
|
||||
case I915_TILING_NONE:
|
||||
WARN(1, "allocating a fence for non-tiled object?\n");
|
||||
@ -2230,7 +2250,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
|
||||
}
|
||||
|
||||
/* First try to find a free reg */
|
||||
try_again:
|
||||
avail = 0;
|
||||
for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
|
||||
reg = &dev_priv->fence_regs[i];
|
||||
@ -2244,63 +2263,62 @@ try_again:
|
||||
|
||||
/* None available, try to steal one or wait for a user to finish */
|
||||
if (i == dev_priv->num_fence_regs) {
|
||||
uint32_t seqno = dev_priv->mm.next_gem_seqno;
|
||||
struct drm_gem_object *old_obj = NULL;
|
||||
|
||||
if (avail == 0)
|
||||
return -ENOSPC;
|
||||
|
||||
for (i = dev_priv->fence_reg_start;
|
||||
i < dev_priv->num_fence_regs; i++) {
|
||||
uint32_t this_seqno;
|
||||
|
||||
reg = &dev_priv->fence_regs[i];
|
||||
old_obj_priv = reg->obj->driver_private;
|
||||
list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list,
|
||||
fence_list) {
|
||||
old_obj = old_obj_priv->obj;
|
||||
|
||||
if (old_obj_priv->pin_count)
|
||||
continue;
|
||||
|
||||
/* Take a reference, as otherwise the wait_rendering
|
||||
* below may cause the object to get freed out from
|
||||
* under us.
|
||||
*/
|
||||
drm_gem_object_reference(old_obj);
|
||||
|
||||
/* i915 uses fences for GPU access to tiled buffers */
|
||||
if (IS_I965G(dev) || !old_obj_priv->active)
|
||||
break;
|
||||
|
||||
/* find the seqno of the first available fence */
|
||||
this_seqno = old_obj_priv->last_rendering_seqno;
|
||||
if (this_seqno != 0 &&
|
||||
reg->obj->write_domain == 0 &&
|
||||
i915_seqno_passed(seqno, this_seqno))
|
||||
seqno = this_seqno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now things get ugly... we have to wait for one of the
|
||||
* objects to finish before trying again.
|
||||
*/
|
||||
if (i == dev_priv->num_fence_regs) {
|
||||
if (seqno == dev_priv->mm.next_gem_seqno) {
|
||||
i915_gem_flush(dev,
|
||||
I915_GEM_GPU_DOMAINS,
|
||||
I915_GEM_GPU_DOMAINS);
|
||||
seqno = i915_add_request(dev, NULL,
|
||||
I915_GEM_GPU_DOMAINS);
|
||||
if (seqno == 0)
|
||||
return -ENOMEM;
|
||||
/* This brings the object to the head of the LRU if it
|
||||
* had been written to. The only way this should
|
||||
* result in us waiting longer than the expected
|
||||
* optimal amount of time is if there was a
|
||||
* fence-using buffer later that was read-only.
|
||||
*/
|
||||
i915_gem_object_flush_gpu_write_domain(old_obj);
|
||||
ret = i915_gem_object_wait_rendering(old_obj);
|
||||
if (ret != 0) {
|
||||
drm_gem_object_unreference(old_obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i915_wait_request(dev, seqno);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto try_again;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zap this virtual mapping so we can set up a fence again
|
||||
* for this object next time we need it.
|
||||
*/
|
||||
i915_gem_release_mmap(reg->obj);
|
||||
i915_gem_release_mmap(old_obj);
|
||||
|
||||
i = old_obj_priv->fence_reg;
|
||||
reg = &dev_priv->fence_regs[i];
|
||||
|
||||
old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
|
||||
list_del_init(&old_obj_priv->fence_list);
|
||||
|
||||
drm_gem_object_unreference(old_obj);
|
||||
}
|
||||
|
||||
obj_priv->fence_reg = i;
|
||||
list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
|
||||
|
||||
reg->obj = obj;
|
||||
|
||||
if (IS_I965G(dev))
|
||||
@ -2343,6 +2361,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
|
||||
|
||||
dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL;
|
||||
obj_priv->fence_reg = I915_FENCE_REG_NONE;
|
||||
list_del_init(&obj_priv->fence_list);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2762,6 +2781,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
|
||||
BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
|
||||
BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
|
||||
|
||||
intel_mark_busy(dev, obj);
|
||||
|
||||
#if WATCH_BUF
|
||||
DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
|
||||
__func__, obj,
|
||||
@ -3596,9 +3617,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
|
||||
* Pre-965 chips need a fence register set up in order to
|
||||
* properly handle tiled surfaces.
|
||||
*/
|
||||
if (!IS_I965G(dev) &&
|
||||
obj_priv->fence_reg == I915_FENCE_REG_NONE &&
|
||||
obj_priv->tiling_mode != I915_TILING_NONE) {
|
||||
if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) {
|
||||
ret = i915_gem_object_get_fence_reg(obj);
|
||||
if (ret != 0) {
|
||||
if (ret != -EBUSY && ret != -ERESTARTSYS)
|
||||
@ -3807,6 +3826,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
|
||||
obj_priv->obj = obj;
|
||||
obj_priv->fence_reg = I915_FENCE_REG_NONE;
|
||||
INIT_LIST_HEAD(&obj_priv->list);
|
||||
INIT_LIST_HEAD(&obj_priv->fence_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4080,7 +4100,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
|
||||
|
||||
/* Set up the kernel mapping for the ring. */
|
||||
ring->Size = obj->size;
|
||||
ring->tail_mask = obj->size - 1;
|
||||
|
||||
ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
|
||||
ring->map.size = obj->size;
|
||||
@ -4254,6 +4273,7 @@ i915_gem_load(struct drm_device *dev)
|
||||
INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.request_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.fence_list);
|
||||
INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
|
||||
i915_gem_retire_work_handler);
|
||||
dev_priv->mm.next_gem_seqno = 1;
|
||||
|
@ -234,7 +234,13 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
|
||||
uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
|
||||
bool need_disable;
|
||||
|
||||
if (!IS_I9XX(dev)) {
|
||||
if (IS_IGDNG(dev)) {
|
||||
/* On IGDNG whatever DRAM config, GPU always do
|
||||
* same swizzling setup.
|
||||
*/
|
||||
swizzle_x = I915_BIT_6_SWIZZLE_9_10;
|
||||
swizzle_y = I915_BIT_6_SWIZZLE_9;
|
||||
} else if (!IS_I9XX(dev)) {
|
||||
/* As far as we know, the 865 doesn't have these bit 6
|
||||
* swizzling issues.
|
||||
*/
|
||||
@ -317,13 +323,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: check with memory config on IGDNG */
|
||||
if (IS_IGDNG(dev)) {
|
||||
DRM_ERROR("disable tiling on IGDNG...\n");
|
||||
swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
|
||||
swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
|
||||
}
|
||||
|
||||
dev_priv->mm.bit_6_swizzle_x = swizzle_x;
|
||||
dev_priv->mm.bit_6_swizzle_y = swizzle_y;
|
||||
}
|
||||
|
@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
|
||||
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
|
||||
I915_READ(PORT_HOTPLUG_STAT);
|
||||
|
||||
/* EOS interrupts occurs */
|
||||
if (IS_IGD(dev) &&
|
||||
(hotplug_status & CRT_EOS_INT_STATUS)) {
|
||||
u32 temp;
|
||||
|
||||
DRM_DEBUG("EOS interrupt occurs\n");
|
||||
/* status is already cleared */
|
||||
temp = I915_READ(ADPA);
|
||||
temp &= ~ADPA_DAC_ENABLE;
|
||||
I915_WRITE(ADPA, temp);
|
||||
|
||||
temp = I915_READ(PORT_HOTPLUG_EN);
|
||||
temp &= ~CRT_EOS_INT_EN;
|
||||
I915_WRITE(PORT_HOTPLUG_EN, temp);
|
||||
|
||||
temp = I915_READ(PORT_HOTPLUG_STAT);
|
||||
if (temp & CRT_EOS_INT_STATUS)
|
||||
I915_WRITE(PORT_HOTPLUG_STAT,
|
||||
CRT_EOS_INT_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
I915_WRITE(IIR, iir);
|
||||
|
@ -55,7 +55,7 @@
|
||||
/* PCI config space */
|
||||
|
||||
#define HPLLCC 0xc0 /* 855 only */
|
||||
#define GC_CLOCK_CONTROL_MASK (3 << 0)
|
||||
#define GC_CLOCK_CONTROL_MASK (0xf << 0)
|
||||
#define GC_CLOCK_133_200 (0 << 0)
|
||||
#define GC_CLOCK_100_200 (1 << 0)
|
||||
#define GC_CLOCK_100_133 (2 << 0)
|
||||
@ -65,6 +65,25 @@
|
||||
#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
|
||||
#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
|
||||
#define GC_DISPLAY_CLOCK_MASK (7 << 4)
|
||||
#define GM45_GC_RENDER_CLOCK_MASK (0xf << 0)
|
||||
#define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0)
|
||||
#define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0)
|
||||
#define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0)
|
||||
#define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0)
|
||||
#define I965_GC_RENDER_CLOCK_MASK (0xf << 0)
|
||||
#define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0)
|
||||
#define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0)
|
||||
#define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0)
|
||||
#define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0)
|
||||
#define I945_GC_RENDER_CLOCK_MASK (7 << 0)
|
||||
#define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0)
|
||||
#define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0)
|
||||
#define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0)
|
||||
#define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0)
|
||||
#define I915_GC_RENDER_CLOCK_MASK (7 << 0)
|
||||
#define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0)
|
||||
#define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0)
|
||||
#define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0)
|
||||
#define LBB 0xf4
|
||||
|
||||
/* VGA stuff */
|
||||
@ -553,9 +572,118 @@
|
||||
#define DPLLA_TEST_M_BYPASS (1 << 2)
|
||||
#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
|
||||
#define D_STATE 0x6104
|
||||
#define CG_2D_DIS 0x6200
|
||||
#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24)
|
||||
#define CG_3D_DIS 0x6204
|
||||
#define DSTATE_PLL_D3_OFF (1<<3)
|
||||
#define DSTATE_GFX_CLOCK_GATING (1<<1)
|
||||
#define DSTATE_DOT_CLOCK_GATING (1<<0)
|
||||
#define DSPCLK_GATE_D 0x6200
|
||||
# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */
|
||||
# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */
|
||||
# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */
|
||||
# define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */
|
||||
# define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */
|
||||
# define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */
|
||||
# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */
|
||||
# define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */
|
||||
# define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */
|
||||
# define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */
|
||||
# define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */
|
||||
# define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */
|
||||
# define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */
|
||||
# define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */
|
||||
# define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */
|
||||
# define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */
|
||||
# define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */
|
||||
# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */
|
||||
# define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */
|
||||
# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11)
|
||||
# define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10)
|
||||
# define DCUNIT_CLOCK_GATE_DISABLE (1 << 9)
|
||||
# define DPUNIT_CLOCK_GATE_DISABLE (1 << 8)
|
||||
# define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */
|
||||
# define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */
|
||||
# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */
|
||||
# define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5)
|
||||
# define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4)
|
||||
/**
|
||||
* This bit must be set on the 830 to prevent hangs when turning off the
|
||||
* overlay scaler.
|
||||
*/
|
||||
# define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3)
|
||||
# define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2)
|
||||
# define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1)
|
||||
# define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */
|
||||
# define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */
|
||||
|
||||
#define RENCLK_GATE_D1 0x6204
|
||||
# define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */
|
||||
# define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */
|
||||
# define PC_FE_CLOCK_GATE_DISABLE (1 << 11)
|
||||
# define PC_BE_CLOCK_GATE_DISABLE (1 << 10)
|
||||
# define WINDOWER_CLOCK_GATE_DISABLE (1 << 9)
|
||||
# define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8)
|
||||
# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7)
|
||||
# define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6)
|
||||
# define MAG_CLOCK_GATE_DISABLE (1 << 5)
|
||||
/** This bit must be unset on 855,865 */
|
||||
# define MECI_CLOCK_GATE_DISABLE (1 << 4)
|
||||
# define DCMP_CLOCK_GATE_DISABLE (1 << 3)
|
||||
# define MEC_CLOCK_GATE_DISABLE (1 << 2)
|
||||
# define MECO_CLOCK_GATE_DISABLE (1 << 1)
|
||||
/** This bit must be set on 855,865. */
|
||||
# define SV_CLOCK_GATE_DISABLE (1 << 0)
|
||||
# define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16)
|
||||
# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15)
|
||||
# define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14)
|
||||
# define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13)
|
||||
# define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12)
|
||||
# define I915_WM_CLOCK_GATE_DISABLE (1 << 11)
|
||||
# define I915_IZ_CLOCK_GATE_DISABLE (1 << 10)
|
||||
# define I915_PI_CLOCK_GATE_DISABLE (1 << 9)
|
||||
# define I915_DI_CLOCK_GATE_DISABLE (1 << 8)
|
||||
# define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7)
|
||||
# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6)
|
||||
# define I915_SC_CLOCK_GATE_DISABLE (1 << 5)
|
||||
# define I915_FL_CLOCK_GATE_DISABLE (1 << 4)
|
||||
# define I915_DM_CLOCK_GATE_DISABLE (1 << 3)
|
||||
# define I915_PS_CLOCK_GATE_DISABLE (1 << 2)
|
||||
# define I915_CC_CLOCK_GATE_DISABLE (1 << 1)
|
||||
# define I915_BY_CLOCK_GATE_DISABLE (1 << 0)
|
||||
|
||||
# define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30)
|
||||
/** This bit must always be set on 965G/965GM */
|
||||
# define I965_RCC_CLOCK_GATE_DISABLE (1 << 29)
|
||||
# define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28)
|
||||
# define I965_DAP_CLOCK_GATE_DISABLE (1 << 27)
|
||||
# define I965_ROC_CLOCK_GATE_DISABLE (1 << 26)
|
||||
# define I965_GW_CLOCK_GATE_DISABLE (1 << 25)
|
||||
# define I965_TD_CLOCK_GATE_DISABLE (1 << 24)
|
||||
/** This bit must always be set on 965G */
|
||||
# define I965_ISC_CLOCK_GATE_DISABLE (1 << 23)
|
||||
# define I965_IC_CLOCK_GATE_DISABLE (1 << 22)
|
||||
# define I965_EU_CLOCK_GATE_DISABLE (1 << 21)
|
||||
# define I965_IF_CLOCK_GATE_DISABLE (1 << 20)
|
||||
# define I965_TC_CLOCK_GATE_DISABLE (1 << 19)
|
||||
# define I965_SO_CLOCK_GATE_DISABLE (1 << 17)
|
||||
# define I965_FBC_CLOCK_GATE_DISABLE (1 << 16)
|
||||
# define I965_MARI_CLOCK_GATE_DISABLE (1 << 15)
|
||||
# define I965_MASF_CLOCK_GATE_DISABLE (1 << 14)
|
||||
# define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13)
|
||||
# define I965_EM_CLOCK_GATE_DISABLE (1 << 12)
|
||||
# define I965_UC_CLOCK_GATE_DISABLE (1 << 11)
|
||||
# define I965_SI_CLOCK_GATE_DISABLE (1 << 6)
|
||||
# define I965_MT_CLOCK_GATE_DISABLE (1 << 5)
|
||||
# define I965_PL_CLOCK_GATE_DISABLE (1 << 4)
|
||||
# define I965_DG_CLOCK_GATE_DISABLE (1 << 3)
|
||||
# define I965_QC_CLOCK_GATE_DISABLE (1 << 2)
|
||||
# define I965_FT_CLOCK_GATE_DISABLE (1 << 1)
|
||||
# define I965_DM_CLOCK_GATE_DISABLE (1 << 0)
|
||||
|
||||
#define RENCLK_GATE_D2 0x6208
|
||||
#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9)
|
||||
#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7)
|
||||
#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6)
|
||||
#define RAMCLK_GATE_D 0x6210 /* CRL only */
|
||||
#define DEUC 0x6214 /* CRL only */
|
||||
|
||||
/*
|
||||
* Palette regs
|
||||
@ -683,6 +811,7 @@
|
||||
#define SDVOB_HOTPLUG_INT_EN (1 << 26)
|
||||
#define SDVOC_HOTPLUG_INT_EN (1 << 25)
|
||||
#define TV_HOTPLUG_INT_EN (1 << 18)
|
||||
#define CRT_EOS_INT_EN (1 << 10)
|
||||
#define CRT_HOTPLUG_INT_EN (1 << 9)
|
||||
#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
|
||||
#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8)
|
||||
@ -717,6 +846,7 @@
|
||||
#define DPC_HOTPLUG_INT_STATUS (1 << 28)
|
||||
#define HDMID_HOTPLUG_INT_STATUS (1 << 27)
|
||||
#define DPD_HOTPLUG_INT_STATUS (1 << 27)
|
||||
#define CRT_EOS_INT_STATUS (1 << 12)
|
||||
#define CRT_HOTPLUG_INT_STATUS (1 << 11)
|
||||
#define TV_HOTPLUG_INT_STATUS (1 << 10)
|
||||
#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
|
||||
@ -1586,6 +1716,7 @@
|
||||
#define PIPECONF_PROGRESSIVE (0 << 21)
|
||||
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
|
||||
#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
|
||||
#define PIPECONF_CXSR_DOWNCLOCK (1<<16)
|
||||
#define PIPEASTAT 0x70024
|
||||
#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
|
||||
#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
|
||||
@ -1733,6 +1864,7 @@
|
||||
#define DISPPLANE_NO_LINE_DOUBLE 0
|
||||
#define DISPPLANE_STEREO_POLARITY_FIRST 0
|
||||
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
|
||||
#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* IGDNG */
|
||||
#define DISPPLANE_TILED (1<<10)
|
||||
#define DSPAADDR 0x70184
|
||||
#define DSPASTRIDE 0x70188
|
||||
@ -1913,6 +2045,9 @@
|
||||
#define GTIIR 0x44018
|
||||
#define GTIER 0x4401c
|
||||
|
||||
#define DISP_ARB_CTL 0x45000
|
||||
#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
|
||||
|
||||
/* PCH */
|
||||
|
||||
/* south display engine interrupt */
|
||||
|
@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev)
|
||||
|
||||
/* Clock gating state */
|
||||
dev_priv->saveD_STATE = I915_READ(D_STATE);
|
||||
dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
|
||||
dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
|
||||
|
||||
/* Cache mode state */
|
||||
dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
|
||||
@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev)
|
||||
|
||||
/* Clock gating state */
|
||||
I915_WRITE (D_STATE, dev_priv->saveD_STATE);
|
||||
I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
|
||||
I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
|
||||
|
||||
/* Cache mode state */
|
||||
I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
|
||||
|
@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u16
|
||||
get_blocksize(void *p)
|
||||
{
|
||||
u16 *block_ptr, block_size;
|
||||
|
||||
block_ptr = (u16 *)((char *)p - 2);
|
||||
block_size = *block_ptr;
|
||||
return block_size;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
|
||||
struct lvds_dvo_timing *dvo_timing)
|
||||
@ -214,6 +224,41 @@ parse_general_features(struct drm_i915_private *dev_priv,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parse_general_definitions(struct drm_i915_private *dev_priv,
|
||||
struct bdb_header *bdb)
|
||||
{
|
||||
struct bdb_general_definitions *general;
|
||||
const int crt_bus_map_table[] = {
|
||||
GPIOB,
|
||||
GPIOA,
|
||||
GPIOC,
|
||||
GPIOD,
|
||||
GPIOE,
|
||||
GPIOF,
|
||||
};
|
||||
|
||||
/* Set sensible defaults in case we can't find the general block
|
||||
or it is the wrong chipset */
|
||||
dev_priv->crt_ddc_bus = -1;
|
||||
|
||||
general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
|
||||
if (general) {
|
||||
u16 block_size = get_blocksize(general);
|
||||
if (block_size >= sizeof(*general)) {
|
||||
int bus_pin = general->crt_ddc_gmbus_pin;
|
||||
DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
|
||||
if ((bus_pin >= 1) && (bus_pin <= 6)) {
|
||||
dev_priv->crt_ddc_bus =
|
||||
crt_bus_map_table[bus_pin-1];
|
||||
}
|
||||
} else {
|
||||
DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
|
||||
block_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
||||
struct bdb_header *bdb)
|
||||
@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
||||
struct bdb_general_definitions *p_defs;
|
||||
struct child_device_config *p_child;
|
||||
int i, child_device_num, count;
|
||||
u16 block_size, *block_ptr;
|
||||
u16 block_size;
|
||||
|
||||
p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
|
||||
if (!p_defs) {
|
||||
@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
|
||||
return;
|
||||
}
|
||||
/* get the block size of general definitions */
|
||||
block_ptr = (u16 *)((char *)p_defs - 2);
|
||||
block_size = *block_ptr;
|
||||
block_size = get_blocksize(p_defs);
|
||||
/* get the number of child device */
|
||||
child_device_num = (block_size - sizeof(*p_defs)) /
|
||||
sizeof(*p_child);
|
||||
@ -311,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv,
|
||||
}
|
||||
|
||||
driver = find_section(bdb, BDB_DRIVER_FEATURES);
|
||||
if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
|
||||
if (!driver)
|
||||
return;
|
||||
|
||||
if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
|
||||
dev_priv->edp_support = 1;
|
||||
|
||||
if (driver->dual_frequency)
|
||||
dev_priv->render_reclock_avail = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -362,6 +412,7 @@ intel_init_bios(struct drm_device *dev)
|
||||
|
||||
/* Grab useful general definitions */
|
||||
parse_general_features(dev_priv, bdb);
|
||||
parse_general_definitions(dev_priv, bdb);
|
||||
parse_lfp_panel_data(dev_priv, bdb);
|
||||
parse_sdvo_panel_data(dev_priv, bdb);
|
||||
parse_sdvo_device_mapping(dev_priv, bdb);
|
||||
|
@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
|
||||
}
|
||||
|
||||
I915_WRITE(reg, temp);
|
||||
|
||||
if (IS_IGD(dev)) {
|
||||
if (mode == DRM_MODE_DPMS_OFF) {
|
||||
/* turn off DAC */
|
||||
temp = I915_READ(PORT_HOTPLUG_EN);
|
||||
temp &= ~CRT_EOS_INT_EN;
|
||||
I915_WRITE(PORT_HOTPLUG_EN, temp);
|
||||
|
||||
temp = I915_READ(PORT_HOTPLUG_STAT);
|
||||
if (temp & CRT_EOS_INT_STATUS)
|
||||
I915_WRITE(PORT_HOTPLUG_STAT,
|
||||
CRT_EOS_INT_STATUS);
|
||||
} else {
|
||||
/* turn on DAC. EOS interrupt must be enabled after DAC
|
||||
* is enabled, so it sounds not good to enable it in
|
||||
* i915_driver_irq_postinstall()
|
||||
* wait 12.5ms after DAC is enabled
|
||||
*/
|
||||
msleep(13);
|
||||
temp = I915_READ(PORT_HOTPLUG_STAT);
|
||||
if (temp & CRT_EOS_INT_STATUS)
|
||||
I915_WRITE(PORT_HOTPLUG_STAT,
|
||||
CRT_EOS_INT_STATUS);
|
||||
temp = I915_READ(PORT_HOTPLUG_EN);
|
||||
temp |= CRT_EOS_INT_EN;
|
||||
I915_WRITE(PORT_HOTPLUG_EN, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int intel_crt_mode_valid(struct drm_connector *connector,
|
||||
@ -508,6 +536,7 @@ void intel_crt_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct intel_output *intel_output;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 i2c_reg;
|
||||
|
||||
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
|
||||
@ -527,8 +556,12 @@ void intel_crt_init(struct drm_device *dev)
|
||||
/* Set up the DDC bus. */
|
||||
if (IS_IGDNG(dev))
|
||||
i2c_reg = PCH_GPIOA;
|
||||
else
|
||||
else {
|
||||
i2c_reg = GPIOA;
|
||||
/* Use VBT information for CRT DDC if available */
|
||||
if (dev_priv->crt_ddc_bus != -1)
|
||||
i2c_reg = dev_priv->crt_ddc_bus;
|
||||
}
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
|
||||
if (!intel_output->ddc_bus) {
|
||||
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
|
||||
@ -537,6 +570,10 @@ void intel_crt_init(struct drm_device *dev)
|
||||
}
|
||||
|
||||
intel_output->type = INTEL_OUTPUT_ANALOG;
|
||||
intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
|
||||
(1 << INTEL_ANALOG_CLONE_BIT) |
|
||||
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
|
||||
intel_output->crtc_mask = (1 << 0) | (1 << 1);
|
||||
connector->interlace_allowed = 0;
|
||||
connector->doublescan_allowed = 0;
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
|
||||
static void intel_update_watermarks(struct drm_device *dev);
|
||||
static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule);
|
||||
|
||||
typedef struct {
|
||||
/* given values */
|
||||
@ -67,6 +68,8 @@ struct intel_limit {
|
||||
intel_p2_t p2;
|
||||
bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
|
||||
int, int, intel_clock_t *);
|
||||
bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
|
||||
int, int, intel_clock_t *);
|
||||
};
|
||||
|
||||
#define I8XX_DOT_MIN 25000
|
||||
@ -261,6 +264,9 @@ static bool
|
||||
intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
int target, int refclk, intel_clock_t *best_clock);
|
||||
static bool
|
||||
intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
int target, int refclk, intel_clock_t *best_clock);
|
||||
static bool
|
||||
intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
int target, int refclk, intel_clock_t *best_clock);
|
||||
static bool
|
||||
@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = {
|
||||
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
|
||||
.p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
|
||||
.find_pll = intel_find_best_PLL,
|
||||
.find_reduced_pll = intel_find_best_reduced_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_i8xx_lvds = {
|
||||
@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = {
|
||||
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
|
||||
.p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
|
||||
.find_pll = intel_find_best_PLL,
|
||||
.find_reduced_pll = intel_find_best_reduced_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_i9xx_sdvo = {
|
||||
@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
|
||||
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
|
||||
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
|
||||
.find_pll = intel_find_best_PLL,
|
||||
.find_reduced_pll = intel_find_best_reduced_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_i9xx_lvds = {
|
||||
@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = {
|
||||
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
|
||||
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
|
||||
.find_pll = intel_find_best_PLL,
|
||||
.find_reduced_pll = intel_find_best_reduced_PLL,
|
||||
};
|
||||
|
||||
/* below parameter and function is for G4X Chipset Family*/
|
||||
@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = {
|
||||
.p2_fast = G4X_P2_SDVO_FAST
|
||||
},
|
||||
.find_pll = intel_g4x_find_best_PLL,
|
||||
.find_reduced_pll = intel_g4x_find_best_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_g4x_hdmi = {
|
||||
@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = {
|
||||
.p2_fast = G4X_P2_HDMI_DAC_FAST
|
||||
},
|
||||
.find_pll = intel_g4x_find_best_PLL,
|
||||
.find_reduced_pll = intel_g4x_find_best_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
|
||||
@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
|
||||
.p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
|
||||
},
|
||||
.find_pll = intel_g4x_find_best_PLL,
|
||||
.find_reduced_pll = intel_g4x_find_best_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
|
||||
@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
|
||||
.p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
|
||||
},
|
||||
.find_pll = intel_g4x_find_best_PLL,
|
||||
.find_reduced_pll = intel_g4x_find_best_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_g4x_display_port = {
|
||||
@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_igd_sdvo = {
|
||||
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
|
||||
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
|
||||
.find_pll = intel_find_best_PLL,
|
||||
.find_reduced_pll = intel_find_best_reduced_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_igd_lvds = {
|
||||
@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_igd_lvds = {
|
||||
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
|
||||
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
|
||||
.find_pll = intel_find_best_PLL,
|
||||
.find_reduced_pll = intel_find_best_reduced_PLL,
|
||||
};
|
||||
|
||||
static const intel_limit_t intel_limits_igdng_sdvo = {
|
||||
@ -666,7 +682,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
intel_clock_t clock;
|
||||
int err = target;
|
||||
|
||||
if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
|
||||
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
|
||||
(I915_READ(LVDS)) != 0) {
|
||||
/*
|
||||
* For LVDS, if the panel is on, just rely on its current
|
||||
@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
|
||||
memset (best_clock, 0, sizeof (*best_clock));
|
||||
|
||||
for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
|
||||
for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
|
||||
/* m1 is always 0 in IGD */
|
||||
if (clock.m2 >= clock.m1 && !IS_IGD(dev))
|
||||
break;
|
||||
for (clock.n = limit->n.min; clock.n <= limit->n.max;
|
||||
clock.n++) {
|
||||
for (clock.p1 = limit->p1.min;
|
||||
clock.p1 <= limit->p1.max; clock.p1++) {
|
||||
for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
|
||||
for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
|
||||
clock.m1++) {
|
||||
for (clock.m2 = limit->m2.min;
|
||||
clock.m2 <= limit->m2.max; clock.m2++) {
|
||||
/* m1 is always 0 in IGD */
|
||||
if (clock.m2 >= clock.m1 && !IS_IGD(dev))
|
||||
break;
|
||||
for (clock.n = limit->n.min;
|
||||
clock.n <= limit->n.max; clock.n++) {
|
||||
int this_err;
|
||||
|
||||
intel_clock(dev, refclk, &clock);
|
||||
@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
return (err != target);
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
int target, int refclk, intel_clock_t *best_clock)
|
||||
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
intel_clock_t clock;
|
||||
int err = target;
|
||||
bool found = false;
|
||||
|
||||
memcpy(&clock, best_clock, sizeof(intel_clock_t));
|
||||
|
||||
for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
|
||||
for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
|
||||
/* m1 is always 0 in IGD */
|
||||
if (clock.m2 >= clock.m1 && !IS_IGD(dev))
|
||||
break;
|
||||
for (clock.n = limit->n.min; clock.n <= limit->n.max;
|
||||
clock.n++) {
|
||||
int this_err;
|
||||
|
||||
intel_clock(dev, refclk, &clock);
|
||||
|
||||
if (!intel_PLL_is_valid(crtc, &clock))
|
||||
continue;
|
||||
|
||||
this_err = abs(clock.dot - target);
|
||||
if (this_err < err) {
|
||||
*best_clock = clock;
|
||||
err = this_err;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
int target, int refclk, intel_clock_t *best_clock)
|
||||
@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
max_n = limit->n.max;
|
||||
/* based on hardware requriment prefer smaller n to precision */
|
||||
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
|
||||
/* based on hardware requirment prefere larger m1,m2, p1 */
|
||||
/* based on hardware requirment prefere larger m1,m2 */
|
||||
for (clock.m1 = limit->m1.max;
|
||||
clock.m1 >= limit->m1.min; clock.m1--) {
|
||||
for (clock.m2 = limit->m2.max;
|
||||
@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
||||
|
||||
memset(best_clock, 0, sizeof(*best_clock));
|
||||
max_n = limit->n.max;
|
||||
/* based on hardware requriment prefer smaller n to precision */
|
||||
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
|
||||
/* based on hardware requirment prefere larger m1,m2, p1 */
|
||||
for (clock.m1 = limit->m1.max;
|
||||
clock.m1 >= limit->m1.min; clock.m1--) {
|
||||
for (clock.m2 = limit->m2.max;
|
||||
clock.m2 >= limit->m2.min; clock.m2--) {
|
||||
for (clock.p1 = limit->p1.max;
|
||||
clock.p1 >= limit->p1.min; clock.p1--) {
|
||||
for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
|
||||
/* based on hardware requriment prefer smaller n to precision */
|
||||
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
|
||||
/* based on hardware requirment prefere larger m1,m2 */
|
||||
for (clock.m1 = limit->m1.max;
|
||||
clock.m1 >= limit->m1.min; clock.m1--) {
|
||||
for (clock.m2 = limit->m2.max;
|
||||
clock.m2 >= limit->m2.min; clock.m2--) {
|
||||
int this_err;
|
||||
|
||||
intel_clock(dev, refclk, &clock);
|
||||
@ -1008,6 +1064,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
dspcntr &= ~DISPPLANE_TILED;
|
||||
}
|
||||
|
||||
if (IS_IGDNG(dev))
|
||||
/* must disable */
|
||||
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
|
||||
|
||||
I915_WRITE(dspcntr_reg, dspcntr);
|
||||
|
||||
Start = obj_priv->gtt_offset;
|
||||
@ -1030,8 +1090,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
|
||||
if (old_fb) {
|
||||
intel_fb = to_intel_framebuffer(old_fb);
|
||||
obj_priv = intel_fb->obj->driver_private;
|
||||
i915_gem_object_unpin(intel_fb->obj);
|
||||
}
|
||||
intel_increase_pllclock(crtc, true);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
if (!dev->primary->master)
|
||||
@ -1581,6 +1644,8 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
else
|
||||
i9xx_crtc_dpms(crtc, mode);
|
||||
|
||||
intel_crtc->dpms_mode = mode;
|
||||
|
||||
if (!dev->primary->master)
|
||||
return;
|
||||
|
||||
@ -1603,8 +1668,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
|
||||
break;
|
||||
}
|
||||
|
||||
intel_crtc->dpms_mode = mode;
|
||||
}
|
||||
|
||||
static void intel_crtc_prepare (struct drm_crtc *crtc)
|
||||
@ -2005,7 +2068,21 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
|
||||
return;
|
||||
}
|
||||
|
||||
const static int latency_ns = 3000; /* default for non-igd platforms */
|
||||
/*
|
||||
* Latency for FIFO fetches is dependent on several factors:
|
||||
* - memory configuration (speed, channels)
|
||||
* - chipset
|
||||
* - current MCH state
|
||||
* It can be fairly high in some situations, so here we assume a fairly
|
||||
* pessimal value. It's a tradeoff between extra memory fetches (if we
|
||||
* set this value too high, the FIFO will fetch frequently to stay full)
|
||||
* and power consumption (set it too low to save power and we might see
|
||||
* FIFO underruns and display "flicker").
|
||||
*
|
||||
* A value of 5us seems to be a good balance; safe for very low end
|
||||
* platforms but not overly aggressive on lower latency configs.
|
||||
*/
|
||||
const static int latency_ns = 5000;
|
||||
|
||||
static int intel_get_fifo_size(struct drm_device *dev, int plane)
|
||||
{
|
||||
@ -2040,6 +2117,18 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane)
|
||||
return size;
|
||||
}
|
||||
|
||||
static void g4x_update_wm(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 fw_blc_self = I915_READ(FW_BLC_SELF);
|
||||
|
||||
if (i915_powersave)
|
||||
fw_blc_self |= FW_BLC_SELF_EN;
|
||||
else
|
||||
fw_blc_self &= ~FW_BLC_SELF_EN;
|
||||
I915_WRITE(FW_BLC_SELF, fw_blc_self);
|
||||
}
|
||||
|
||||
static void i965_update_wm(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
@ -2091,7 +2180,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
|
||||
cwm = 2;
|
||||
|
||||
/* Calc sr entries for one plane configs */
|
||||
if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
|
||||
if (HAS_FW_BLC(dev) && sr_hdisplay &&
|
||||
(!planea_clock || !planeb_clock)) {
|
||||
/* self-refresh has much higher latency */
|
||||
const static int sr_latency_ns = 6000;
|
||||
|
||||
@ -2106,8 +2196,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
|
||||
srwm = total_size - sr_entries;
|
||||
if (srwm < 0)
|
||||
srwm = 1;
|
||||
if (IS_I9XX(dev))
|
||||
I915_WRITE(FW_BLC_SELF, (srwm & 0x3f));
|
||||
I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
|
||||
}
|
||||
|
||||
DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
|
||||
@ -2181,9 +2270,6 @@ static void intel_update_watermarks(struct drm_device *dev)
|
||||
unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
|
||||
int enabled = 0, pixel_size = 0;
|
||||
|
||||
if (DSPARB_HWCONTROL(dev))
|
||||
return;
|
||||
|
||||
/* Get the clock config from both planes */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
intel_crtc = to_intel_crtc(crtc);
|
||||
@ -2216,7 +2302,9 @@ static void intel_update_watermarks(struct drm_device *dev)
|
||||
else if (IS_IGD(dev))
|
||||
igd_disable_cxsr(dev);
|
||||
|
||||
if (IS_I965G(dev))
|
||||
if (IS_G4X(dev))
|
||||
g4x_update_wm(dev);
|
||||
else if (IS_I965G(dev))
|
||||
i965_update_wm(dev);
|
||||
else if (IS_I9XX(dev) || IS_MOBILE(dev))
|
||||
i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay,
|
||||
@ -2250,9 +2338,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
|
||||
int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
|
||||
int refclk, num_outputs = 0;
|
||||
intel_clock_t clock;
|
||||
u32 dpll = 0, fp = 0, dspcntr, pipeconf;
|
||||
bool ok, is_sdvo = false, is_dvo = false;
|
||||
intel_clock_t clock, reduced_clock;
|
||||
u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
|
||||
bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
|
||||
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
|
||||
bool is_edp = false;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
@ -2335,6 +2423,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) {
|
||||
memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
|
||||
has_reduced_clock = limit->find_reduced_pll(limit, crtc,
|
||||
(adjusted_mode->clock*3/4),
|
||||
refclk,
|
||||
&reduced_clock);
|
||||
}
|
||||
|
||||
/* SDVO TV has fixed PLL values depend on its clock range,
|
||||
this mirrors vbios setting. */
|
||||
if (is_sdvo && is_tv) {
|
||||
@ -2380,10 +2476,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
link_bw, &m_n);
|
||||
}
|
||||
|
||||
if (IS_IGD(dev))
|
||||
if (IS_IGD(dev)) {
|
||||
fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
|
||||
else
|
||||
if (has_reduced_clock)
|
||||
fp2 = (1 << reduced_clock.n) << 16 |
|
||||
reduced_clock.m1 << 8 | reduced_clock.m2;
|
||||
} else {
|
||||
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
|
||||
if (has_reduced_clock)
|
||||
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
|
||||
reduced_clock.m2;
|
||||
}
|
||||
|
||||
if (!IS_IGDNG(dev))
|
||||
dpll = DPLL_VGA_MODE_DIS;
|
||||
@ -2396,7 +2499,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
if (is_sdvo) {
|
||||
dpll |= DPLL_DVO_HIGH_SPEED;
|
||||
sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
|
||||
if (IS_I945G(dev) || IS_I945GM(dev))
|
||||
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
|
||||
dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
|
||||
else if (IS_IGDNG(dev))
|
||||
dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
|
||||
@ -2412,6 +2515,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
/* also FPA1 */
|
||||
if (IS_IGDNG(dev))
|
||||
dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
|
||||
if (IS_G4X(dev) && has_reduced_clock)
|
||||
dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
|
||||
}
|
||||
switch (clock.p2) {
|
||||
case 5:
|
||||
@ -2559,6 +2664,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
udelay(150);
|
||||
}
|
||||
|
||||
if (is_lvds && has_reduced_clock && i915_powersave) {
|
||||
I915_WRITE(fp_reg + 4, fp2);
|
||||
intel_crtc->lowfreq_avail = true;
|
||||
if (HAS_PIPE_CXSR(dev)) {
|
||||
DRM_DEBUG("enabling CxSR downclocking\n");
|
||||
pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
|
||||
}
|
||||
} else {
|
||||
I915_WRITE(fp_reg + 4, fp);
|
||||
intel_crtc->lowfreq_avail = false;
|
||||
if (HAS_PIPE_CXSR(dev)) {
|
||||
DRM_DEBUG("disabling CxSR downclocking\n");
|
||||
pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
|
||||
((adjusted_mode->crtc_htotal - 1) << 16));
|
||||
I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
|
||||
@ -2602,6 +2723,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
|
||||
intel_wait_for_vblank(dev);
|
||||
|
||||
if (IS_IGDNG(dev)) {
|
||||
/* enable address swizzle for tiling buffer */
|
||||
temp = I915_READ(DISP_ARB_CTL);
|
||||
I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING);
|
||||
}
|
||||
|
||||
I915_WRITE(dspcntr_reg, dspcntr);
|
||||
|
||||
/* Flush the plane changes */
|
||||
@ -2755,10 +2882,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_framebuffer *intel_fb;
|
||||
int pipe = intel_crtc->pipe;
|
||||
uint32_t temp = 0;
|
||||
uint32_t adder;
|
||||
|
||||
if (crtc->fb) {
|
||||
intel_fb = to_intel_framebuffer(crtc->fb);
|
||||
intel_mark_busy(dev, intel_fb->obj);
|
||||
}
|
||||
|
||||
if (x < 0) {
|
||||
temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
|
||||
x = -x;
|
||||
@ -3056,6 +3189,315 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
|
||||
return mode;
|
||||
}
|
||||
|
||||
#define GPU_IDLE_TIMEOUT 500 /* ms */
|
||||
|
||||
/* When this timer fires, we've been idle for awhile */
|
||||
static void intel_gpu_idle_timer(unsigned long arg)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *)arg;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_DEBUG("idle timer fired, downclocking\n");
|
||||
|
||||
dev_priv->busy = false;
|
||||
|
||||
queue_work(dev_priv->wq, &dev_priv->idle_work);
|
||||
}
|
||||
|
||||
void intel_increase_renderclock(struct drm_device *dev, bool schedule)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if (IS_IGDNG(dev))
|
||||
return;
|
||||
|
||||
if (!dev_priv->render_reclock_avail) {
|
||||
DRM_DEBUG("not reclocking render clock\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Restore render clock frequency to original value */
|
||||
if (IS_G4X(dev) || IS_I9XX(dev))
|
||||
pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
|
||||
else if (IS_I85X(dev))
|
||||
pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
|
||||
DRM_DEBUG("increasing render clock frequency\n");
|
||||
|
||||
/* Schedule downclock */
|
||||
if (schedule)
|
||||
mod_timer(&dev_priv->idle_timer, jiffies +
|
||||
msecs_to_jiffies(GPU_IDLE_TIMEOUT));
|
||||
}
|
||||
|
||||
void intel_decrease_renderclock(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if (IS_IGDNG(dev))
|
||||
return;
|
||||
|
||||
if (!dev_priv->render_reclock_avail) {
|
||||
DRM_DEBUG("not reclocking render clock\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_G4X(dev)) {
|
||||
u16 gcfgc;
|
||||
|
||||
/* Adjust render clock... */
|
||||
pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
|
||||
|
||||
/* Down to minimum... */
|
||||
gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK;
|
||||
gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ;
|
||||
|
||||
pci_write_config_word(dev->pdev, GCFGC, gcfgc);
|
||||
} else if (IS_I965G(dev)) {
|
||||
u16 gcfgc;
|
||||
|
||||
/* Adjust render clock... */
|
||||
pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
|
||||
|
||||
/* Down to minimum... */
|
||||
gcfgc &= ~I965_GC_RENDER_CLOCK_MASK;
|
||||
gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ;
|
||||
|
||||
pci_write_config_word(dev->pdev, GCFGC, gcfgc);
|
||||
} else if (IS_I945G(dev) || IS_I945GM(dev)) {
|
||||
u16 gcfgc;
|
||||
|
||||
/* Adjust render clock... */
|
||||
pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
|
||||
|
||||
/* Down to minimum... */
|
||||
gcfgc &= ~I945_GC_RENDER_CLOCK_MASK;
|
||||
gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ;
|
||||
|
||||
pci_write_config_word(dev->pdev, GCFGC, gcfgc);
|
||||
} else if (IS_I915G(dev)) {
|
||||
u16 gcfgc;
|
||||
|
||||
/* Adjust render clock... */
|
||||
pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
|
||||
|
||||
/* Down to minimum... */
|
||||
gcfgc &= ~I915_GC_RENDER_CLOCK_MASK;
|
||||
gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ;
|
||||
|
||||
pci_write_config_word(dev->pdev, GCFGC, gcfgc);
|
||||
} else if (IS_I85X(dev)) {
|
||||
u16 hpllcc;
|
||||
|
||||
/* Adjust render clock... */
|
||||
pci_read_config_word(dev->pdev, HPLLCC, &hpllcc);
|
||||
|
||||
/* Up to maximum... */
|
||||
hpllcc &= ~GC_CLOCK_CONTROL_MASK;
|
||||
hpllcc |= GC_CLOCK_133_200;
|
||||
|
||||
pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
|
||||
}
|
||||
DRM_DEBUG("decreasing render clock frequency\n");
|
||||
}
|
||||
|
||||
/* Note that no increase function is needed for this - increase_renderclock()
|
||||
* will also rewrite these bits
|
||||
*/
|
||||
void intel_decrease_displayclock(struct drm_device *dev)
|
||||
{
|
||||
if (IS_IGDNG(dev))
|
||||
return;
|
||||
|
||||
if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
|
||||
IS_I915GM(dev)) {
|
||||
u16 gcfgc;
|
||||
|
||||
/* Adjust render clock... */
|
||||
pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
|
||||
|
||||
/* Down to minimum... */
|
||||
gcfgc &= ~0xf0;
|
||||
gcfgc |= 0x80;
|
||||
|
||||
pci_write_config_word(dev->pdev, GCFGC, gcfgc);
|
||||
}
|
||||
}
|
||||
|
||||
#define CRTC_IDLE_TIMEOUT 1000 /* ms */
|
||||
|
||||
static void intel_crtc_idle_timer(unsigned long arg)
|
||||
{
|
||||
struct intel_crtc *intel_crtc = (struct intel_crtc *)arg;
|
||||
struct drm_crtc *crtc = &intel_crtc->base;
|
||||
drm_i915_private_t *dev_priv = crtc->dev->dev_private;
|
||||
|
||||
DRM_DEBUG("idle timer fired, downclocking\n");
|
||||
|
||||
intel_crtc->busy = false;
|
||||
|
||||
queue_work(dev_priv->wq, &dev_priv->idle_work);
|
||||
}
|
||||
|
||||
static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int pipe = intel_crtc->pipe;
|
||||
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
|
||||
int dpll = I915_READ(dpll_reg);
|
||||
|
||||
if (IS_IGDNG(dev))
|
||||
return;
|
||||
|
||||
if (!dev_priv->lvds_downclock_avail)
|
||||
return;
|
||||
|
||||
if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
|
||||
DRM_DEBUG("upclocking LVDS\n");
|
||||
|
||||
/* Unlock panel regs */
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
|
||||
|
||||
dpll &= ~DISPLAY_RATE_SELECT_FPA1;
|
||||
I915_WRITE(dpll_reg, dpll);
|
||||
dpll = I915_READ(dpll_reg);
|
||||
intel_wait_for_vblank(dev);
|
||||
dpll = I915_READ(dpll_reg);
|
||||
if (dpll & DISPLAY_RATE_SELECT_FPA1)
|
||||
DRM_DEBUG("failed to upclock LVDS!\n");
|
||||
|
||||
/* ...and lock them again */
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
|
||||
}
|
||||
|
||||
/* Schedule downclock */
|
||||
if (schedule)
|
||||
mod_timer(&intel_crtc->idle_timer, jiffies +
|
||||
msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
|
||||
}
|
||||
|
||||
static void intel_decrease_pllclock(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int pipe = intel_crtc->pipe;
|
||||
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
|
||||
int dpll = I915_READ(dpll_reg);
|
||||
|
||||
if (IS_IGDNG(dev))
|
||||
return;
|
||||
|
||||
if (!dev_priv->lvds_downclock_avail)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Since this is called by a timer, we should never get here in
|
||||
* the manual case.
|
||||
*/
|
||||
if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
|
||||
DRM_DEBUG("downclocking LVDS\n");
|
||||
|
||||
/* Unlock panel regs */
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
|
||||
|
||||
dpll |= DISPLAY_RATE_SELECT_FPA1;
|
||||
I915_WRITE(dpll_reg, dpll);
|
||||
dpll = I915_READ(dpll_reg);
|
||||
intel_wait_for_vblank(dev);
|
||||
dpll = I915_READ(dpll_reg);
|
||||
if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
|
||||
DRM_DEBUG("failed to downclock LVDS!\n");
|
||||
|
||||
/* ...and lock them again */
|
||||
I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_idle_update - adjust clocks for idleness
|
||||
* @work: work struct
|
||||
*
|
||||
* Either the GPU or display (or both) went idle. Check the busy status
|
||||
* here and adjust the CRTC and GPU clocks as necessary.
|
||||
*/
|
||||
static void intel_idle_update(struct work_struct *work)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
|
||||
idle_work);
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_crtc *intel_crtc;
|
||||
|
||||
if (!i915_powersave)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
/* GPU isn't processing, downclock it. */
|
||||
if (!dev_priv->busy) {
|
||||
intel_decrease_renderclock(dev);
|
||||
intel_decrease_displayclock(dev);
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
/* Skip inactive CRTCs */
|
||||
if (!crtc->fb)
|
||||
continue;
|
||||
|
||||
intel_crtc = to_intel_crtc(crtc);
|
||||
if (!intel_crtc->busy)
|
||||
intel_decrease_pllclock(crtc);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_mark_busy - mark the GPU and possibly the display busy
|
||||
* @dev: drm device
|
||||
* @obj: object we're operating on
|
||||
*
|
||||
* Callers can use this function to indicate that the GPU is busy processing
|
||||
* commands. If @obj matches one of the CRTC objects (i.e. it's a scanout
|
||||
* buffer), we'll also mark the display as busy, so we know to increase its
|
||||
* clock frequency.
|
||||
*/
|
||||
void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
struct intel_framebuffer *intel_fb;
|
||||
struct intel_crtc *intel_crtc;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
return;
|
||||
|
||||
dev_priv->busy = true;
|
||||
intel_increase_renderclock(dev, true);
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (!crtc->fb)
|
||||
continue;
|
||||
|
||||
intel_crtc = to_intel_crtc(crtc);
|
||||
intel_fb = to_intel_framebuffer(crtc->fb);
|
||||
if (intel_fb->obj == obj) {
|
||||
if (!intel_crtc->busy) {
|
||||
/* Non-busy -> busy, upclock */
|
||||
intel_increase_pllclock(crtc, true);
|
||||
intel_crtc->busy = true;
|
||||
} else {
|
||||
/* Busy -> busy, put off timer */
|
||||
mod_timer(&intel_crtc->idle_timer, jiffies +
|
||||
msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
@ -3105,6 +3547,11 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
|
||||
intel_crtc->cursor_addr = 0;
|
||||
intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
|
||||
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
|
||||
|
||||
intel_crtc->busy = false;
|
||||
|
||||
setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
|
||||
(unsigned long)intel_crtc);
|
||||
}
|
||||
|
||||
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
||||
@ -3112,30 +3559,26 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
int pipe = -1;
|
||||
struct drm_mode_object *drmmode_obj;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("called with no initialization\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
if (crtc->base.id == pipe_from_crtc_id->crtc_id) {
|
||||
pipe = intel_crtc->pipe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC);
|
||||
|
||||
if (pipe == -1) {
|
||||
if (!drmmode_obj) {
|
||||
DRM_ERROR("no such CRTC id\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pipe_from_crtc_id->pipe = pipe;
|
||||
crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
|
||||
pipe_from_crtc_id->pipe = crtc->pipe;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
|
||||
@ -3158,7 +3601,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
if (type_mask & (1 << intel_output->type))
|
||||
if (type_mask & intel_output->clone_mask)
|
||||
index_mask |= (1 << entry);
|
||||
entry++;
|
||||
}
|
||||
@ -3206,30 +3649,30 @@ static void intel_setup_outputs(struct drm_device *dev)
|
||||
intel_dp_init(dev, PCH_DP_D);
|
||||
|
||||
} else if (IS_I9XX(dev)) {
|
||||
int found;
|
||||
u32 reg;
|
||||
bool found = false;
|
||||
|
||||
if (I915_READ(SDVOB) & SDVO_DETECTED) {
|
||||
found = intel_sdvo_init(dev, SDVOB);
|
||||
if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
|
||||
intel_hdmi_init(dev, SDVOB);
|
||||
|
||||
if (!found && SUPPORTS_INTEGRATED_DP(dev))
|
||||
intel_dp_init(dev, DP_B);
|
||||
}
|
||||
|
||||
/* Before G4X SDVOC doesn't have its own detect register */
|
||||
if (IS_G4X(dev))
|
||||
reg = SDVOC;
|
||||
else
|
||||
reg = SDVOB;
|
||||
|
||||
if (I915_READ(reg) & SDVO_DETECTED) {
|
||||
if (I915_READ(SDVOB) & SDVO_DETECTED)
|
||||
found = intel_sdvo_init(dev, SDVOC);
|
||||
if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
|
||||
|
||||
if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) {
|
||||
|
||||
if (SUPPORTS_INTEGRATED_HDMI(dev))
|
||||
intel_hdmi_init(dev, SDVOC);
|
||||
if (!found && SUPPORTS_INTEGRATED_DP(dev))
|
||||
if (SUPPORTS_INTEGRATED_DP(dev))
|
||||
intel_dp_init(dev, DP_C);
|
||||
}
|
||||
|
||||
if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
|
||||
intel_dp_init(dev, DP_D);
|
||||
} else
|
||||
@ -3241,51 +3684,10 @@ static void intel_setup_outputs(struct drm_device *dev)
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct drm_encoder *encoder = &intel_output->enc;
|
||||
int crtc_mask = 0, clone_mask = 0;
|
||||
|
||||
/* valid crtcs */
|
||||
switch(intel_output->type) {
|
||||
case INTEL_OUTPUT_HDMI:
|
||||
crtc_mask = ((1 << 0)|
|
||||
(1 << 1));
|
||||
clone_mask = ((1 << INTEL_OUTPUT_HDMI));
|
||||
break;
|
||||
case INTEL_OUTPUT_DVO:
|
||||
case INTEL_OUTPUT_SDVO:
|
||||
crtc_mask = ((1 << 0)|
|
||||
(1 << 1));
|
||||
clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
|
||||
(1 << INTEL_OUTPUT_DVO) |
|
||||
(1 << INTEL_OUTPUT_SDVO));
|
||||
break;
|
||||
case INTEL_OUTPUT_ANALOG:
|
||||
crtc_mask = ((1 << 0)|
|
||||
(1 << 1));
|
||||
clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
|
||||
(1 << INTEL_OUTPUT_DVO) |
|
||||
(1 << INTEL_OUTPUT_SDVO));
|
||||
break;
|
||||
case INTEL_OUTPUT_LVDS:
|
||||
crtc_mask = (1 << 1);
|
||||
clone_mask = (1 << INTEL_OUTPUT_LVDS);
|
||||
break;
|
||||
case INTEL_OUTPUT_TVOUT:
|
||||
crtc_mask = ((1 << 0) |
|
||||
(1 << 1));
|
||||
clone_mask = (1 << INTEL_OUTPUT_TVOUT);
|
||||
break;
|
||||
case INTEL_OUTPUT_DISPLAYPORT:
|
||||
crtc_mask = ((1 << 0) |
|
||||
(1 << 1));
|
||||
clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
|
||||
break;
|
||||
case INTEL_OUTPUT_EDP:
|
||||
crtc_mask = (1 << 1);
|
||||
clone_mask = (1 << INTEL_OUTPUT_EDP);
|
||||
break;
|
||||
}
|
||||
encoder->possible_crtcs = crtc_mask;
|
||||
encoder->possible_clones = intel_connector_clones(dev, clone_mask);
|
||||
encoder->possible_crtcs = intel_output->crtc_mask;
|
||||
encoder->possible_clones = intel_connector_clones(dev,
|
||||
intel_output->clone_mask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3377,8 +3779,56 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
|
||||
.fb_changed = intelfb_probe,
|
||||
};
|
||||
|
||||
void intel_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
/*
|
||||
* Disable clock gating reported to work incorrectly according to the
|
||||
* specs, but enable as much else as we can.
|
||||
*/
|
||||
if (IS_G4X(dev)) {
|
||||
uint32_t dspclk_gate;
|
||||
I915_WRITE(RENCLK_GATE_D1, 0);
|
||||
I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
|
||||
GS_UNIT_CLOCK_GATE_DISABLE |
|
||||
CL_UNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RAMCLK_GATE_D, 0);
|
||||
dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
|
||||
OVRUNIT_CLOCK_GATE_DISABLE |
|
||||
OVCUNIT_CLOCK_GATE_DISABLE;
|
||||
if (IS_GM45(dev))
|
||||
dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
|
||||
I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
|
||||
} else if (IS_I965GM(dev)) {
|
||||
I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RENCLK_GATE_D2, 0);
|
||||
I915_WRITE(DSPCLK_GATE_D, 0);
|
||||
I915_WRITE(RAMCLK_GATE_D, 0);
|
||||
I915_WRITE16(DEUC, 0);
|
||||
} else if (IS_I965G(dev)) {
|
||||
I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
|
||||
I965_RCC_CLOCK_GATE_DISABLE |
|
||||
I965_RCPB_CLOCK_GATE_DISABLE |
|
||||
I965_ISC_CLOCK_GATE_DISABLE |
|
||||
I965_FBC_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(RENCLK_GATE_D2, 0);
|
||||
} else if (IS_I9XX(dev)) {
|
||||
u32 dstate = I915_READ(D_STATE);
|
||||
|
||||
dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
|
||||
DSTATE_DOT_CLOCK_GATING;
|
||||
I915_WRITE(D_STATE, dstate);
|
||||
} else if (IS_I855(dev) || IS_I865G(dev)) {
|
||||
I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
|
||||
} else if (IS_I830(dev)) {
|
||||
I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void intel_modeset_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int num_pipe;
|
||||
int i;
|
||||
|
||||
@ -3413,15 +3863,47 @@ void intel_modeset_init(struct drm_device *dev)
|
||||
DRM_DEBUG("%d display pipe%s available.\n",
|
||||
num_pipe, num_pipe > 1 ? "s" : "");
|
||||
|
||||
if (IS_I85X(dev))
|
||||
pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock);
|
||||
else if (IS_I9XX(dev) || IS_G4X(dev))
|
||||
pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock);
|
||||
|
||||
for (i = 0; i < num_pipe; i++) {
|
||||
intel_crtc_init(dev, i);
|
||||
}
|
||||
|
||||
intel_setup_outputs(dev);
|
||||
|
||||
intel_init_clock_gating(dev);
|
||||
|
||||
INIT_WORK(&dev_priv->idle_work, intel_idle_update);
|
||||
setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
|
||||
(unsigned long)dev);
|
||||
}
|
||||
|
||||
void intel_modeset_cleanup(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_crtc *intel_crtc;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
/* Skip inactive CRTCs */
|
||||
if (!crtc->fb)
|
||||
continue;
|
||||
|
||||
intel_crtc = to_intel_crtc(crtc);
|
||||
intel_increase_pllclock(crtc, false);
|
||||
del_timer_sync(&intel_crtc->idle_timer);
|
||||
}
|
||||
|
||||
intel_increase_renderclock(dev, false);
|
||||
del_timer_sync(&dev_priv->idle_timer);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
drm_mode_config_cleanup(dev);
|
||||
}
|
||||
|
||||
|
@ -1254,6 +1254,18 @@ intel_dp_init(struct drm_device *dev, int output_reg)
|
||||
else
|
||||
intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
|
||||
|
||||
if (output_reg == DP_B)
|
||||
intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
|
||||
else if (output_reg == DP_C)
|
||||
intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
|
||||
else if (output_reg == DP_D)
|
||||
intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
|
||||
|
||||
if (IS_eDP(intel_output)) {
|
||||
intel_output->crtc_mask = (1 << 1);
|
||||
intel_output->clone_mask = (1 << INTEL_OUTPUT_EDP);
|
||||
} else
|
||||
intel_output->crtc_mask = (1 << 0) | (1 << 1);
|
||||
connector->interlace_allowed = true;
|
||||
connector->doublescan_allowed = 0;
|
||||
|
||||
|
@ -57,6 +57,24 @@
|
||||
#define INTEL_OUTPUT_DISPLAYPORT 7
|
||||
#define INTEL_OUTPUT_EDP 8
|
||||
|
||||
/* Intel Pipe Clone Bit */
|
||||
#define INTEL_HDMIB_CLONE_BIT 1
|
||||
#define INTEL_HDMIC_CLONE_BIT 2
|
||||
#define INTEL_HDMID_CLONE_BIT 3
|
||||
#define INTEL_HDMIE_CLONE_BIT 4
|
||||
#define INTEL_HDMIF_CLONE_BIT 5
|
||||
#define INTEL_SDVO_NON_TV_CLONE_BIT 6
|
||||
#define INTEL_SDVO_TV_CLONE_BIT 7
|
||||
#define INTEL_SDVO_LVDS_CLONE_BIT 8
|
||||
#define INTEL_ANALOG_CLONE_BIT 9
|
||||
#define INTEL_TV_CLONE_BIT 10
|
||||
#define INTEL_DP_B_CLONE_BIT 11
|
||||
#define INTEL_DP_C_CLONE_BIT 12
|
||||
#define INTEL_DP_D_CLONE_BIT 13
|
||||
#define INTEL_LVDS_CLONE_BIT 14
|
||||
#define INTEL_DVO_TMDS_CLONE_BIT 15
|
||||
#define INTEL_DVO_LVDS_CLONE_BIT 16
|
||||
|
||||
#define INTEL_DVO_CHIP_NONE 0
|
||||
#define INTEL_DVO_CHIP_LVDS 1
|
||||
#define INTEL_DVO_CHIP_TMDS 2
|
||||
@ -86,6 +104,8 @@ struct intel_output {
|
||||
bool needs_tv_clock;
|
||||
void *dev_priv;
|
||||
void (*hot_plug)(struct intel_output *);
|
||||
int crtc_mask;
|
||||
int clone_mask;
|
||||
};
|
||||
|
||||
struct intel_crtc {
|
||||
@ -96,6 +116,9 @@ struct intel_crtc {
|
||||
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? */
|
||||
struct timer_list idle_timer;
|
||||
bool lowfreq_avail;
|
||||
};
|
||||
|
||||
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
|
||||
@ -114,6 +137,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
|
||||
extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
|
||||
extern void intel_dvo_init(struct drm_device *dev);
|
||||
extern void intel_tv_init(struct drm_device *dev);
|
||||
extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
|
||||
extern void intel_lvds_init(struct drm_device *dev);
|
||||
extern void intel_dp_init(struct drm_device *dev, int dp_reg);
|
||||
void
|
||||
|
@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev)
|
||||
continue;
|
||||
|
||||
intel_output->type = INTEL_OUTPUT_DVO;
|
||||
intel_output->crtc_mask = (1 << 0) | (1 << 1);
|
||||
switch (dvo->type) {
|
||||
case INTEL_DVO_CHIP_TMDS:
|
||||
intel_output->clone_mask =
|
||||
(1 << INTEL_DVO_TMDS_CLONE_BIT) |
|
||||
(1 << INTEL_ANALOG_CLONE_BIT);
|
||||
drm_connector_init(dev, connector,
|
||||
&intel_dvo_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_DVII);
|
||||
encoder_type = DRM_MODE_ENCODER_TMDS;
|
||||
break;
|
||||
case INTEL_DVO_CHIP_LVDS:
|
||||
intel_output->clone_mask =
|
||||
(1 << INTEL_DVO_LVDS_CLONE_BIT);
|
||||
drm_connector_init(dev, connector,
|
||||
&intel_dvo_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
|
@ -230,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
|
||||
|
||||
connector->interlace_allowed = 0;
|
||||
connector->doublescan_allowed = 0;
|
||||
intel_output->crtc_mask = (1 << 0) | (1 << 1);
|
||||
|
||||
/* Set up the DDC bus. */
|
||||
if (sdvox_reg == SDVOB)
|
||||
if (sdvox_reg == SDVOB) {
|
||||
intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
|
||||
else if (sdvox_reg == SDVOC)
|
||||
} else if (sdvox_reg == SDVOC) {
|
||||
intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
|
||||
else if (sdvox_reg == HDMIB)
|
||||
} else if (sdvox_reg == HDMIB) {
|
||||
intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
|
||||
"HDMIB");
|
||||
else if (sdvox_reg == HDMIC)
|
||||
} else if (sdvox_reg == HDMIC) {
|
||||
intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
|
||||
"HDMIC");
|
||||
else if (sdvox_reg == HDMID)
|
||||
} else if (sdvox_reg == HDMID) {
|
||||
intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
|
||||
"HDMID");
|
||||
|
||||
}
|
||||
if (!intel_output->ddc_bus)
|
||||
goto err_connector;
|
||||
|
||||
|
@ -42,11 +42,11 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
|
||||
if (!IS_IGD(dev))
|
||||
return;
|
||||
if (enable)
|
||||
I915_WRITE(CG_2D_DIS,
|
||||
I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE);
|
||||
I915_WRITE(DSPCLK_GATE_D,
|
||||
I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE);
|
||||
else
|
||||
I915_WRITE(CG_2D_DIS,
|
||||
I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE));
|
||||
I915_WRITE(DSPCLK_GATE_D,
|
||||
I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -904,6 +904,8 @@ void intel_lvds_init(struct drm_device *dev)
|
||||
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
|
||||
intel_output->type = INTEL_OUTPUT_LVDS;
|
||||
|
||||
intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
|
||||
intel_output->crtc_mask = (1 << 1);
|
||||
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
|
||||
drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
|
@ -37,6 +37,19 @@
|
||||
#include "intel_sdvo_regs.h"
|
||||
|
||||
#undef SDVO_DEBUG
|
||||
|
||||
static char *tv_format_names[] = {
|
||||
"NTSC_M" , "NTSC_J" , "NTSC_443",
|
||||
"PAL_B" , "PAL_D" , "PAL_G" ,
|
||||
"PAL_H" , "PAL_I" , "PAL_M" ,
|
||||
"PAL_N" , "PAL_NC" , "PAL_60" ,
|
||||
"SECAM_B" , "SECAM_D" , "SECAM_G" ,
|
||||
"SECAM_K" , "SECAM_K1", "SECAM_L" ,
|
||||
"SECAM_60"
|
||||
};
|
||||
|
||||
#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names))
|
||||
|
||||
struct intel_sdvo_priv {
|
||||
u8 slave_addr;
|
||||
|
||||
@ -70,6 +83,15 @@ struct intel_sdvo_priv {
|
||||
*/
|
||||
bool is_tv;
|
||||
|
||||
/* This is for current tv format name */
|
||||
char *tv_format_name;
|
||||
|
||||
/* This contains all current supported TV format */
|
||||
char *tv_format_supported[TV_FORMAT_NUM];
|
||||
int format_supported_num;
|
||||
struct drm_property *tv_format_property;
|
||||
struct drm_property *tv_format_name_property[TV_FORMAT_NUM];
|
||||
|
||||
/**
|
||||
* This is set if we treat the device as HDMI, instead of DVI.
|
||||
*/
|
||||
@ -96,14 +118,6 @@ struct intel_sdvo_priv {
|
||||
*/
|
||||
struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
|
||||
|
||||
/**
|
||||
* Current selected TV format.
|
||||
*
|
||||
* This is stored in the same structure that's passed to the device, for
|
||||
* convenience.
|
||||
*/
|
||||
struct intel_sdvo_tv_format tv_format;
|
||||
|
||||
/*
|
||||
* supported encoding mode, used to determine whether HDMI is
|
||||
* supported
|
||||
@ -113,6 +127,9 @@ struct intel_sdvo_priv {
|
||||
/* DDC bus used by this SDVO output */
|
||||
uint8_t ddc_bus;
|
||||
|
||||
/* Mac mini hack -- use the same DDC as the analog connector */
|
||||
struct i2c_adapter *analog_ddc_bus;
|
||||
|
||||
int save_sdvo_mult;
|
||||
u16 save_active_outputs;
|
||||
struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
|
||||
@ -944,23 +961,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
|
||||
|
||||
static void intel_sdvo_set_tv_format(struct intel_output *output)
|
||||
{
|
||||
struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
|
||||
struct intel_sdvo_tv_format *format, unset;
|
||||
u8 status;
|
||||
|
||||
format = &sdvo_priv->tv_format;
|
||||
memset(&unset, 0, sizeof(unset));
|
||||
if (memcmp(format, &unset, sizeof(*format))) {
|
||||
DRM_DEBUG_KMS("%s: Choosing default TV format of NTSC-M\n",
|
||||
SDVO_NAME(sdvo_priv));
|
||||
format->ntsc_m = 1;
|
||||
intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format,
|
||||
sizeof(*format));
|
||||
status = intel_sdvo_read_response(output, NULL, 0);
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
DRM_DEBUG_KMS("%s: Failed to set TV format\n",
|
||||
SDVO_NAME(sdvo_priv));
|
||||
}
|
||||
struct intel_sdvo_tv_format format;
|
||||
struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
|
||||
uint32_t format_map, i;
|
||||
uint8_t status;
|
||||
|
||||
for (i = 0; i < TV_FORMAT_NUM; i++)
|
||||
if (tv_format_names[i] == sdvo_priv->tv_format_name)
|
||||
break;
|
||||
|
||||
format_map = 1 << i;
|
||||
memset(&format, 0, sizeof(format));
|
||||
memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
|
||||
sizeof(format) : sizeof(format_map));
|
||||
|
||||
intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
|
||||
sizeof(format));
|
||||
|
||||
status = intel_sdvo_read_response(output, NULL, 0);
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
DRM_DEBUG("%s: Failed to set TV format\n",
|
||||
SDVO_NAME(sdvo_priv));
|
||||
}
|
||||
|
||||
static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
|
||||
@ -1457,7 +1479,7 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
|
||||
(SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1))
|
||||
caps++;
|
||||
if (sdvo_priv->caps.output_flags &
|
||||
(SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0))
|
||||
(SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1))
|
||||
caps++;
|
||||
if (sdvo_priv->caps.output_flags &
|
||||
(SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1))
|
||||
@ -1477,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
|
||||
return (caps > 1);
|
||||
}
|
||||
|
||||
static struct drm_connector *
|
||||
intel_find_analog_connector(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct intel_output *intel_output;
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
intel_output = to_intel_output(connector);
|
||||
if (intel_output->type == INTEL_OUTPUT_ANALOG)
|
||||
return connector;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_analog_is_connected(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *analog_connector;
|
||||
analog_connector = intel_find_analog_connector(dev);
|
||||
|
||||
if (!analog_connector)
|
||||
return false;
|
||||
|
||||
if (analog_connector->funcs->detect(analog_connector) ==
|
||||
connector_status_disconnected)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum drm_connector_status
|
||||
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
|
||||
{
|
||||
@ -1487,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
|
||||
|
||||
edid = drm_get_edid(&intel_output->base,
|
||||
intel_output->ddc_bus);
|
||||
|
||||
/* when there is no edid and no monitor is connected with VGA
|
||||
* port, try to use the CRT ddc to read the EDID for DVI-connector
|
||||
*/
|
||||
if (edid == NULL &&
|
||||
sdvo_priv->analog_ddc_bus &&
|
||||
!intel_analog_is_connected(intel_output->base.dev))
|
||||
edid = drm_get_edid(&intel_output->base,
|
||||
sdvo_priv->analog_ddc_bus);
|
||||
if (edid != NULL) {
|
||||
/* Don't report the output as connected if it's a DVI-I
|
||||
* connector with a non-digital EDID coming out.
|
||||
@ -1515,7 +1576,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
|
||||
|
||||
intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
|
||||
intel_sdvo_write_cmd(intel_output,
|
||||
SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
|
||||
status = intel_sdvo_read_response(intel_output, &response, 2);
|
||||
|
||||
DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
|
||||
@ -1539,50 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
|
||||
static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
|
||||
int num_modes;
|
||||
|
||||
/* set the bus switch and get the modes */
|
||||
intel_ddc_get_modes(intel_output);
|
||||
num_modes = intel_ddc_get_modes(intel_output);
|
||||
|
||||
#if 0
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
/* Mac mini hack. On this device, I get DDC through the analog, which
|
||||
* load-detects as disconnected. I fail to DDC through the SDVO DDC,
|
||||
* but it does load-detect as connected. So, just steal the DDC bits
|
||||
* from analog when we fail at finding it the right way.
|
||||
/*
|
||||
* Mac mini hack. On this device, the DVI-I connector shares one DDC
|
||||
* link between analog and digital outputs. So, if the regular SDVO
|
||||
* DDC fails, check to see if the analog output is disconnected, in
|
||||
* which case we'll look there for the digital DDC data.
|
||||
*/
|
||||
crt = xf86_config->output[0];
|
||||
intel_output = crt->driver_private;
|
||||
if (intel_output->type == I830_OUTPUT_ANALOG &&
|
||||
crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
|
||||
I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A");
|
||||
edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus);
|
||||
xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true);
|
||||
if (num_modes == 0 &&
|
||||
sdvo_priv->analog_ddc_bus &&
|
||||
!intel_analog_is_connected(intel_output->base.dev)) {
|
||||
struct i2c_adapter *digital_ddc_bus;
|
||||
|
||||
/* Switch to the analog ddc bus and try that
|
||||
*/
|
||||
digital_ddc_bus = intel_output->ddc_bus;
|
||||
intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
|
||||
|
||||
(void) intel_ddc_get_modes(intel_output);
|
||||
|
||||
intel_output->ddc_bus = digital_ddc_bus;
|
||||
}
|
||||
if (edid_mon) {
|
||||
xf86OutputSetEDID(output, edid_mon);
|
||||
modes = xf86OutputGetEDIDModes(output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks the current TV format, and chooses a default if
|
||||
* it hasn't been set.
|
||||
*/
|
||||
static void
|
||||
intel_sdvo_check_tv_format(struct intel_output *output)
|
||||
{
|
||||
struct intel_sdvo_priv *dev_priv = output->dev_priv;
|
||||
struct intel_sdvo_tv_format format;
|
||||
uint8_t status;
|
||||
|
||||
intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
|
||||
status = intel_sdvo_read_response(output, &format, sizeof(format));
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
memcpy(&dev_priv->tv_format, &format, sizeof(format));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1655,17 +1699,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
|
||||
struct intel_output *output = to_intel_output(connector);
|
||||
struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
|
||||
struct intel_sdvo_sdtv_resolution_request tv_res;
|
||||
uint32_t reply = 0;
|
||||
uint32_t reply = 0, format_map = 0;
|
||||
int i;
|
||||
uint8_t status;
|
||||
int i = 0;
|
||||
|
||||
intel_sdvo_check_tv_format(output);
|
||||
|
||||
/* Read the list of supported input resolutions for the selected TV
|
||||
* format.
|
||||
*/
|
||||
memset(&tv_res, 0, sizeof(tv_res));
|
||||
memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res));
|
||||
for (i = 0; i < TV_FORMAT_NUM; i++)
|
||||
if (tv_format_names[i] == sdvo_priv->tv_format_name)
|
||||
break;
|
||||
|
||||
format_map = (1 << i);
|
||||
memcpy(&tv_res, &format_map,
|
||||
sizeof(struct intel_sdvo_sdtv_resolution_request) >
|
||||
sizeof(format_map) ? sizeof(format_map) :
|
||||
sizeof(struct intel_sdvo_sdtv_resolution_request));
|
||||
|
||||
intel_sdvo_set_target_output(output, sdvo_priv->controlled_output);
|
||||
|
||||
intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
|
||||
&tv_res, sizeof(tv_res));
|
||||
status = intel_sdvo_read_response(output, &reply, 3);
|
||||
@ -1680,6 +1733,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
|
||||
if (nmode)
|
||||
drm_mode_probed_add(connector, nmode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
|
||||
@ -1747,17 +1801,62 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
|
||||
intel_i2c_destroy(intel_output->i2c_bus);
|
||||
if (intel_output->ddc_bus)
|
||||
intel_i2c_destroy(intel_output->ddc_bus);
|
||||
if (sdvo_priv->analog_ddc_bus)
|
||||
intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
|
||||
|
||||
if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
|
||||
drm_mode_destroy(connector->dev,
|
||||
sdvo_priv->sdvo_lvds_fixed_mode);
|
||||
|
||||
if (sdvo_priv->tv_format_property)
|
||||
drm_property_destroy(connector->dev,
|
||||
sdvo_priv->tv_format_property);
|
||||
|
||||
drm_sysfs_connector_remove(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
|
||||
kfree(intel_output);
|
||||
}
|
||||
|
||||
static int
|
||||
intel_sdvo_set_property(struct drm_connector *connector,
|
||||
struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
|
||||
struct drm_encoder *encoder = &intel_output->enc;
|
||||
struct drm_crtc *crtc = encoder->crtc;
|
||||
int ret = 0;
|
||||
bool changed = false;
|
||||
|
||||
ret = drm_connector_property_set_value(connector, property, val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (property == sdvo_priv->tv_format_property) {
|
||||
if (val >= TV_FORMAT_NUM) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (sdvo_priv->tv_format_name ==
|
||||
sdvo_priv->tv_format_supported[val])
|
||||
goto out;
|
||||
|
||||
sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val];
|
||||
changed = true;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (changed && crtc)
|
||||
drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
|
||||
crtc->y, crtc->fb);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
|
||||
.dpms = intel_sdvo_dpms,
|
||||
.mode_fixup = intel_sdvo_mode_fixup,
|
||||
@ -1772,6 +1871,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
|
||||
.restore = intel_sdvo_restore,
|
||||
.detect = intel_sdvo_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = intel_sdvo_set_property,
|
||||
.destroy = intel_sdvo_destroy,
|
||||
};
|
||||
|
||||
@ -1966,6 +2066,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
|
||||
intel_sdvo_set_colorimetry(intel_output,
|
||||
SDVO_COLORIMETRY_RGB256);
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
intel_output->clone_mask =
|
||||
(1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
|
||||
(1 << INTEL_ANALOG_CLONE_BIT);
|
||||
}
|
||||
} else if (flags & SDVO_OUTPUT_SVID0) {
|
||||
|
||||
@ -1974,11 +2077,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
|
||||
sdvo_priv->is_tv = true;
|
||||
intel_output->needs_tv_clock = true;
|
||||
intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
|
||||
} else if (flags & SDVO_OUTPUT_RGB0) {
|
||||
|
||||
sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
|
||||
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_VGA;
|
||||
intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
|
||||
(1 << INTEL_ANALOG_CLONE_BIT);
|
||||
} else if (flags & SDVO_OUTPUT_RGB1) {
|
||||
|
||||
sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
|
||||
@ -1990,12 +2096,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
|
||||
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
|
||||
sdvo_priv->is_lvds = true;
|
||||
intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
|
||||
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
|
||||
} else if (flags & SDVO_OUTPUT_LVDS1) {
|
||||
|
||||
sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
|
||||
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
|
||||
sdvo_priv->is_lvds = true;
|
||||
intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
|
||||
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
|
||||
} else {
|
||||
|
||||
unsigned char bytes[2];
|
||||
@ -2007,6 +2117,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
|
||||
bytes[0], bytes[1]);
|
||||
ret = false;
|
||||
}
|
||||
intel_output->crtc_mask = (1 << 0) | (1 << 1);
|
||||
|
||||
if (ret && registered)
|
||||
ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
|
||||
@ -2016,6 +2127,55 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
|
||||
|
||||
}
|
||||
|
||||
static void intel_sdvo_tv_create_property(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
|
||||
struct intel_sdvo_tv_format format;
|
||||
uint32_t format_map, i;
|
||||
uint8_t status;
|
||||
|
||||
intel_sdvo_set_target_output(intel_output,
|
||||
sdvo_priv->controlled_output);
|
||||
|
||||
intel_sdvo_write_cmd(intel_output,
|
||||
SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
|
||||
status = intel_sdvo_read_response(intel_output,
|
||||
&format, sizeof(format));
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ?
|
||||
sizeof(format_map) : sizeof(format));
|
||||
|
||||
if (format_map == 0)
|
||||
return;
|
||||
|
||||
sdvo_priv->format_supported_num = 0;
|
||||
for (i = 0 ; i < TV_FORMAT_NUM; i++)
|
||||
if (format_map & (1 << i)) {
|
||||
sdvo_priv->tv_format_supported
|
||||
[sdvo_priv->format_supported_num++] =
|
||||
tv_format_names[i];
|
||||
}
|
||||
|
||||
|
||||
sdvo_priv->tv_format_property =
|
||||
drm_property_create(
|
||||
connector->dev, DRM_MODE_PROP_ENUM,
|
||||
"mode", sdvo_priv->format_supported_num);
|
||||
|
||||
for (i = 0; i < sdvo_priv->format_supported_num; i++)
|
||||
drm_property_add_enum(
|
||||
sdvo_priv->tv_format_property, i,
|
||||
i, sdvo_priv->tv_format_supported[i]);
|
||||
|
||||
sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0];
|
||||
drm_connector_attach_property(
|
||||
connector, sdvo_priv->tv_format_property, 0);
|
||||
|
||||
}
|
||||
|
||||
bool intel_sdvo_init(struct drm_device *dev, int output_device)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
@ -2060,10 +2220,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
|
||||
}
|
||||
|
||||
/* setup the DDC bus. */
|
||||
if (output_device == SDVOB)
|
||||
if (output_device == SDVOB) {
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
|
||||
else
|
||||
sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
|
||||
"SDVOB/VGA DDC BUS");
|
||||
} else {
|
||||
intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
|
||||
sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
|
||||
"SDVOC/VGA DDC BUS");
|
||||
}
|
||||
|
||||
if (intel_output->ddc_bus == NULL)
|
||||
goto err_i2c;
|
||||
@ -2097,6 +2262,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
|
||||
drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
|
||||
|
||||
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
|
||||
if (sdvo_priv->is_tv)
|
||||
intel_sdvo_tv_create_property(connector);
|
||||
drm_sysfs_connector_add(connector);
|
||||
|
||||
intel_sdvo_select_ddc_bus(sdvo_priv);
|
||||
@ -2129,6 +2296,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
|
||||
return true;
|
||||
|
||||
err_i2c:
|
||||
if (sdvo_priv->analog_ddc_bus != NULL)
|
||||
intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
|
||||
if (intel_output->ddc_bus != NULL)
|
||||
intel_i2c_destroy(intel_output->ddc_bus);
|
||||
if (intel_output->i2c_bus != NULL)
|
||||
|
@ -1437,6 +1437,35 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we set accurate tv format according to connector type
|
||||
* i.e Component TV should not be assigned by NTSC or PAL
|
||||
*/
|
||||
static void intel_tv_find_better_format(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
|
||||
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
|
||||
int i;
|
||||
|
||||
if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
|
||||
tv_mode->component_only)
|
||||
return;
|
||||
|
||||
|
||||
for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
|
||||
tv_mode = tv_modes + i;
|
||||
|
||||
if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
|
||||
tv_mode->component_only)
|
||||
break;
|
||||
}
|
||||
|
||||
tv_priv->tv_format = tv_mode->name;
|
||||
drm_connector_property_set_value(connector,
|
||||
connector->dev->mode_config.tv_mode_property, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the TV connection.
|
||||
*
|
||||
@ -1473,6 +1502,7 @@ intel_tv_detect(struct drm_connector *connector)
|
||||
if (type < 0)
|
||||
return connector_status_disconnected;
|
||||
|
||||
intel_tv_find_better_format(connector);
|
||||
return connector_status_connected;
|
||||
}
|
||||
|
||||
@ -1718,6 +1748,7 @@ intel_tv_init(struct drm_device *dev)
|
||||
if (!intel_output) {
|
||||
return;
|
||||
}
|
||||
|
||||
connector = &intel_output->base;
|
||||
|
||||
drm_connector_init(dev, connector, &intel_tv_connector_funcs,
|
||||
@ -1729,6 +1760,7 @@ intel_tv_init(struct drm_device *dev)
|
||||
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
|
||||
tv_priv = (struct intel_tv_priv *)(intel_output + 1);
|
||||
intel_output->type = INTEL_OUTPUT_TVOUT;
|
||||
intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
|
||||
intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
|
||||
intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
|
||||
intel_output->dev_priv = tv_priv;
|
||||
|
@ -1140,6 +1140,16 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
||||
tmp |= tile_flags;
|
||||
ib[idx] = tmp;
|
||||
break;
|
||||
case RADEON_RB3D_ZPASS_ADDR:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
|
||||
idx, reg);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
default:
|
||||
/* FIXME: we don't want to allow anyothers packet */
|
||||
break;
|
||||
|
@ -450,6 +450,7 @@ void r300_gpu_init(struct radeon_device *rdev)
|
||||
/* rv350,rv370,rv380 */
|
||||
rdev->num_gb_pipes = 1;
|
||||
}
|
||||
rdev->num_z_pipes = 1;
|
||||
gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16);
|
||||
switch (rdev->num_gb_pipes) {
|
||||
case 2:
|
||||
@ -488,7 +489,8 @@ void r300_gpu_init(struct radeon_device *rdev)
|
||||
printk(KERN_WARNING "Failed to wait MC idle while "
|
||||
"programming pipes. Bad things might happen.\n");
|
||||
}
|
||||
DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes);
|
||||
DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n",
|
||||
rdev->num_gb_pipes, rdev->num_z_pipes);
|
||||
}
|
||||
|
||||
int r300_ga_reset(struct radeon_device *rdev)
|
||||
|
@ -165,7 +165,18 @@ void r420_pipes_init(struct radeon_device *rdev)
|
||||
printk(KERN_WARNING "Failed to wait GUI idle while "
|
||||
"programming pipes. Bad things might happen.\n");
|
||||
}
|
||||
DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes);
|
||||
|
||||
if (rdev->family == CHIP_RV530) {
|
||||
tmp = RREG32(RV530_GB_PIPE_SELECT2);
|
||||
if ((tmp & 3) == 3)
|
||||
rdev->num_z_pipes = 2;
|
||||
else
|
||||
rdev->num_z_pipes = 1;
|
||||
} else
|
||||
rdev->num_z_pipes = 1;
|
||||
|
||||
DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n",
|
||||
rdev->num_gb_pipes, rdev->num_z_pipes);
|
||||
}
|
||||
|
||||
void r420_gpu_init(struct radeon_device *rdev)
|
||||
|
@ -177,7 +177,6 @@ void r520_gpu_init(struct radeon_device *rdev)
|
||||
*/
|
||||
/* workaround for RV530 */
|
||||
if (rdev->family == CHIP_RV530) {
|
||||
WREG32(0x4124, 1);
|
||||
WREG32(0x4128, 0xFF);
|
||||
}
|
||||
r420_pipes_init(rdev);
|
||||
|
@ -655,6 +655,7 @@ struct radeon_device {
|
||||
int usec_timeout;
|
||||
enum radeon_pll_errata pll_errata;
|
||||
int num_gb_pipes;
|
||||
int num_z_pipes;
|
||||
int disp_priority;
|
||||
/* BIOS */
|
||||
uint8_t *bios;
|
||||
|
@ -421,6 +421,15 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
|
||||
{
|
||||
uint32_t gb_tile_config, gb_pipe_sel = 0;
|
||||
|
||||
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
|
||||
uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2);
|
||||
if ((z_pipe_sel & 3) == 3)
|
||||
dev_priv->num_z_pipes = 2;
|
||||
else
|
||||
dev_priv->num_z_pipes = 1;
|
||||
} else
|
||||
dev_priv->num_z_pipes = 1;
|
||||
|
||||
/* RS4xx/RS6xx/R4xx/R5xx */
|
||||
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
|
||||
gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
|
||||
|
@ -103,9 +103,10 @@
|
||||
* 1.28- Add support for VBL on CRTC2
|
||||
* 1.29- R500 3D cmd buffer support
|
||||
* 1.30- Add support for occlusion queries
|
||||
* 1.31- Add support for num Z pipes from GET_PARAM
|
||||
*/
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 30
|
||||
#define DRIVER_MINOR 31
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
/*
|
||||
@ -332,6 +333,7 @@ typedef struct drm_radeon_private {
|
||||
resource_size_t fb_aper_offset;
|
||||
|
||||
int num_gb_pipes;
|
||||
int num_z_pipes;
|
||||
int track_flush;
|
||||
drm_local_map_t *mmio;
|
||||
|
||||
@ -694,6 +696,7 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga
|
||||
|
||||
/* pipe config regs */
|
||||
#define R400_GB_PIPE_SELECT 0x402c
|
||||
#define RV530_GB_PIPE_SELECT2 0x4124
|
||||
#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */
|
||||
#define R300_GB_TILE_CONFIG 0x4018
|
||||
# define R300_ENABLE_TILING (1 << 0)
|
||||
|
@ -274,16 +274,22 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
|
||||
}
|
||||
robj = gobj->driver_private;
|
||||
r = radeon_object_busy_domain(robj, &cur_placement);
|
||||
if (cur_placement == TTM_PL_VRAM)
|
||||
switch (cur_placement) {
|
||||
case TTM_PL_VRAM:
|
||||
args->domain = RADEON_GEM_DOMAIN_VRAM;
|
||||
if (cur_placement == TTM_PL_FLAG_TT)
|
||||
break;
|
||||
case TTM_PL_TT:
|
||||
args->domain = RADEON_GEM_DOMAIN_GTT;
|
||||
if (cur_placement == TTM_PL_FLAG_SYSTEM)
|
||||
break;
|
||||
case TTM_PL_SYSTEM:
|
||||
args->domain = RADEON_GEM_DOMAIN_CPU;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(gobj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
|
||||
|
@ -95,6 +95,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
case RADEON_INFO_NUM_GB_PIPES:
|
||||
value = rdev->num_gb_pipes;
|
||||
break;
|
||||
case RADEON_INFO_NUM_Z_PIPES:
|
||||
value = rdev->num_z_pipes;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG("Invalid request %d\n", info->request);
|
||||
return -EINVAL;
|
||||
@ -318,5 +321,6 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = {
|
||||
DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH),
|
||||
};
|
||||
int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms);
|
||||
|
@ -2337,6 +2337,9 @@
|
||||
# define RADEON_RE_WIDTH_SHIFT 0
|
||||
# define RADEON_RE_HEIGHT_SHIFT 16
|
||||
|
||||
#define RADEON_RB3D_ZPASS_DATA 0x3290
|
||||
#define RADEON_RB3D_ZPASS_ADDR 0x3294
|
||||
|
||||
#define RADEON_SE_CNTL 0x1c4c
|
||||
# define RADEON_FFACE_CULL_CW (0 << 0)
|
||||
# define RADEON_FFACE_CULL_CCW (1 << 0)
|
||||
@ -3571,4 +3574,6 @@
|
||||
#define RADEON_SCRATCH_REG4 0x15f0
|
||||
#define RADEON_SCRATCH_REG5 0x15f4
|
||||
|
||||
#define RV530_GB_PIPE_SELECT2 0x4124
|
||||
|
||||
#endif
|
||||
|
@ -3081,6 +3081,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
|
||||
case RADEON_PARAM_NUM_GB_PIPES:
|
||||
value = dev_priv->num_gb_pipes;
|
||||
break;
|
||||
case RADEON_PARAM_NUM_Z_PIPES:
|
||||
value = dev_priv->num_z_pipes;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG("Invalid parameter %d\n", param->param);
|
||||
return -EINVAL;
|
||||
|
@ -674,7 +674,14 @@ omap_i2c_isr(int this_irq, void *dev_id)
|
||||
|
||||
err = 0;
|
||||
complete:
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
|
||||
/*
|
||||
* Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
|
||||
* acked after the data operation is complete.
|
||||
* Ref: TRM SWPU114Q Figure 18-31
|
||||
*/
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
|
||||
~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
|
||||
OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
|
||||
|
||||
if (stat & OMAP_I2C_STAT_NACK) {
|
||||
err |= OMAP_I2C_STAT_NACK;
|
||||
@ -687,6 +694,9 @@ complete:
|
||||
}
|
||||
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
|
||||
OMAP_I2C_STAT_AL)) {
|
||||
omap_i2c_ack_stat(dev, stat &
|
||||
(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
|
||||
OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
|
||||
omap_i2c_complete_cmd(dev, err);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -774,7 +784,7 @@ complete:
|
||||
* memory to the I2C interface.
|
||||
*/
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
if (dev->rev <= OMAP_I2C_REV_ON_3430) {
|
||||
while (!(stat & OMAP_I2C_STAT_XUDF)) {
|
||||
if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
|
||||
omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
|
||||
|
@ -117,7 +117,8 @@ enum stu300_error {
|
||||
STU300_ERROR_NONE = 0,
|
||||
STU300_ERROR_ACKNOWLEDGE_FAILURE,
|
||||
STU300_ERROR_BUS_ERROR,
|
||||
STU300_ERROR_ARBITRATION_LOST
|
||||
STU300_ERROR_ARBITRATION_LOST,
|
||||
STU300_ERROR_UNKNOWN
|
||||
};
|
||||
|
||||
/* timeout waiting for the controller to respond */
|
||||
@ -127,7 +128,7 @@ enum stu300_error {
|
||||
* The number of address send athemps tried before giving up.
|
||||
* If the first one failes it seems like 5 to 8 attempts are required.
|
||||
*/
|
||||
#define NUM_ADDR_RESEND_ATTEMPTS 10
|
||||
#define NUM_ADDR_RESEND_ATTEMPTS 12
|
||||
|
||||
/* I2C clock speed, in Hz 0-400kHz*/
|
||||
static unsigned int scl_frequency = 100000;
|
||||
@ -149,6 +150,7 @@ module_param(scl_frequency, uint, 0644);
|
||||
* @msg_index: index of current message
|
||||
* @msg_len: length of current message
|
||||
*/
|
||||
|
||||
struct stu300_dev {
|
||||
struct platform_device *pdev;
|
||||
struct i2c_adapter adapter;
|
||||
@ -188,6 +190,27 @@ static inline u32 stu300_r8(void __iomem *address)
|
||||
return readl(address) & 0x000000FFU;
|
||||
}
|
||||
|
||||
static void stu300_irq_enable(struct stu300_dev *dev)
|
||||
{
|
||||
u32 val;
|
||||
val = stu300_r8(dev->virtbase + I2C_CR);
|
||||
val |= I2C_CR_INTERRUPT_ENABLE;
|
||||
/* Twice paranoia (possible HW glitch) */
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
}
|
||||
|
||||
static void stu300_irq_disable(struct stu300_dev *dev)
|
||||
{
|
||||
u32 val;
|
||||
val = stu300_r8(dev->virtbase + I2C_CR);
|
||||
val &= ~I2C_CR_INTERRUPT_ENABLE;
|
||||
/* Twice paranoia (possible HW glitch) */
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tells whether a certain event or events occurred in
|
||||
* response to a command. The events represent states in
|
||||
@ -196,9 +219,10 @@ static inline u32 stu300_r8(void __iomem *address)
|
||||
* documentation and can only be treated as abstract state
|
||||
* machine states.
|
||||
*
|
||||
* @ret 0 = event has not occurred, any other value means
|
||||
* the event occurred.
|
||||
* @ret 0 = event has not occurred or unknown error, any
|
||||
* other value means the correct event occurred or an error.
|
||||
*/
|
||||
|
||||
static int stu300_event_occurred(struct stu300_dev *dev,
|
||||
enum stu300_event mr_event) {
|
||||
u32 status1;
|
||||
@ -206,11 +230,28 @@ static int stu300_event_occurred(struct stu300_dev *dev,
|
||||
|
||||
/* What event happened? */
|
||||
status1 = stu300_r8(dev->virtbase + I2C_SR1);
|
||||
|
||||
if (!(status1 & I2C_SR1_EVF_IND))
|
||||
/* No event at all */
|
||||
return 0;
|
||||
|
||||
status2 = stu300_r8(dev->virtbase + I2C_SR2);
|
||||
|
||||
/* Block any multiple interrupts */
|
||||
stu300_irq_disable(dev);
|
||||
|
||||
/* Check for errors first */
|
||||
if (status2 & I2C_SR2_AF_IND) {
|
||||
dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;
|
||||
return 1;
|
||||
} else if (status2 & I2C_SR2_BERR_IND) {
|
||||
dev->cmd_err = STU300_ERROR_BUS_ERROR;
|
||||
return 1;
|
||||
} else if (status2 & I2C_SR2_ARLO_IND) {
|
||||
dev->cmd_err = STU300_ERROR_ARBITRATION_LOST;
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (mr_event) {
|
||||
case STU300_EVENT_1:
|
||||
if (status1 & I2C_SR1_ADSL_IND)
|
||||
@ -221,10 +262,6 @@ static int stu300_event_occurred(struct stu300_dev *dev,
|
||||
case STU300_EVENT_7:
|
||||
case STU300_EVENT_8:
|
||||
if (status1 & I2C_SR1_BTF_IND) {
|
||||
if (status2 & I2C_SR2_AF_IND)
|
||||
dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;
|
||||
else if (status2 & I2C_SR2_BERR_IND)
|
||||
dev->cmd_err = STU300_ERROR_BUS_ERROR;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@ -240,8 +277,6 @@ static int stu300_event_occurred(struct stu300_dev *dev,
|
||||
case STU300_EVENT_6:
|
||||
if (status2 & I2C_SR2_ENDAD_IND) {
|
||||
/* First check for any errors */
|
||||
if (status2 & I2C_SR2_AF_IND)
|
||||
dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@ -252,8 +287,15 @@ static int stu300_event_occurred(struct stu300_dev *dev,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (status2 & I2C_SR2_ARLO_IND)
|
||||
dev->cmd_err = STU300_ERROR_ARBITRATION_LOST;
|
||||
/* If we get here, we're on thin ice.
|
||||
* Here we are in a status where we have
|
||||
* gotten a response that does not match
|
||||
* what we requested.
|
||||
*/
|
||||
dev->cmd_err = STU300_ERROR_UNKNOWN;
|
||||
dev_err(&dev->pdev->dev,
|
||||
"Unhandled interrupt! %d sr1: 0x%x sr2: 0x%x\n",
|
||||
mr_event, status1, status2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -262,21 +304,20 @@ static irqreturn_t stu300_irh(int irq, void *data)
|
||||
struct stu300_dev *dev = data;
|
||||
int res;
|
||||
|
||||
/* Just make sure that the block is clocked */
|
||||
clk_enable(dev->clk);
|
||||
|
||||
/* See if this was what we were waiting for */
|
||||
spin_lock(&dev->cmd_issue_lock);
|
||||
if (dev->cmd_event != STU300_EVENT_NONE) {
|
||||
res = stu300_event_occurred(dev, dev->cmd_event);
|
||||
if (res || dev->cmd_err != STU300_ERROR_NONE) {
|
||||
u32 val;
|
||||
|
||||
complete(&dev->cmd_complete);
|
||||
/* Block any multiple interrupts */
|
||||
val = stu300_r8(dev->virtbase + I2C_CR);
|
||||
val &= ~I2C_CR_INTERRUPT_ENABLE;
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
}
|
||||
}
|
||||
res = stu300_event_occurred(dev, dev->cmd_event);
|
||||
if (res || dev->cmd_err != STU300_ERROR_NONE)
|
||||
complete(&dev->cmd_complete);
|
||||
|
||||
spin_unlock(&dev->cmd_issue_lock);
|
||||
|
||||
clk_disable(dev->clk);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -308,7 +349,6 @@ static int stu300_start_and_await_event(struct stu300_dev *dev,
|
||||
stu300_wr8(cr_value, dev->virtbase + I2C_CR);
|
||||
ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
|
||||
STU300_TIMEOUT);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&dev->pdev->dev,
|
||||
"wait_for_completion_interruptible_timeout() "
|
||||
@ -342,7 +382,6 @@ static int stu300_await_event(struct stu300_dev *dev,
|
||||
enum stu300_event mr_event)
|
||||
{
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
if (unlikely(irqs_disabled())) {
|
||||
/* TODO: implement polling for this case if need be. */
|
||||
@ -354,36 +393,18 @@ static int stu300_await_event(struct stu300_dev *dev,
|
||||
/* Is it already here? */
|
||||
spin_lock_irq(&dev->cmd_issue_lock);
|
||||
dev->cmd_err = STU300_ERROR_NONE;
|
||||
if (stu300_event_occurred(dev, mr_event)) {
|
||||
spin_unlock_irq(&dev->cmd_issue_lock);
|
||||
goto exit_await_check_err;
|
||||
}
|
||||
init_completion(&dev->cmd_complete);
|
||||
dev->cmd_err = STU300_ERROR_NONE;
|
||||
dev->cmd_event = mr_event;
|
||||
|
||||
init_completion(&dev->cmd_complete);
|
||||
|
||||
/* Turn on the I2C interrupt for current operation */
|
||||
val = stu300_r8(dev->virtbase + I2C_CR);
|
||||
val |= I2C_CR_INTERRUPT_ENABLE;
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
|
||||
/* Twice paranoia (possible HW glitch) */
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
|
||||
/* Check again: is it already here? */
|
||||
if (unlikely(stu300_event_occurred(dev, mr_event))) {
|
||||
/* Disable IRQ again. */
|
||||
val &= ~I2C_CR_INTERRUPT_ENABLE;
|
||||
stu300_wr8(val, dev->virtbase + I2C_CR);
|
||||
spin_unlock_irq(&dev->cmd_issue_lock);
|
||||
goto exit_await_check_err;
|
||||
}
|
||||
stu300_irq_enable(dev);
|
||||
|
||||
/* Unlock the command block and wait for the event to occur */
|
||||
spin_unlock_irq(&dev->cmd_issue_lock);
|
||||
|
||||
ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
|
||||
STU300_TIMEOUT);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&dev->pdev->dev,
|
||||
"wait_for_completion_interruptible_timeout()"
|
||||
@ -401,7 +422,6 @@ static int stu300_await_event(struct stu300_dev *dev,
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
exit_await_check_err:
|
||||
if (dev->cmd_err != STU300_ERROR_NONE) {
|
||||
if (mr_event != STU300_EVENT_6) {
|
||||
dev_err(&dev->pdev->dev, "controller "
|
||||
@ -457,18 +477,19 @@ struct stu300_clkset {
|
||||
};
|
||||
|
||||
static const struct stu300_clkset stu300_clktable[] = {
|
||||
{ 0, 0xFFU },
|
||||
{ 2500000, I2C_OAR2_FR_25_10MHZ },
|
||||
{ 10000000, I2C_OAR2_FR_10_1667MHZ },
|
||||
{ 16670000, I2C_OAR2_FR_1667_2667MHZ },
|
||||
{ 26670000, I2C_OAR2_FR_2667_40MHZ },
|
||||
{ 40000000, I2C_OAR2_FR_40_5333MHZ },
|
||||
{ 53330000, I2C_OAR2_FR_5333_66MHZ },
|
||||
{ 66000000, I2C_OAR2_FR_66_80MHZ },
|
||||
{ 80000000, I2C_OAR2_FR_80_100MHZ },
|
||||
{ 0, 0xFFU },
|
||||
{ 2500000, I2C_OAR2_FR_25_10MHZ },
|
||||
{ 10000000, I2C_OAR2_FR_10_1667MHZ },
|
||||
{ 16670000, I2C_OAR2_FR_1667_2667MHZ },
|
||||
{ 26670000, I2C_OAR2_FR_2667_40MHZ },
|
||||
{ 40000000, I2C_OAR2_FR_40_5333MHZ },
|
||||
{ 53330000, I2C_OAR2_FR_5333_66MHZ },
|
||||
{ 66000000, I2C_OAR2_FR_66_80MHZ },
|
||||
{ 80000000, I2C_OAR2_FR_80_100MHZ },
|
||||
{ 100000000, 0xFFU },
|
||||
};
|
||||
|
||||
|
||||
static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
|
||||
{
|
||||
|
||||
@ -494,10 +515,10 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
|
||||
|
||||
if (dev->speed > 100000)
|
||||
/* Fast Mode I2C */
|
||||
val = ((clkrate/dev->speed)-9)/3;
|
||||
val = ((clkrate/dev->speed) - 9)/3 + 1;
|
||||
else
|
||||
/* Standard Mode I2C */
|
||||
val = ((clkrate/dev->speed)-7)/2;
|
||||
val = ((clkrate/dev->speed) - 7)/2 + 1;
|
||||
|
||||
/* According to spec the divider must be > 2 */
|
||||
if (val < 0x002) {
|
||||
@ -557,6 +578,7 @@ static int stu300_init_hw(struct stu300_dev *dev)
|
||||
*/
|
||||
clkrate = clk_get_rate(dev->clk);
|
||||
ret = stu300_set_clk(dev, clkrate);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
@ -641,7 +663,6 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,
|
||||
int attempts = 0;
|
||||
struct stu300_dev *dev = i2c_get_adapdata(adap);
|
||||
|
||||
|
||||
clk_enable(dev->clk);
|
||||
|
||||
/* Remove this if (0) to trace each and every message. */
|
||||
@ -715,14 +736,15 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,
|
||||
|
||||
if (attempts < NUM_ADDR_RESEND_ATTEMPTS && attempts > 0) {
|
||||
dev_dbg(&dev->pdev->dev, "managed to get address "
|
||||
"through after %d attempts\n", attempts);
|
||||
"through after %d attempts\n", attempts);
|
||||
} else if (attempts == NUM_ADDR_RESEND_ATTEMPTS) {
|
||||
dev_dbg(&dev->pdev->dev, "I give up, tried %d times "
|
||||
"to resend address.\n",
|
||||
NUM_ADDR_RESEND_ATTEMPTS);
|
||||
"to resend address.\n",
|
||||
NUM_ADDR_RESEND_ATTEMPTS);
|
||||
goto exit_disable;
|
||||
}
|
||||
|
||||
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
/* READ: we read the actual bytes one at a time */
|
||||
for (i = 0; i < msg->len; i++) {
|
||||
@ -804,8 +826,10 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
|
||||
struct stu300_dev *dev = i2c_get_adapdata(adap);
|
||||
dev->msg_len = num;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
/*
|
||||
* Another driver appears to send stop for each message,
|
||||
@ -817,6 +841,7 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||
dev->msg_index = i;
|
||||
|
||||
ret = stu300_xfer_msg(adap, &msgs[i], (i == (num - 1)));
|
||||
|
||||
if (ret != 0) {
|
||||
num = ret;
|
||||
break;
|
||||
@ -845,6 +870,7 @@ stu300_probe(struct platform_device *pdev)
|
||||
struct resource *res;
|
||||
int bus_nr;
|
||||
int ret = 0;
|
||||
char clk_name[] = "I2C0";
|
||||
|
||||
dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
@ -854,7 +880,8 @@ stu300_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
bus_nr = pdev->id;
|
||||
dev->clk = clk_get(&pdev->dev, NULL);
|
||||
clk_name[3] += (char)bus_nr;
|
||||
dev->clk = clk_get(&pdev->dev, clk_name);
|
||||
if (IS_ERR(dev->clk)) {
|
||||
ret = PTR_ERR(dev->clk);
|
||||
dev_err(&pdev->dev, "could not retrieve i2c bus clock\n");
|
||||
|
@ -456,8 +456,11 @@ static int joydev_ioctl_common(struct joydev *joydev,
|
||||
unsigned int cmd, void __user *argp)
|
||||
{
|
||||
struct input_dev *dev = joydev->handle.dev;
|
||||
size_t len;
|
||||
int i, j;
|
||||
const char *name;
|
||||
|
||||
/* Process fixed-sized commands. */
|
||||
switch (cmd) {
|
||||
|
||||
case JS_SET_CAL:
|
||||
@ -499,9 +502,22 @@ static int joydev_ioctl_common(struct joydev *joydev,
|
||||
return copy_to_user(argp, joydev->corr,
|
||||
sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
|
||||
|
||||
case JSIOCSAXMAP:
|
||||
if (copy_from_user(joydev->abspam, argp,
|
||||
sizeof(__u8) * (ABS_MAX + 1)))
|
||||
}
|
||||
|
||||
/*
|
||||
* Process variable-sized commands (the axis and button map commands
|
||||
* are considered variable-sized to decouple them from the values of
|
||||
* ABS_MAX and KEY_MAX).
|
||||
*/
|
||||
switch (cmd & ~IOCSIZE_MASK) {
|
||||
|
||||
case (JSIOCSAXMAP & ~IOCSIZE_MASK):
|
||||
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
|
||||
/*
|
||||
* FIXME: we should not copy into our axis map before
|
||||
* validating the data.
|
||||
*/
|
||||
if (copy_from_user(joydev->abspam, argp, len))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < joydev->nabs; i++) {
|
||||
@ -511,13 +527,17 @@ static int joydev_ioctl_common(struct joydev *joydev,
|
||||
}
|
||||
return 0;
|
||||
|
||||
case JSIOCGAXMAP:
|
||||
return copy_to_user(argp, joydev->abspam,
|
||||
sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
|
||||
case (JSIOCGAXMAP & ~IOCSIZE_MASK):
|
||||
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
|
||||
return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
|
||||
|
||||
case JSIOCSBTNMAP:
|
||||
if (copy_from_user(joydev->keypam, argp,
|
||||
sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
|
||||
case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
|
||||
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
|
||||
/*
|
||||
* FIXME: we should not copy into our keymap before
|
||||
* validating the data.
|
||||
*/
|
||||
if (copy_from_user(joydev->keypam, argp, len))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < joydev->nkey; i++) {
|
||||
@ -529,25 +549,19 @@ static int joydev_ioctl_common(struct joydev *joydev,
|
||||
|
||||
return 0;
|
||||
|
||||
case JSIOCGBTNMAP:
|
||||
return copy_to_user(argp, joydev->keypam,
|
||||
sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
|
||||
case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
|
||||
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
|
||||
return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
|
||||
|
||||
default:
|
||||
if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
|
||||
int len;
|
||||
const char *name = dev->name;
|
||||
case JSIOCGNAME(0):
|
||||
name = dev->name;
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
if (!name)
|
||||
return 0;
|
||||
len = strlen(name) + 1;
|
||||
if (len > _IOC_SIZE(cmd))
|
||||
len = _IOC_SIZE(cmd);
|
||||
if (copy_to_user(argp, name, len))
|
||||
return -EFAULT;
|
||||
return len;
|
||||
}
|
||||
len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
|
||||
return copy_to_user(argp, name, len) ? -EFAULT : len;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ static struct iforce_device iforce_device[] = {
|
||||
{ 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_avb_wheel, abs_wheel, ff_iforce },
|
||||
{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, //?
|
||||
{ 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //?
|
||||
{ 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce },
|
||||
{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //?
|
||||
{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //?
|
||||
{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //?
|
||||
|
@ -223,6 +223,7 @@ static struct usb_device_id iforce_usb_ids [] = {
|
||||
{ USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */
|
||||
{ USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */
|
||||
{ USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */
|
||||
{ USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */
|
||||
{ USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */
|
||||
{ USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */
|
||||
{ USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */
|
||||
|
@ -388,6 +388,32 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
|
||||
return result;
|
||||
}
|
||||
|
||||
static int wacom_query_tablet_data(struct usb_interface *intf)
|
||||
{
|
||||
unsigned char *rep_data;
|
||||
int limit = 0;
|
||||
int error;
|
||||
|
||||
rep_data = kmalloc(2, GFP_KERNEL);
|
||||
if (!rep_data)
|
||||
return -ENOMEM;
|
||||
|
||||
do {
|
||||
rep_data[0] = 2;
|
||||
rep_data[1] = 2;
|
||||
error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
|
||||
2, rep_data, 2);
|
||||
if (error >= 0)
|
||||
error = usb_get_report(intf,
|
||||
WAC_HID_FEATURE_REPORT, 2,
|
||||
rep_data, 2);
|
||||
} while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
|
||||
|
||||
kfree(rep_data);
|
||||
|
||||
return error < 0 ? error : 0;
|
||||
}
|
||||
|
||||
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *dev = interface_to_usbdev(intf);
|
||||
@ -398,7 +424,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
|
||||
struct wacom_features *features;
|
||||
struct input_dev *input_dev;
|
||||
int error = -ENOMEM;
|
||||
char rep_data[2], limit = 0;
|
||||
struct hid_descriptor *hid_desc;
|
||||
|
||||
wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
|
||||
@ -489,20 +514,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
|
||||
|
||||
/*
|
||||
* Ask the tablet to report tablet data if it is not a Tablet PC.
|
||||
* Repeat until it succeeds
|
||||
* Note that if query fails it is not a hard failure.
|
||||
*/
|
||||
if (wacom_wac->features->type != TABLETPC) {
|
||||
do {
|
||||
rep_data[0] = 2;
|
||||
rep_data[1] = 2;
|
||||
error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
|
||||
2, rep_data, 2);
|
||||
if (error >= 0)
|
||||
error = usb_get_report(intf,
|
||||
WAC_HID_FEATURE_REPORT, 2,
|
||||
rep_data, 2);
|
||||
} while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
|
||||
}
|
||||
if (wacom_wac->features->type != TABLETPC)
|
||||
wacom_query_tablet_data(intf);
|
||||
|
||||
usb_set_intfdata(intf, wacom);
|
||||
return 0;
|
||||
|
@ -170,11 +170,11 @@ static void ucb1400_handle_pending_irq(struct ucb1400_ts *ucb)
|
||||
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr);
|
||||
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
|
||||
|
||||
if (isr & UCB_IE_TSPX) {
|
||||
if (isr & UCB_IE_TSPX)
|
||||
ucb1400_ts_irq_disable(ucb->ac97);
|
||||
enable_irq(ucb->irq);
|
||||
} else
|
||||
printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
|
||||
else
|
||||
dev_dbg(&ucb->ts_idev->dev, "ucb1400: unexpected IE_STATUS = %#x\n", isr);
|
||||
enable_irq(ucb->irq);
|
||||
}
|
||||
|
||||
static int ucb1400_ts_thread(void *_ucb)
|
||||
@ -345,6 +345,7 @@ static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
|
||||
static int ucb1400_ts_probe(struct platform_device *dev)
|
||||
{
|
||||
int error, x_res, y_res;
|
||||
u16 fcsr;
|
||||
struct ucb1400_ts *ucb = dev->dev.platform_data;
|
||||
|
||||
ucb->ts_idev = input_allocate_device();
|
||||
@ -382,6 +383,14 @@ static int ucb1400_ts_probe(struct platform_device *dev)
|
||||
ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
|
||||
ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
|
||||
/*
|
||||
* Enable ADC filter to prevent horrible jitter on Colibri.
|
||||
* This also further reduces jitter on boards where ADCSYNC
|
||||
* pin is connected.
|
||||
*/
|
||||
fcsr = ucb1400_reg_read(ucb->ac97, UCB_FCSR);
|
||||
ucb1400_reg_write(ucb->ac97, UCB_FCSR, fcsr | UCB_FCSR_AVE);
|
||||
|
||||
ucb1400_adc_enable(ucb->ac97);
|
||||
x_res = ucb1400_ts_read_xres(ucb);
|
||||
y_res = ucb1400_ts_read_yres(ucb);
|
||||
|
@ -117,6 +117,9 @@ static ssize_t gpio_trig_inverted_store(struct device *dev,
|
||||
|
||||
gpio_data->inverted = !!inverted;
|
||||
|
||||
/* After inverting, we need to update the LED. */
|
||||
schedule_work(&gpio_data->work);
|
||||
|
||||
return n;
|
||||
}
|
||||
static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
|
||||
@ -146,20 +149,26 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (gpio_data->gpio == gpio)
|
||||
return n;
|
||||
|
||||
if (!gpio) {
|
||||
free_irq(gpio_to_irq(gpio_data->gpio), led);
|
||||
if (gpio_data->gpio != 0)
|
||||
free_irq(gpio_to_irq(gpio_data->gpio), led);
|
||||
gpio_data->gpio = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
if (gpio_data->gpio > 0 && gpio_data->gpio != gpio)
|
||||
free_irq(gpio_to_irq(gpio_data->gpio), led);
|
||||
|
||||
gpio_data->gpio = gpio;
|
||||
ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
|
||||
IRQF_SHARED | IRQF_TRIGGER_RISING
|
||||
| IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "request_irq failed with error %d\n", ret);
|
||||
} else {
|
||||
if (gpio_data->gpio != 0)
|
||||
free_irq(gpio_to_irq(gpio_data->gpio), led);
|
||||
gpio_data->gpio = gpio;
|
||||
}
|
||||
|
||||
return ret ? ret : n;
|
||||
}
|
||||
@ -211,7 +220,8 @@ static void gpio_trig_deactivate(struct led_classdev *led)
|
||||
device_remove_file(led->dev, &dev_attr_inverted);
|
||||
device_remove_file(led->dev, &dev_attr_desired_brightness);
|
||||
flush_work(&gpio_data->work);
|
||||
free_irq(gpio_to_irq(gpio_data->gpio),led);
|
||||
if (gpio_data->gpio != 0)
|
||||
free_irq(gpio_to_irq(gpio_data->gpio), led);
|
||||
kfree(gpio_data);
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ static void maciisi_sync(struct adb_request *req)
|
||||
}
|
||||
/* This could be BAD... when the ADB controller doesn't respond
|
||||
* for this long, it's probably not coming back :-( */
|
||||
if(count >= 50) /* Hopefully shouldn't happen */
|
||||
if (count > 50) /* Hopefully shouldn't happen */
|
||||
printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
|
||||
}
|
||||
|
||||
|
@ -2,25 +2,33 @@
|
||||
# Siano Mobile Silicon Digital TV device configuration
|
||||
#
|
||||
|
||||
config DVB_SIANO_SMS1XXX
|
||||
tristate "Siano SMS1XXX USB dongle support"
|
||||
depends on DVB_CORE && USB && INPUT
|
||||
config SMS_SIANO_MDTV
|
||||
tristate "Siano SMS1xxx based MDTV receiver"
|
||||
depends on DVB_CORE && INPUT
|
||||
---help---
|
||||
Choose Y here if you have a USB dongle with a SMS1XXX chipset.
|
||||
Choose Y or M here if you have MDTV receiver with a Siano chipset.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called sms1xxx.
|
||||
To compile this driver as a module, choose M here
|
||||
(The module will be called smsmdtv).
|
||||
|
||||
config DVB_SIANO_SMS1XXX_SMS_IDS
|
||||
bool "Enable support for Siano Mobile Silicon default USB IDs"
|
||||
depends on DVB_SIANO_SMS1XXX
|
||||
default y
|
||||
Further documentation on this driver can be found on the WWW
|
||||
at http://www.siano-ms.com/
|
||||
|
||||
if SMS_SIANO_MDTV
|
||||
menu "Siano module components"
|
||||
|
||||
# Hardware interfaces support
|
||||
|
||||
config SMS_USB_DRV
|
||||
tristate "USB interface support"
|
||||
depends on DVB_CORE && USB
|
||||
---help---
|
||||
Choose Y here if you have a USB dongle with a SMS1XXX chipset
|
||||
that uses Siano Mobile Silicon's default usb vid:pid.
|
||||
|
||||
Choose N here if you would prefer to use Siano's external driver.
|
||||
|
||||
Further documentation on this driver can be found on the WWW at
|
||||
<http://www.siano-ms.com/>.
|
||||
Choose if you would like to have Siano's support for USB interface
|
||||
|
||||
config SMS_SDIO_DRV
|
||||
tristate "SDIO interface support"
|
||||
depends on DVB_CORE && MMC
|
||||
---help---
|
||||
Choose if you would like to have Siano's support for SDIO interface
|
||||
endmenu
|
||||
endif # SMS_SIANO_MDTV
|
||||
|
@ -1,8 +1,9 @@
|
||||
sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
|
||||
|
||||
obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
|
||||
obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o
|
||||
obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o
|
||||
smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
|
||||
|
||||
obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
|
||||
obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
|
||||
obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
|
||||
|
||||
|
@ -325,6 +325,16 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
|
||||
0 : -ETIME;
|
||||
}
|
||||
|
||||
static inline int led_feedback(struct smsdvb_client_t *client)
|
||||
{
|
||||
if (client->fe_status & FE_HAS_LOCK)
|
||||
return sms_board_led_feedback(client->coredev,
|
||||
(client->sms_stat_dvb.ReceptionData.BER
|
||||
== 0) ? SMS_LED_HI : SMS_LED_LO);
|
||||
else
|
||||
return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
|
||||
}
|
||||
|
||||
static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
|
||||
{
|
||||
struct smsdvb_client_t *client;
|
||||
@ -332,6 +342,8 @@ static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
|
||||
|
||||
*stat = client->fe_status;
|
||||
|
||||
led_feedback(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -342,6 +354,8 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
|
||||
*ber = client->sms_stat_dvb.ReceptionData.BER;
|
||||
|
||||
led_feedback(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -359,6 +373,8 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
(client->sms_stat_dvb.ReceptionData.InBandPwr
|
||||
+ 95) * 3 / 2;
|
||||
|
||||
led_feedback(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -369,6 +385,8 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
|
||||
*snr = client->sms_stat_dvb.ReceptionData.SNR;
|
||||
|
||||
led_feedback(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -379,6 +397,8 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
|
||||
*ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
|
||||
|
||||
led_feedback(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -404,6 +424,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
|
||||
u32 Data[3];
|
||||
} Msg;
|
||||
|
||||
int ret;
|
||||
|
||||
client->fe_status = FE_HAS_SIGNAL;
|
||||
client->event_fe_state = -1;
|
||||
client->event_unc_state = -1;
|
||||
@ -426,6 +448,23 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
|
||||
case BANDWIDTH_AUTO: return -EOPNOTSUPP;
|
||||
default: return -EINVAL;
|
||||
}
|
||||
/* Disable LNA, if any. An error is returned if no LNA is present */
|
||||
ret = sms_board_lna_control(client->coredev, 0);
|
||||
if (ret == 0) {
|
||||
fe_status_t status;
|
||||
|
||||
/* tune with LNA off at first */
|
||||
ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
|
||||
&client->tune_done);
|
||||
|
||||
smsdvb_read_status(fe, &status);
|
||||
|
||||
if (status & FE_HAS_LOCK)
|
||||
return ret;
|
||||
|
||||
/* previous tune didnt lock - enable LNA and tune again */
|
||||
sms_board_lna_control(client->coredev, 1);
|
||||
}
|
||||
|
||||
return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
|
||||
&client->tune_done);
|
||||
@ -451,6 +490,8 @@ static int smsdvb_init(struct dvb_frontend *fe)
|
||||
struct smsdvb_client_t *client =
|
||||
container_of(fe, struct smsdvb_client_t, frontend);
|
||||
|
||||
sms_board_power(client->coredev, 1);
|
||||
|
||||
sms_board_dvb3_event(client, DVB3_EVENT_INIT);
|
||||
return 0;
|
||||
}
|
||||
@ -460,6 +501,9 @@ static int smsdvb_sleep(struct dvb_frontend *fe)
|
||||
struct smsdvb_client_t *client =
|
||||
container_of(fe, struct smsdvb_client_t, frontend);
|
||||
|
||||
sms_board_led_feedback(client->coredev, SMS_LED_OFF);
|
||||
sms_board_power(client->coredev, 0);
|
||||
|
||||
sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
|
||||
|
||||
return 0;
|
||||
|
@ -46,6 +46,7 @@
|
||||
|
||||
#define SMSSDIO_DATA 0x00
|
||||
#define SMSSDIO_INT 0x04
|
||||
#define SMSSDIO_BLOCK_SIZE 128
|
||||
|
||||
static const struct sdio_device_id smssdio_ids[] = {
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
|
||||
@ -85,7 +86,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size)
|
||||
sdio_claim_host(smsdev->func);
|
||||
|
||||
while (size >= smsdev->func->cur_blksize) {
|
||||
ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1);
|
||||
ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
|
||||
buffer, smsdev->func->cur_blksize);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@ -94,8 +96,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size)
|
||||
}
|
||||
|
||||
if (size) {
|
||||
ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA,
|
||||
buffer, size);
|
||||
ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
|
||||
buffer, size);
|
||||
}
|
||||
|
||||
out:
|
||||
@ -125,23 +127,23 @@ static void smssdio_interrupt(struct sdio_func *func)
|
||||
*/
|
||||
isr = sdio_readb(func, SMSSDIO_INT, &ret);
|
||||
if (ret) {
|
||||
dev_err(&smsdev->func->dev,
|
||||
"Unable to read interrupt register!\n");
|
||||
sms_err("Unable to read interrupt register!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (smsdev->split_cb == NULL) {
|
||||
cb = smscore_getbuffer(smsdev->coredev);
|
||||
if (!cb) {
|
||||
dev_err(&smsdev->func->dev,
|
||||
"Unable to allocate data buffer!\n");
|
||||
sms_err("Unable to allocate data buffer!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1);
|
||||
ret = sdio_memcpy_fromio(smsdev->func,
|
||||
cb->p,
|
||||
SMSSDIO_DATA,
|
||||
SMSSDIO_BLOCK_SIZE);
|
||||
if (ret) {
|
||||
dev_err(&smsdev->func->dev,
|
||||
"Error %d reading initial block!\n", ret);
|
||||
sms_err("Error %d reading initial block!\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -152,7 +154,10 @@ static void smssdio_interrupt(struct sdio_func *func)
|
||||
return;
|
||||
}
|
||||
|
||||
size = hdr->msgLength - smsdev->func->cur_blksize;
|
||||
if (hdr->msgLength > smsdev->func->cur_blksize)
|
||||
size = hdr->msgLength - smsdev->func->cur_blksize;
|
||||
else
|
||||
size = 0;
|
||||
} else {
|
||||
cb = smsdev->split_cb;
|
||||
hdr = cb->p;
|
||||
@ -162,23 +167,24 @@ static void smssdio_interrupt(struct sdio_func *func)
|
||||
smsdev->split_cb = NULL;
|
||||
}
|
||||
|
||||
if (hdr->msgLength > smsdev->func->cur_blksize) {
|
||||
if (size) {
|
||||
void *buffer;
|
||||
|
||||
size = ALIGN(size, 128);
|
||||
buffer = cb->p + hdr->msgLength;
|
||||
buffer = cb->p + (hdr->msgLength - size);
|
||||
size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
|
||||
|
||||
BUG_ON(smsdev->func->cur_blksize != 128);
|
||||
BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
|
||||
|
||||
/*
|
||||
* First attempt to transfer all of it in one go...
|
||||
*/
|
||||
ret = sdio_read_blocks(smsdev->func, buffer,
|
||||
SMSSDIO_DATA, size / 128);
|
||||
ret = sdio_memcpy_fromio(smsdev->func,
|
||||
buffer,
|
||||
SMSSDIO_DATA,
|
||||
size);
|
||||
if (ret && ret != -EINVAL) {
|
||||
smscore_putbuffer(smsdev->coredev, cb);
|
||||
dev_err(&smsdev->func->dev,
|
||||
"Error %d reading data from card!\n", ret);
|
||||
sms_err("Error %d reading data from card!\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -191,12 +197,12 @@ static void smssdio_interrupt(struct sdio_func *func)
|
||||
*/
|
||||
if (ret == -EINVAL) {
|
||||
while (size) {
|
||||
ret = sdio_read_blocks(smsdev->func,
|
||||
buffer, SMSSDIO_DATA, 1);
|
||||
ret = sdio_memcpy_fromio(smsdev->func,
|
||||
buffer, SMSSDIO_DATA,
|
||||
smsdev->func->cur_blksize);
|
||||
if (ret) {
|
||||
smscore_putbuffer(smsdev->coredev, cb);
|
||||
dev_err(&smsdev->func->dev,
|
||||
"Error %d reading "
|
||||
sms_err("Error %d reading "
|
||||
"data from card!\n", ret);
|
||||
return;
|
||||
}
|
||||
@ -269,7 +275,7 @@ static int smssdio_probe(struct sdio_func *func,
|
||||
if (ret)
|
||||
goto release;
|
||||
|
||||
ret = sdio_set_block_size(func, 128);
|
||||
ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
|
||||
if (ret)
|
||||
goto disable;
|
||||
|
||||
|
@ -1730,6 +1730,25 @@ static inline void em28xx_set_model(struct em28xx *dev)
|
||||
EM28XX_I2C_FREQ_100_KHZ;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: Should be replaced by a proper mt9m111 driver */
|
||||
static int em28xx_initialize_mt9m111(struct em28xx *dev)
|
||||
{
|
||||
int i;
|
||||
unsigned char regs[][3] = {
|
||||
{ 0x0d, 0x00, 0x01, }, /* reset and use defaults */
|
||||
{ 0x0d, 0x00, 0x00, },
|
||||
{ 0x0a, 0x00, 0x21, },
|
||||
{ 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs); i++)
|
||||
i2c_master_send(&dev->i2c_client, ®s[i][0], 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: Should be replaced by a proper mt9m001 driver */
|
||||
static int em28xx_initialize_mt9m001(struct em28xx *dev)
|
||||
{
|
||||
@ -1758,7 +1777,7 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev)
|
||||
|
||||
/* HINT method: webcam I2C chips
|
||||
*
|
||||
* This method work for webcams with Micron sensors
|
||||
* This method works for webcams with Micron sensors
|
||||
*/
|
||||
static int em28xx_hint_sensor(struct em28xx *dev)
|
||||
{
|
||||
@ -1804,6 +1823,23 @@ static int em28xx_hint_sensor(struct em28xx *dev)
|
||||
dev->vinctl = 0x00;
|
||||
|
||||
break;
|
||||
|
||||
case 0x143a: /* MT9M111 as found in the ECS G200 */
|
||||
dev->model = EM2750_BOARD_UNKNOWN;
|
||||
em28xx_set_model(dev);
|
||||
|
||||
sensor_name = "mt9m111";
|
||||
dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ;
|
||||
dev->em28xx_sensor = EM28XX_MT9M111;
|
||||
em28xx_initialize_mt9m111(dev);
|
||||
dev->sensor_xres = 640;
|
||||
dev->sensor_yres = 512;
|
||||
|
||||
dev->vinmode = 0x0a;
|
||||
dev->vinctl = 0x00;
|
||||
|
||||
break;
|
||||
|
||||
case 0x8431:
|
||||
dev->model = EM2750_BOARD_UNKNOWN;
|
||||
em28xx_set_model(dev);
|
||||
@ -1820,7 +1856,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
|
||||
|
||||
break;
|
||||
default:
|
||||
printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version));
|
||||
printk("Unknown Micron Sensor 0x%04x\n", version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -2346,7 +2382,9 @@ void em28xx_card_setup(struct em28xx *dev)
|
||||
}
|
||||
|
||||
em28xx_tuner_setup(dev);
|
||||
em28xx_ir_init(dev);
|
||||
|
||||
if(!disable_ir)
|
||||
em28xx_ir_init(dev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -367,6 +367,7 @@ enum em28xx_sensor {
|
||||
EM28XX_NOSENSOR = 0,
|
||||
EM28XX_MT9V011,
|
||||
EM28XX_MT9M001,
|
||||
EM28XX_MT9M111,
|
||||
};
|
||||
|
||||
enum em28xx_adecoder {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user