diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 2f7fd4360848..9c27e5125dd2 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -102,9 +102,12 @@ X!Iinclude/linux/kobject.h
!Iinclude/linux/device.h
Device Drivers Base
+!Idrivers/base/init.c
!Edrivers/base/driver.c
!Edrivers/base/core.c
+!Edrivers/base/syscore.c
!Edrivers/base/class.c
+!Idrivers/base/node.c
!Edrivers/base/firmware_class.c
!Edrivers/base/transport_class.c
-!Edrivers/base/sys.c
+!Edrivers/base/dd.c
!Iinclude/linux/platform_device.h
!Edrivers/base/platform.c
!Edrivers/base/bus.c
+
+ Device Drivers DMA Management
+!Edrivers/base/dma-buf.c
+!Edrivers/base/dma-coherent.c
+!Edrivers/base/dma-mapping.c
Device Drivers Power Management
!Edrivers/base/power/main.c
@@ -219,7 +227,7 @@ X!Isound/sound_firmware.c
16x50 UART Driver
!Edrivers/tty/serial/serial_core.c
-!Edrivers/tty/serial/8250.c
+!Edrivers/tty/serial/8250/8250.c
diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt
index 23fcb05175be..53305bd08182 100644
--- a/Documentation/input/event-codes.txt
+++ b/Documentation/input/event-codes.txt
@@ -17,11 +17,11 @@ reports supported by a device are also provided by sysfs in
class/input/event*/device/capabilities/, and the properties of a device are
provided in class/input/event*/device/properties.
-Types:
-==========
-Types are groupings of codes under a logical input construct. Each type has a
-set of applicable codes to be used in generating events. See the Codes section
-for details on valid codes for each type.
+Event types:
+===========
+Event types are groupings of codes under a logical input construct. Each
+type has a set of applicable codes to be used in generating events. See the
+Codes section for details on valid codes for each type.
* EV_SYN:
- Used as markers to separate events. Events may be separated in time or in
@@ -63,9 +63,9 @@ for details on valid codes for each type.
* EV_FF_STATUS:
- Used to receive force feedback device status.
-Codes:
-==========
-Codes define the precise type of event.
+Event codes:
+===========
+Event codes define the precise type of event.
EV_SYN:
----------
@@ -220,6 +220,56 @@ EV_PWR:
EV_PWR events are a special type of event used specifically for power
mangement. Its usage is not well defined. To be addressed later.
+Device properties:
+=================
+Normally, userspace sets up an input device based on the data it emits,
+i.e., the event types. In the case of two devices emitting the same event
+types, additional information can be provided in the form of device
+properties.
+
+INPUT_PROP_DIRECT + INPUT_PROP_POINTER:
+--------------------------------------
+The INPUT_PROP_DIRECT property indicates that device coordinates should be
+directly mapped to screen coordinates (not taking into account trivial
+transformations, such as scaling, flipping and rotating). Non-direct input
+devices require non-trivial transformation, such as absolute to relative
+transformation for touchpads. Typical direct input devices: touchscreens,
+drawing tablets; non-direct devices: touchpads, mice.
+
+The INPUT_PROP_POINTER property indicates that the device is not transposed
+on the screen and thus requires use of an on-screen pointer to trace user's
+movements. Typical pointer devices: touchpads, tablets, mice; non-pointer
+device: touchscreen.
+
+If neither INPUT_PROP_DIRECT or INPUT_PROP_POINTER are set, the property is
+considered undefined and the device type should be deduced in the
+traditional way, using emitted event types.
+
+INPUT_PROP_BUTTONPAD:
+--------------------
+For touchpads where the button is placed beneath the surface, such that
+pressing down on the pad causes a button click, this property should be
+set. Common in clickpad notebooks and macbooks from 2009 and onwards.
+
+Originally, the buttonpad property was coded into the bcm5974 driver
+version field under the name integrated button. For backwards
+compatibility, both methods need to be checked in userspace.
+
+INPUT_PROP_SEMI_MT:
+------------------
+Some touchpads, most common between 2008 and 2011, can detect the presence
+of multiple contacts without resolving the individual positions; only the
+number of contacts and a rectangular shape is known. For such
+touchpads, the semi-mt property should be set.
+
+Depending on the device, the rectangle may enclose all touches, like a
+bounding box, or just some of them, for instance the two most recent
+touches. The diversity makes the rectangle of limited use, but some
+gestures can normally be extracted from it.
+
+If INPUT_PROP_SEMI_MT is not set, the device is assumed to be a true MT
+device.
+
Guidelines:
==========
The guidelines below ensure proper single-touch and multi-finger functionality.
@@ -240,6 +290,8 @@ used to report when a touch is active on the screen.
BTN_{MOUSE,LEFT,MIDDLE,RIGHT} must not be reported as the result of touch
contact. BTN_TOOL_ events should be reported where possible.
+For new hardware, INPUT_PROP_DIRECT should be set.
+
Trackpads:
----------
Legacy trackpads that only provide relative position information must report
@@ -250,6 +302,8 @@ location of the touch. BTN_TOUCH should be used to report when a touch is active
on the trackpad. Where multi-finger support is available, BTN_TOOL_ should
be used to report the number of touches active on the trackpad.
+For new hardware, INPUT_PROP_POINTER should be set.
+
Tablets:
----------
BTN_TOOL_ events must be reported when a stylus or other tool is active on
@@ -260,3 +314,5 @@ button may be used for buttons on the tablet except BTN_{MOUSE,LEFT}.
BTN_{0,1,2,etc} are good generic codes for unlabeled buttons. Do not use
meaningful buttons, like BTN_FORWARD, unless the button is labeled for that
purpose on the device.
+
+For new hardware, both INPUT_PROP_DIRECT and INPUT_PROP_POINTER should be set.
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 8c20fbd8b42d..6d78841fd416 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -601,6 +601,8 @@ can be ORed together:
instead of using the one provided by the hardware.
512 - A kernel warning has occurred.
1024 - A module from drivers/staging was loaded.
+2048 - The system is working around a severe firmware bug.
+4096 - An out-of-tree module has been loaded.
==============================================================
diff --git a/MAINTAINERS b/MAINTAINERS
index f71da55f9ac6..5f540bb733ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -159,7 +159,7 @@ S: Maintained
F: drivers/net/ethernet/realtek/r8169.c
8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-serial@vger.kernel.org
W: http://serial.sourceforge.net
S: Maintained
@@ -789,12 +789,6 @@ F: arch/arm/mach-mx*/
F: arch/arm/mach-imx/
F: arch/arm/plat-mxc/
-ARM/FREESCALE IMX51
-M: Amit Kucheria
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/mach-mx5/
-
ARM/FREESCALE IMX6
M: Shawn Guo
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1784,9 +1778,9 @@ X: net/wireless/wext*
CHAR and MISC DRIVERS
M: Arnd Bergmann
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
-S: Maintained
+S: Supported
F: drivers/char/*
F: drivers/misc/*
@@ -2289,7 +2283,7 @@ F: drivers/acpi/dock.c
DOCUMENTATION
M: Randy Dunlap
L: linux-doc@vger.kernel.org
-T: quilt http://userweb.kernel.org/~rdunlap/kernel-doc-patches/current/
+T: quilt http://xenotime.net/kernel-doc-patches/current/
S: Maintained
F: Documentation/
@@ -2322,7 +2316,7 @@ F: lib/lru_cache.c
F: Documentation/blockdev/drbd/
DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
S: Supported
F: Documentation/kobject.txt
@@ -3326,6 +3320,12 @@ S: Maintained
F: net/ieee802154/
F: drivers/ieee802154/
+IIO SUBSYSTEM AND DRIVERS
+M: Jonathan Cameron
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: drivers/staging/iio/
+
IKANOS/ADI EAGLE ADSL USB DRIVER
M: Matthieu Castet
M: Stanislaw Gruszka
@@ -3994,11 +3994,11 @@ M: Rusty Russell
L: lguest@lists.ozlabs.org
W: http://lguest.ozlabs.org/
S: Odd Fixes
-F: Documentation/virtual/lguest/
+F: arch/x86/include/asm/lguest*.h
F: arch/x86/lguest/
F: drivers/lguest/
F: include/linux/lguest*.h
-F: arch/x86/include/asm/lguest*.h
+F: tools/lguest/
LINUX FOR IBM pSERIES (RS/6000)
M: Paul Mackerras
@@ -4138,7 +4138,7 @@ L: linux-ntfs-dev@lists.sourceforge.net
W: http://www.linux-ntfs.org/content/view/19/37/
S: Maintained
F: Documentation/ldm.txt
-F: fs/partitions/ldm.*
+F: block/partitions/ldm.*
LogFS
M: Joern Engel
@@ -5635,7 +5635,7 @@ W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
F: arch/s390/
F: drivers/s390/
-F: fs/partitions/ibm.c
+F: block/partitions/ibm.c
F: Documentation/s390/
F: Documentation/DocBook/s390*
@@ -6278,15 +6278,15 @@ S: Maintained
F: arch/alpha/kernel/srm_env.c
STABLE BRANCH
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: stable@vger.kernel.org
-S: Maintained
+S: Supported
STAGING SUBSYSTEM
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
L: devel@driverdev.osuosl.org
-S: Maintained
+S: Supported
F: drivers/staging/
STAGING - AGERE HERMES II and II.5 WIRELESS DRIVERS
@@ -6398,11 +6398,6 @@ M: Omar Ramirez Luna
S: Odd Fixes
F: drivers/staging/tidspbridge/
-STAGING - TRIDENT TVMASTER TMxxxx USB VIDEO CAPTURE DRIVERS
-L: linux-media@vger.kernel.org
-S: Odd Fixes
-F: drivers/staging/tm6000/
-
STAGING - USB ENE SM/MS CARD READER DRIVER
M: Al Cho
S: Odd Fixes
@@ -6671,8 +6666,8 @@ S: Maintained
K: ^Subject:.*(?i)trivial
TTY LAYER
-M: Greg Kroah-Hartman
-S: Maintained
+M: Greg Kroah-Hartman
+S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
F: drivers/tty/
F: drivers/tty/serial/serial_core.c
@@ -6960,7 +6955,7 @@ S: Maintained
F: drivers/usb/serial/digi_acceleport.c
USB SERIAL DRIVER
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-usb@vger.kernel.org
S: Supported
F: Documentation/usb/usb-serial.txt
@@ -6975,9 +6970,8 @@ S: Maintained
F: drivers/usb/serial/empeg.c
USB SERIAL KEYSPAN DRIVER
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-usb@vger.kernel.org
-W: http://www.kroah.com/linux/
S: Maintained
F: drivers/usb/serial/*keyspan*
@@ -7005,7 +6999,7 @@ F: Documentation/video4linux/sn9c102.txt
F: drivers/media/video/sn9c102/
USB SUBSYSTEM
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
@@ -7092,7 +7086,7 @@ F: fs/hppfs/
USERSPACE I/O (UIO)
M: "Hans J. Koch"
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
S: Maintained
F: Documentation/DocBook/uio-howto.tmpl
F: drivers/uio/
diff --git a/Makefile b/Makefile
index 71e6ed21dd15..7c44b676b77a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 3
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index 5d3ed7e38561..314d4664eae7 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -198,7 +198,15 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
unsigned long addr)
{
pgtable_page_dtor(pte);
- tlb_add_flush(tlb, addr);
+
+ /*
+ * With the classic ARM MMU, a pte page has two corresponding pmd
+ * entries, each covering 1MB.
+ */
+ addr &= PMD_MASK;
+ tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);
+ tlb_add_flush(tlb, addr + SZ_1M);
+
tlb_remove_page(tlb, pte);
}
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 3a456c6c7005..be16a48007b4 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -790,7 +790,7 @@ __kuser_cmpxchg64: @ 0xffff0f60
smp_dmb arm
rsbs r0, r3, #0 @ set returned val and C flag
ldmfd sp!, {r4, r5, r6, r7}
- bx lr
+ usr_ret lr
#elif !defined(CONFIG_SMP)
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 460bbbb6b885..6933244c68f9 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -469,6 +469,20 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
+ [C(NODE)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
};
/*
@@ -579,6 +593,20 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
+ [C(NODE)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
};
/*
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index e1d5e1929fbd..e33870ff0ac0 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -699,10 +699,13 @@ static int vfp_set(struct task_struct *target,
{
int ret;
struct thread_info *thread = task_thread_info(target);
- struct vfp_hard_struct new_vfp = thread->vfpstate.hard;
+ struct vfp_hard_struct new_vfp;
const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+ vfp_sync_hwstate(thread);
+ new_vfp = thread->vfpstate.hard;
+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&new_vfp.fpregs,
user_fpregs_offset,
@@ -723,9 +726,8 @@ static int vfp_set(struct task_struct *target,
if (ret)
return ret;
- vfp_sync_hwstate(thread);
- thread->vfpstate.hard = new_vfp;
vfp_flush_hwstate(thread);
+ thread->vfpstate.hard = new_vfp;
return 0;
}
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 0340224cf73c..9e617bd4a146 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -227,6 +227,8 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
return -EINVAL;
+ vfp_flush_hwstate(thread);
+
/*
* Copy the floating point registers. There can be unused
* registers see asm/hwcap.h for details.
@@ -251,9 +253,6 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
- if (!err)
- vfp_flush_hwstate(thread);
-
return err ? -EFAULT : 0;
}
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c
index 9e5e7552498c..45c97b1ee9b1 100644
--- a/arch/arm/mach-bcmring/arch.c
+++ b/arch/arm/mach-bcmring/arch.c
@@ -194,6 +194,6 @@ MACHINE_START(BCMRING, "BCMRING")
.init_early = bcmring_init_early,
.init_irq = bcmring_init_irq,
.timer = &bcmring_timer,
- .init_machine = bcmring_init_machine
+ .init_machine = bcmring_init_machine,
.restart = bcmring_restart,
MACHINE_END
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c
index 1a1a27dd5654..1024396797e1 100644
--- a/arch/arm/mach-bcmring/dma.c
+++ b/arch/arm/mach-bcmring/dma.c
@@ -33,17 +33,11 @@
#include
-#include
#include
#include
#include
#include
-/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
-/* especially since dc4 doesn't use kmalloc'd memory. */
-
-#define ALLOW_MAP_OF_KMALLOC_MEMORY 0
-
/* ---- Public Variables ------------------------------------------------- */
/* ---- Private Constants and Types -------------------------------------- */
@@ -53,58 +47,18 @@
#define CONTROLLER_FROM_HANDLE(handle) (((handle) >> 4) & 0x0f)
#define CHANNEL_FROM_HANDLE(handle) ((handle) & 0x0f)
-#define DMA_MAP_DEBUG 0
-
-#if DMA_MAP_DEBUG
-# define DMA_MAP_PRINT(fmt, args...) printk("%s: " fmt, __func__, ## args)
-#else
-# define DMA_MAP_PRINT(fmt, args...)
-#endif
/* ---- Private Variables ------------------------------------------------ */
static DMA_Global_t gDMA;
static struct proc_dir_entry *gDmaDir;
-static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0);
-
#include "dma_device.c"
/* ---- Private Function Prototypes -------------------------------------- */
/* ---- Functions ------------------------------------------------------- */
-/****************************************************************************/
-/**
-* Displays information for /proc/dma/mem-type
-*/
-/****************************************************************************/
-
-static int dma_proc_read_mem_type(char *buf, char **start, off_t offset,
- int count, int *eof, void *data)
-{
- int len = 0;
-
- len += sprintf(buf + len, "dma_map_mem statistics\n");
- len +=
- sprintf(buf + len, "coherent: %d\n",
- atomic_read(&gDmaStatMemTypeCoherent));
- len +=
- sprintf(buf + len, "kmalloc: %d\n",
- atomic_read(&gDmaStatMemTypeKmalloc));
- len +=
- sprintf(buf + len, "vmalloc: %d\n",
- atomic_read(&gDmaStatMemTypeVmalloc));
- len +=
- sprintf(buf + len, "user: %d\n",
- atomic_read(&gDmaStatMemTypeUser));
-
- return len;
-}
-
/****************************************************************************/
/**
* Displays information for /proc/dma/channels
@@ -846,8 +800,6 @@ int dma_init(void)
dma_proc_read_channels, NULL);
create_proc_read_entry("devices", 0, gDmaDir,
dma_proc_read_devices, NULL);
- create_proc_read_entry("mem-type", 0, gDmaDir,
- dma_proc_read_mem_type, NULL);
}
out:
@@ -1565,767 +1517,3 @@ int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for.
}
EXPORT_SYMBOL(dma_set_device_handler);
-
-/****************************************************************************/
-/**
-* Initializes a memory mapping structure
-*/
-/****************************************************************************/
-
-int dma_init_mem_map(DMA_MemMap_t *memMap)
-{
- memset(memMap, 0, sizeof(*memMap));
-
- sema_init(&memMap->lock, 1);
-
- return 0;
-}
-
-EXPORT_SYMBOL(dma_init_mem_map);
-
-/****************************************************************************/
-/**
-* Releases any memory currently being held by a memory mapping structure.
-*/
-/****************************************************************************/
-
-int dma_term_mem_map(DMA_MemMap_t *memMap)
-{
- down(&memMap->lock); /* Just being paranoid */
-
- /* Free up any allocated memory */
-
- up(&memMap->lock);
- memset(memMap, 0, sizeof(*memMap));
-
- return 0;
-}
-
-EXPORT_SYMBOL(dma_term_mem_map);
-
-/****************************************************************************/
-/**
-* Looks at a memory address and categorizes it.
-*
-* @return One of the values from the DMA_MemType_t enumeration.
-*/
-/****************************************************************************/
-
-DMA_MemType_t dma_mem_type(void *addr)
-{
- unsigned long addrVal = (unsigned long)addr;
-
- if (addrVal >= CONSISTENT_BASE) {
- /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */
-
- /* dma_alloc_xxx pages are physically and virtually contiguous */
-
- return DMA_MEM_TYPE_DMA;
- }
-
- /* Technically, we could add one more classification. Addresses between VMALLOC_END */
- /* and the beginning of the DMA virtual address could be considered to be I/O space. */
- /* Right now, nobody cares about this particular classification, so we ignore it. */
-
- if (is_vmalloc_addr(addr)) {
- /* Address comes from the vmalloc'd region. Pages are virtually */
- /* contiguous but NOT physically contiguous */
-
- return DMA_MEM_TYPE_VMALLOC;
- }
-
- if (addrVal >= PAGE_OFFSET) {
- /* PAGE_OFFSET is typically 0xC0000000 */
-
- /* kmalloc'd pages are physically contiguous */
-
- return DMA_MEM_TYPE_KMALLOC;
- }
-
- return DMA_MEM_TYPE_USER;
-}
-
-EXPORT_SYMBOL(dma_mem_type);
-
-/****************************************************************************/
-/**
-* Looks at a memory address and determines if we support DMA'ing to/from
-* that type of memory.
-*
-* @return boolean -
-* return value != 0 means dma supported
-* return value == 0 means dma not supported
-*/
-/****************************************************************************/
-
-int dma_mem_supports_dma(void *addr)
-{
- DMA_MemType_t memType = dma_mem_type(addr);
-
- return (memType == DMA_MEM_TYPE_DMA)
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
- || (memType == DMA_MEM_TYPE_KMALLOC)
-#endif
- || (memType == DMA_MEM_TYPE_USER);
-}
-
-EXPORT_SYMBOL(dma_mem_supports_dma);
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- ) {
- int rc;
-
- down(&memMap->lock);
-
- DMA_MAP_PRINT("memMap: %p\n", memMap);
-
- if (memMap->inUse) {
- printk(KERN_ERR "%s: memory map %p is already being used\n",
- __func__, memMap);
- rc = -EBUSY;
- goto out;
- }
-
- memMap->inUse = 1;
- memMap->dir = dir;
- memMap->numRegionsUsed = 0;
-
- rc = 0;
-
-out:
-
- DMA_MAP_PRINT("returning %d", rc);
-
- up(&memMap->lock);
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_start);
-
-/****************************************************************************/
-/**
-* Adds a segment of memory to a memory map. Each segment is both
-* physically and virtually contiguous.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-static int dma_map_add_segment(DMA_MemMap_t *memMap, /* Stores state information about the map */
- DMA_Region_t *region, /* Region that the segment belongs to */
- void *virtAddr, /* Virtual address of the segment being added */
- dma_addr_t physAddr, /* Physical address of the segment being added */
- size_t numBytes /* Number of bytes of the segment being added */
- ) {
- DMA_Segment_t *segment;
-
- DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr,
- physAddr, numBytes);
-
- /* Sanity check */
-
- if (((unsigned long)virtAddr < (unsigned long)region->virtAddr)
- || (((unsigned long)virtAddr + numBytes)) >
- ((unsigned long)region->virtAddr + region->numBytes)) {
- printk(KERN_ERR
- "%s: virtAddr %p is outside region @ %p len: %d\n",
- __func__, virtAddr, region->virtAddr, region->numBytes);
- return -EINVAL;
- }
-
- if (region->numSegmentsUsed > 0) {
- /* Check to see if this segment is physically contiguous with the previous one */
-
- segment = ®ion->segment[region->numSegmentsUsed - 1];
-
- if ((segment->physAddr + segment->numBytes) == physAddr) {
- /* It is - just add on to the end */
-
- DMA_MAP_PRINT("appending %d bytes to last segment\n",
- numBytes);
-
- segment->numBytes += numBytes;
-
- return 0;
- }
- }
-
- /* Reallocate to hold more segments, if required. */
-
- if (region->numSegmentsUsed >= region->numSegmentsAllocated) {
- DMA_Segment_t *newSegment;
- size_t oldSize =
- region->numSegmentsAllocated * sizeof(*newSegment);
- int newAlloc = region->numSegmentsAllocated + 4;
- size_t newSize = newAlloc * sizeof(*newSegment);
-
- newSegment = kmalloc(newSize, GFP_KERNEL);
- if (newSegment == NULL) {
- return -ENOMEM;
- }
- memcpy(newSegment, region->segment, oldSize);
- memset(&((uint8_t *) newSegment)[oldSize], 0,
- newSize - oldSize);
- kfree(region->segment);
-
- region->numSegmentsAllocated = newAlloc;
- region->segment = newSegment;
- }
-
- segment = ®ion->segment[region->numSegmentsUsed];
- region->numSegmentsUsed++;
-
- segment->virtAddr = virtAddr;
- segment->physAddr = physAddr;
- segment->numBytes = numBytes;
-
- DMA_MAP_PRINT("returning success\n");
-
- return 0;
-}
-
-/****************************************************************************/
-/**
-* Adds a region of memory to a memory map. Each region is virtually
-* contiguous, but not necessarily physically contiguous.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *mem, /* Virtual address that we want to get a map of */
- size_t numBytes /* Number of bytes being mapped */
- ) {
- unsigned long addr = (unsigned long)mem;
- unsigned int offset;
- int rc = 0;
- DMA_Region_t *region;
- dma_addr_t physAddr;
-
- down(&memMap->lock);
-
- DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes);
-
- if (!memMap->inUse) {
- printk(KERN_ERR "%s: Make sure you call dma_map_start first\n",
- __func__);
- rc = -EINVAL;
- goto out;
- }
-
- /* Reallocate to hold more regions. */
-
- if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) {
- DMA_Region_t *newRegion;
- size_t oldSize =
- memMap->numRegionsAllocated * sizeof(*newRegion);
- int newAlloc = memMap->numRegionsAllocated + 4;
- size_t newSize = newAlloc * sizeof(*newRegion);
-
- newRegion = kmalloc(newSize, GFP_KERNEL);
- if (newRegion == NULL) {
- rc = -ENOMEM;
- goto out;
- }
- memcpy(newRegion, memMap->region, oldSize);
- memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize);
-
- kfree(memMap->region);
-
- memMap->numRegionsAllocated = newAlloc;
- memMap->region = newRegion;
- }
-
- region = &memMap->region[memMap->numRegionsUsed];
- memMap->numRegionsUsed++;
-
- offset = addr & ~PAGE_MASK;
-
- region->memType = dma_mem_type(mem);
- region->virtAddr = mem;
- region->numBytes = numBytes;
- region->numSegmentsUsed = 0;
- region->numLockedPages = 0;
- region->lockedPages = NULL;
-
- switch (region->memType) {
- case DMA_MEM_TYPE_VMALLOC:
- {
- atomic_inc(&gDmaStatMemTypeVmalloc);
-
- /* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */
-
- /* vmalloc'd pages are not physically contiguous */
-
- rc = -EINVAL;
- break;
- }
-
- case DMA_MEM_TYPE_KMALLOC:
- {
- atomic_inc(&gDmaStatMemTypeKmalloc);
-
- /* kmalloc'd pages are physically contiguous, so they'll have exactly */
- /* one segment */
-
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
- physAddr =
- dma_map_single(NULL, mem, numBytes, memMap->dir);
- rc = dma_map_add_segment(memMap, region, mem, physAddr,
- numBytes);
-#else
- rc = -EINVAL;
-#endif
- break;
- }
-
- case DMA_MEM_TYPE_DMA:
- {
- /* dma_alloc_xxx pages are physically contiguous */
-
- atomic_inc(&gDmaStatMemTypeCoherent);
-
- physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset;
-
- dma_sync_single_for_cpu(NULL, physAddr, numBytes,
- memMap->dir);
- rc = dma_map_add_segment(memMap, region, mem, physAddr,
- numBytes);
- break;
- }
-
- case DMA_MEM_TYPE_USER:
- {
- size_t firstPageOffset;
- size_t firstPageSize;
- struct page **pages;
- struct task_struct *userTask;
-
- atomic_inc(&gDmaStatMemTypeUser);
-
-#if 1
- /* If the pages are user pages, then the dma_mem_map_set_user_task function */
- /* must have been previously called. */
-
- if (memMap->userTask == NULL) {
- printk(KERN_ERR
- "%s: must call dma_mem_map_set_user_task when using user-mode memory\n",
- __func__);
- return -EINVAL;
- }
-
- /* User pages need to be locked. */
-
- firstPageOffset =
- (unsigned long)region->virtAddr & (PAGE_SIZE - 1);
- firstPageSize = PAGE_SIZE - firstPageOffset;
-
- region->numLockedPages = (firstPageOffset
- + region->numBytes +
- PAGE_SIZE - 1) / PAGE_SIZE;
- pages =
- kmalloc(region->numLockedPages *
- sizeof(struct page *), GFP_KERNEL);
-
- if (pages == NULL) {
- region->numLockedPages = 0;
- return -ENOMEM;
- }
-
- userTask = memMap->userTask;
-
- down_read(&userTask->mm->mmap_sem);
- rc = get_user_pages(userTask, /* task */
- userTask->mm, /* mm */
- (unsigned long)region->virtAddr, /* start */
- region->numLockedPages, /* len */
- memMap->dir == DMA_FROM_DEVICE, /* write */
- 0, /* force */
- pages, /* pages (array of pointers to page) */
- NULL); /* vmas */
- up_read(&userTask->mm->mmap_sem);
-
- if (rc != region->numLockedPages) {
- kfree(pages);
- region->numLockedPages = 0;
-
- if (rc >= 0) {
- rc = -EINVAL;
- }
- } else {
- uint8_t *virtAddr = region->virtAddr;
- size_t bytesRemaining;
- int pageIdx;
-
- rc = 0; /* Since get_user_pages returns +ve number */
-
- region->lockedPages = pages;
-
- /* We've locked the user pages. Now we need to walk them and figure */
- /* out the physical addresses. */
-
- /* The first page may be partial */
-
- dma_map_add_segment(memMap,
- region,
- virtAddr,
- PFN_PHYS(page_to_pfn
- (pages[0])) +
- firstPageOffset,
- firstPageSize);
-
- virtAddr += firstPageSize;
- bytesRemaining =
- region->numBytes - firstPageSize;
-
- for (pageIdx = 1;
- pageIdx < region->numLockedPages;
- pageIdx++) {
- size_t bytesThisPage =
- (bytesRemaining >
- PAGE_SIZE ? PAGE_SIZE :
- bytesRemaining);
-
- DMA_MAP_PRINT
- ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n",
- pageIdx, pages[pageIdx],
- page_to_pfn(pages[pageIdx]),
- PFN_PHYS(page_to_pfn
- (pages[pageIdx])));
-
- dma_map_add_segment(memMap,
- region,
- virtAddr,
- PFN_PHYS(page_to_pfn
- (pages
- [pageIdx])),
- bytesThisPage);
-
- virtAddr += bytesThisPage;
- bytesRemaining -= bytesThisPage;
- }
- }
-#else
- printk(KERN_ERR
- "%s: User mode pages are not yet supported\n",
- __func__);
-
- /* user pages are not physically contiguous */
-
- rc = -EINVAL;
-#endif
- break;
- }
-
- default:
- {
- printk(KERN_ERR "%s: Unsupported memory type: %d\n",
- __func__, region->memType);
-
- rc = -EINVAL;
- break;
- }
- }
-
- if (rc != 0) {
- memMap->numRegionsUsed--;
- }
-
-out:
-
- DMA_MAP_PRINT("returning %d\n", rc);
-
- up(&memMap->lock);
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_add_segment);
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *mem, /* Virtual address that we want to get a map of */
- size_t numBytes, /* Number of bytes being mapped */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- ) {
- int rc;
-
- rc = dma_map_start(memMap, dir);
- if (rc == 0) {
- rc = dma_map_add_region(memMap, mem, numBytes);
- if (rc < 0) {
- /* Since the add fails, this function will fail, and the caller won't */
- /* call unmap, so we need to do it here. */
-
- dma_unmap(memMap, 0);
- }
- }
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_mem);
-
-/****************************************************************************/
-/**
-* Setup a descriptor ring for a given memory map.
-*
-* It is assumed that the descriptor ring has already been initialized, and
-* this routine will only reallocate a new descriptor ring if the existing
-* one is too small.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
- DMA_MemMap_t *memMap, /* Memory map that will be used */
- dma_addr_t devPhysAddr /* Physical address of device */
- ) {
- int rc;
- int numDescriptors;
- DMA_DeviceAttribute_t *devAttr;
- DMA_Region_t *region;
- DMA_Segment_t *segment;
- dma_addr_t srcPhysAddr;
- dma_addr_t dstPhysAddr;
- int regionIdx;
- int segmentIdx;
-
- devAttr = &DMA_gDeviceAttribute[dev];
-
- down(&memMap->lock);
-
- /* Figure out how many descriptors we need */
-
- numDescriptors = 0;
- for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
- region = &memMap->region[regionIdx];
-
- for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
- segmentIdx++) {
- segment = ®ion->segment[segmentIdx];
-
- if (memMap->dir == DMA_TO_DEVICE) {
- srcPhysAddr = segment->physAddr;
- dstPhysAddr = devPhysAddr;
- } else {
- srcPhysAddr = devPhysAddr;
- dstPhysAddr = segment->physAddr;
- }
-
- rc =
- dma_calculate_descriptor_count(dev, srcPhysAddr,
- dstPhysAddr,
- segment->
- numBytes);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_calculate_descriptor_count failed: %d\n",
- __func__, rc);
- goto out;
- }
- numDescriptors += rc;
- }
- }
-
- /* Adjust the size of the ring, if it isn't big enough */
-
- if (numDescriptors > devAttr->ring.descriptorsAllocated) {
- dma_free_descriptor_ring(&devAttr->ring);
- rc =
- dma_alloc_descriptor_ring(&devAttr->ring,
- numDescriptors);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_alloc_descriptor_ring failed: %d\n",
- __func__, rc);
- goto out;
- }
- } else {
- rc =
- dma_init_descriptor_ring(&devAttr->ring,
- numDescriptors);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_init_descriptor_ring failed: %d\n",
- __func__, rc);
- goto out;
- }
- }
-
- /* Populate the descriptors */
-
- for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
- region = &memMap->region[regionIdx];
-
- for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
- segmentIdx++) {
- segment = ®ion->segment[segmentIdx];
-
- if (memMap->dir == DMA_TO_DEVICE) {
- srcPhysAddr = segment->physAddr;
- dstPhysAddr = devPhysAddr;
- } else {
- srcPhysAddr = devPhysAddr;
- dstPhysAddr = segment->physAddr;
- }
-
- rc =
- dma_add_descriptors(&devAttr->ring, dev,
- srcPhysAddr, dstPhysAddr,
- segment->numBytes);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_add_descriptors failed: %d\n",
- __func__, rc);
- goto out;
- }
- }
- }
-
- rc = 0;
-
-out:
-
- up(&memMap->lock);
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_create_descriptor_ring);
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
- int dirtied /* non-zero if any of the pages were modified */
- ) {
-
- int rc = 0;
- int regionIdx;
- int segmentIdx;
- DMA_Region_t *region;
- DMA_Segment_t *segment;
-
- down(&memMap->lock);
-
- for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
- region = &memMap->region[regionIdx];
-
- for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
- segmentIdx++) {
- segment = ®ion->segment[segmentIdx];
-
- switch (region->memType) {
- case DMA_MEM_TYPE_VMALLOC:
- {
- printk(KERN_ERR
- "%s: vmalloc'd pages are not yet supported\n",
- __func__);
- rc = -EINVAL;
- goto out;
- }
-
- case DMA_MEM_TYPE_KMALLOC:
- {
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
- dma_unmap_single(NULL,
- segment->physAddr,
- segment->numBytes,
- memMap->dir);
-#endif
- break;
- }
-
- case DMA_MEM_TYPE_DMA:
- {
- dma_sync_single_for_cpu(NULL,
- segment->
- physAddr,
- segment->
- numBytes,
- memMap->dir);
- break;
- }
-
- case DMA_MEM_TYPE_USER:
- {
- /* Nothing to do here. */
-
- break;
- }
-
- default:
- {
- printk(KERN_ERR
- "%s: Unsupported memory type: %d\n",
- __func__, region->memType);
- rc = -EINVAL;
- goto out;
- }
- }
-
- segment->virtAddr = NULL;
- segment->physAddr = 0;
- segment->numBytes = 0;
- }
-
- if (region->numLockedPages > 0) {
- int pageIdx;
-
- /* Some user pages were locked. We need to go and unlock them now. */
-
- for (pageIdx = 0; pageIdx < region->numLockedPages;
- pageIdx++) {
- struct page *page =
- region->lockedPages[pageIdx];
-
- if (memMap->dir == DMA_FROM_DEVICE) {
- SetPageDirty(page);
- }
- page_cache_release(page);
- }
- kfree(region->lockedPages);
- region->numLockedPages = 0;
- region->lockedPages = NULL;
- }
-
- region->memType = DMA_MEM_TYPE_NONE;
- region->virtAddr = NULL;
- region->numBytes = 0;
- region->numSegmentsUsed = 0;
- }
- memMap->userTask = NULL;
- memMap->numRegionsUsed = 0;
- memMap->inUse = 0;
-
-out:
- up(&memMap->lock);
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_unmap);
diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h
index 1f2c5319c056..72543781207b 100644
--- a/arch/arm/mach-bcmring/include/mach/dma.h
+++ b/arch/arm/mach-bcmring/include/mach/dma.h
@@ -26,15 +26,9 @@
/* ---- Include Files ---------------------------------------------------- */
#include
-#include
#include
#include
#include
-#include
-#include
-#include
-#include
-#include
/* ---- Constants and Types ---------------------------------------------- */
@@ -111,78 +105,6 @@ typedef struct {
} DMA_DescriptorRing_t;
-/****************************************************************************
-*
-* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup
-* DMA chains from a variety of memory sources.
-*
-*****************************************************************************/
-
-#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */
- /* off not being DMA'd. */
-
-typedef enum {
- DMA_MEM_TYPE_NONE, /* Not a valid setting */
- DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */
- DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */
- DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */
- DMA_MEM_TYPE_USER, /* Memory came from user space. */
-
-} DMA_MemType_t;
-
-/* A segment represents a physically and virtually contiguous chunk of memory. */
-/* i.e. each segment can be DMA'd */
-/* A user of the DMA code will add memory regions. Each region may need to be */
-/* represented by one or more segments. */
-
-typedef struct {
- void *virtAddr; /* Virtual address used for this segment */
- dma_addr_t physAddr; /* Physical address this segment maps to */
- size_t numBytes; /* Size of the segment, in bytes */
-
-} DMA_Segment_t;
-
-/* A region represents a virtually contiguous chunk of memory, which may be */
-/* made up of multiple segments. */
-
-typedef struct {
- DMA_MemType_t memType;
- void *virtAddr;
- size_t numBytes;
-
- /* Each region (virtually contiguous) consists of one or more segments. Each */
- /* segment is virtually and physically contiguous. */
-
- int numSegmentsUsed;
- int numSegmentsAllocated;
- DMA_Segment_t *segment;
-
- /* When a region corresponds to user memory, we need to lock all of the pages */
- /* down before we can figure out the physical addresses. The lockedPage array contains */
- /* the pages that were locked, and which subsequently need to be unlocked once the */
- /* memory is unmapped. */
-
- unsigned numLockedPages;
- struct page **lockedPages;
-
-} DMA_Region_t;
-
-typedef struct {
- int inUse; /* Is this mapping currently being used? */
- struct semaphore lock; /* Acquired when using this structure */
- enum dma_data_direction dir; /* Direction this transfer is intended for */
-
- /* In the event that we're mapping user memory, we need to know which task */
- /* the memory is for, so that we can obtain the correct mm locks. */
-
- struct task_struct *userTask;
-
- int numRegionsUsed;
- int numRegionsAllocated;
- DMA_Region_t *region;
-
-} DMA_MemMap_t;
-
/****************************************************************************
*
* The DMA_DeviceAttribute_t contains information which describes a
@@ -568,124 +490,6 @@ int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
size_t numBytes /* Number of bytes in each destination buffer */
);
-/****************************************************************************/
-/**
-* Initializes a DMA_MemMap_t data structure
-*/
-/****************************************************************************/
-
-int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
- );
-
-/****************************************************************************/
-/**
-* Releases any memory currently being held by a memory mapping structure.
-*/
-/****************************************************************************/
-
-int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
- );
-
-/****************************************************************************/
-/**
-* Looks at a memory address and categorizes it.
-*
-* @return One of the values from the DMA_MemType_t enumeration.
-*/
-/****************************************************************************/
-
-DMA_MemType_t dma_mem_type(void *addr);
-
-/****************************************************************************/
-/**
-* Sets the process (aka userTask) associated with a mem map. This is
-* required if user-mode segments will be added to the mapping.
-*/
-/****************************************************************************/
-
-static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,
- struct task_struct *task)
-{
- memMap->userTask = task;
-}
-
-/****************************************************************************/
-/**
-* Looks at a memory address and determines if we support DMA'ing to/from
-* that type of memory.
-*
-* @return boolean -
-* return value != 0 means dma supported
-* return value == 0 means dma not supported
-*/
-/****************************************************************************/
-
-int dma_mem_supports_dma(void *addr);
-
-/****************************************************************************/
-/**
-* Initializes a memory map for use. Since this function acquires a
-* sempaphore within the memory map, it is VERY important that dma_unmap
-* be called when you're finished using the map.
-*/
-/****************************************************************************/
-
-int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- );
-
-/****************************************************************************/
-/**
-* Adds a segment of memory to a memory map.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *mem, /* Virtual address that we want to get a map of */
- size_t numBytes /* Number of bytes being mapped */
- );
-
-/****************************************************************************/
-/**
-* Creates a descriptor ring from a memory mapping.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
- DMA_MemMap_t *memMap, /* Memory map that will be used */
- dma_addr_t devPhysAddr /* Physical address of device */
- );
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *addr, /* Virtual address that we want to get a map of */
- size_t count, /* Number of bytes being mapped */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- );
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
- int dirtied /* non-zero if any of the pages were modified */
- );
-
/****************************************************************************/
/**
* Initiates a transfer when the descriptors have already been setup.
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 6b22b543a83f..d5088900af6c 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -44,7 +44,7 @@
#include
#include
-#define DA850_EVM_PHY_ID "0:00"
+#define DA850_EVM_PHY_ID "davinci_mdio-0:00"
#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15)
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 346e1de2f5a8..849311d3cb7c 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -54,7 +54,7 @@ static inline int have_tvp7002(void)
return 0;
}
-#define DM365_EVM_PHY_ID "0:01"
+#define DM365_EVM_PHY_ID "davinci_mdio-0:01"
/*
* A MAX-II CPLD is used for various board control functions.
*/
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index a64b49cfedca..1247ecdcf752 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -40,7 +40,7 @@
#include
#include
-#define DM644X_EVM_PHY_ID "0:01"
+#define DM644X_EVM_PHY_ID "davinci_mdio-0:01"
#define LXT971_PHY_ID (0x001378e2)
#define LXT971_PHY_MASK (0xfffffff0)
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 64017558860b..872ac69fa049 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -736,7 +736,7 @@ static struct davinci_uart_config uart_config __initdata = {
.enabled_uarts = (1 << 0),
};
-#define DM646X_EVM_PHY_ID "0:01"
+#define DM646X_EVM_PHY_ID "davinci_mdio-0:01"
/*
* The following EDMA channels/slots are not being used by drivers (for
* example: Timer, GPIO, UART events etc) on dm646x, hence they are being
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index 6c4a16415d47..8d34f513d415 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -39,7 +39,7 @@
#include
#include
-#define NEUROS_OSD2_PHY_ID "0:01"
+#define NEUROS_OSD2_PHY_ID "davinci_mdio-0:01"
#define LXT971_PHY_ID 0x001378e2
#define LXT971_PHY_MASK 0xfffffff0
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index e7c0c7c53493..45e815760a27 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -21,7 +21,7 @@
#include
#include
-#define HAWKBOARD_PHY_ID "0:07"
+#define HAWKBOARD_PHY_ID "davinci_mdio-0:07"
#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 0b136a831c59..31da3c5b2ba3 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -42,7 +42,7 @@
#include
#include
-#define SFFSDR_PHY_ID "0:01"
+#define SFFSDR_PHY_ID "davinci_mdio-0:01"
static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
/* U-Boot Environment: Block 0
* UBL: Block 1
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 0ed7fdb64efb..992c4c410185 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -153,34 +153,6 @@ static struct clk pll1_sysclk3 = {
.div_reg = PLLDIV3,
};
-static struct clk pll1_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
- .name = "pll0_sysclk6",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk7 = {
- .name = "pll1_sysclk7",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
static struct clk i2c0_clk = {
.name = "i2c0",
.parent = &pll0_aux_clk,
@@ -397,10 +369,6 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
CLK("i2c_davinci.1", NULL, &i2c0_clk),
CLK(NULL, "timer0", &timerp64_0_clk),
CLK("watchdog", NULL, &timerp64_1_clk),
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 41e6612ecbaf..d965da45160e 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -213,13 +213,12 @@ config MACH_OMAP3_PANDORA
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_OMAP3_TOUCHBOOK
bool "OMAP3 Touch Book"
depends on ARCH_OMAP3
default y
- select BACKLIGHT_CLASS_DEVICE
config MACH_OMAP_3430SDP
bool "OMAP 3430 SDP board"
@@ -265,7 +264,7 @@ config MACH_OMAP_ZOOM2
select SERIAL_8250
select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_OMAP_ZOOM3
bool "OMAP3630 Zoom3 board"
@@ -275,7 +274,7 @@ config MACH_OMAP_ZOOM3
select SERIAL_8250
select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_CM_T35
bool "CompuLab CM-T35/CM-T3730 modules"
@@ -334,7 +333,7 @@ config MACH_OMAP_4430SDP
depends on ARCH_OMAP4
select OMAP_PACKAGE_CBL
select OMAP_PACKAGE_CBS
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_OMAP4_PANDA
bool "OMAP4 Panda Board"
@@ -342,7 +341,7 @@ config MACH_OMAP4_PANDA
depends on ARCH_OMAP4
select OMAP_PACKAGE_CBL
select OMAP_PACKAGE_CBS
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config OMAP3_EMU
bool "OMAP3 debugging peripherals"
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 39fba9df17fb..21fc87648660 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -52,8 +52,9 @@
#define ETH_KS8851_QUART 138
#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
#define OMAP4_SFH7741_ENABLE_GPIO 188
-#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
#define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */
#define DLP_POWER_ON_GPIO 40
@@ -603,8 +604,9 @@ static void __init omap_sfh7741prox_init(void)
}
static struct gpio sdp4430_hdmi_gpios[] = {
- { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
};
static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
@@ -621,8 +623,7 @@ static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
{
- gpio_free(HDMI_GPIO_LS_OE);
- gpio_free(HDMI_GPIO_HPD);
+ gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
}
static struct nokia_dsi_panel_data dsi1_panel = {
@@ -738,6 +739,10 @@ static void sdp4430_lcd_init(void)
pr_err("%s: Could not get lcd2_reset_gpio\n", __func__);
}
+static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
static struct omap_dss_device sdp4430_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
@@ -745,6 +750,7 @@ static struct omap_dss_device sdp4430_hdmi_device = {
.platform_enable = sdp4430_panel_enable_hdmi,
.platform_disable = sdp4430_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &sdp4430_hdmi_data,
};
static struct picodlp_panel_data sdp4430_picodlp_pdata = {
@@ -829,6 +835,10 @@ static void omap_4430sdp_display_init(void)
omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
else
omap_hdmi_init(0);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
}
#ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 30ad40db2cf3..b7779c206a90 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -51,8 +51,9 @@
#define GPIO_HUB_NRESET 62
#define GPIO_WIFI_PMENA 43
#define GPIO_WIFI_IRQ 53
-#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
/* wl127x BT, FM, GPS connectivity chip */
static int wl1271_gpios[] = {46, -1, -1};
@@ -413,8 +414,9 @@ int __init omap4_panda_dvi_init(void)
}
static struct gpio panda_hdmi_gpios[] = {
- { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
};
static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
@@ -431,10 +433,13 @@ static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
{
- gpio_free(HDMI_GPIO_LS_OE);
- gpio_free(HDMI_GPIO_HPD);
+ gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
}
+static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
static struct omap_dss_device omap4_panda_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
@@ -442,6 +447,7 @@ static struct omap_dss_device omap4_panda_hdmi_device = {
.platform_enable = omap4_panda_panel_enable_hdmi,
.platform_disable = omap4_panda_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &omap4_panda_hdmi_data,
};
static struct omap_dss_device *omap4_panda_dss_devices[] = {
@@ -473,6 +479,10 @@ void omap4_panda_display_init(void)
omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
else
omap_hdmi_init(0);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
}
static void __init omap4_panda_init(void)
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 0b510ad01a00..283d11eae693 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -405,6 +405,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
break;
default:
pr_err("Invalid McSPI Revision value\n");
+ kfree(pdata);
return -EINVAL;
}
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 3c446d1a1781..3677b1f58b85 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -103,12 +103,8 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
u32 reg;
u16 control_i2c_1;
- /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
- omap_mux_init_signal("hdmi_hpd",
- OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("hdmi_cec",
OMAP_PIN_INPUT_PULLUP);
- /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
omap_mux_init_signal("hdmi_ddc_scl",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("hdmi_ddc_sda",
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 130034bf01d5..dfffbbf4c009 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -528,7 +528,13 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
case GPMC_CONFIG_DEV_SIZE:
regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ /* clear 2 target bits */
+ regval &= ~GPMC_CONFIG1_DEVICESIZE(3);
+
+ /* set the proper value */
regval |= GPMC_CONFIG1_DEVICESIZE(wval);
+
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
break;
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index bd844af13af5..ad0adb5a1e0e 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -175,14 +175,15 @@ static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
{
u32 reg;
- if (mmc->slots[0].internal_clock) {
- reg = omap_ctrl_readl(control_devconf1_offset);
+ reg = omap_ctrl_readl(control_devconf1_offset);
+ if (mmc->slots[0].internal_clock)
reg |= OMAP2_MMCSDIO2ADPCLKISEL;
- omap_ctrl_writel(reg, control_devconf1_offset);
- }
+ else
+ reg &= ~OMAP2_MMCSDIO2ADPCLKISEL;
+ omap_ctrl_writel(reg, control_devconf1_offset);
}
-static void hsmmc23_before_set_reg(struct device *dev, int slot,
+static void hsmmc2_before_set_reg(struct device *dev, int slot,
int power_on, int vdd)
{
struct omap_mmc_platform_data *mmc = dev->platform_data;
@@ -407,14 +408,13 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
c->caps &= ~MMC_CAP_8_BIT_DATA;
c->caps |= MMC_CAP_4_BIT_DATA;
}
- /* FALLTHROUGH */
- case 3:
if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
/* off-chip level shifting, or none */
- mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
+ mmc->slots[0].before_set_reg = hsmmc2_before_set_reg;
mmc->slots[0].after_set_reg = NULL;
}
break;
+ case 3:
case 4:
case 5:
mmc->slots[0].before_set_reg = NULL;
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 3f174d51f67f..eb50c29fb644 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -388,7 +388,7 @@ static void __init omap_hwmod_init_postsetup(void)
omap_pm_if_early_init();
}
-#ifdef CONFIG_ARCH_OMAP2
+#ifdef CONFIG_SOC_OMAP2420
void __init omap2420_init_early(void)
{
omap2_set_globals_242x();
@@ -400,7 +400,9 @@ void __init omap2420_init_early(void)
omap_hwmod_init_postsetup();
omap2420_clk_init();
}
+#endif
+#ifdef CONFIG_SOC_OMAP2430
void __init omap2430_init_early(void)
{
omap2_set_globals_243x();
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
index c11273da5dcc..f08e442af397 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
@@ -55,27 +55,6 @@ struct omap_hwmod_class omap2_dss_hwmod_class = {
.reset = omap_dss_reset,
};
-/*
- * 'dispc' class
- * display controller
- */
-
-static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
- .rev_offs = 0x0000,
- .sysc_offs = 0x0010,
- .syss_offs = 0x0014,
- .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
- SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
- MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
- .sysc_fields = &omap_hwmod_sysc_type1,
-};
-
-struct omap_hwmod_class omap2_dispc_hwmod_class = {
- .name = "dispc",
- .sysc = &omap2_dispc_sysc,
-};
-
/*
* 'rfbi' class
* remote frame buffer interface
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 177dee20faef..2a6729741b06 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -28,6 +28,28 @@ struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = {
{ .name = "dispc", .dma_req = 5 },
{ .dma_req = -1 }
};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class omap2_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap2_dispc_sysc,
+};
+
/* OMAP2xxx Timer Common */
static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
.rev_offs = 0x0000,
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 5324e8d93bc0..3c8dd928628e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1480,6 +1480,28 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = {
.masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters),
};
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSC_HAS_ENAWAKEUP),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap3_dispc_sysc,
+};
+
/* l4_core -> dss_dispc */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = {
.master = &omap3xxx_l4_core_hwmod,
@@ -1503,7 +1525,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
.name = "dss_dispc",
- .class = &omap2_dispc_hwmod_class,
+ .class = &omap3_dispc_hwmod_class,
.mpu_irqs = omap2_dispc_irqs,
.main_clk = "dss1_alwon_fck",
.prcm = {
@@ -3523,12 +3545,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_uart2_hwmod,
&omap3xxx_uart3_hwmod,
- /* dss class */
- &omap3xxx_dss_dispc_hwmod,
- &omap3xxx_dss_dsi1_hwmod,
- &omap3xxx_dss_rfbi_hwmod,
- &omap3xxx_dss_venc_hwmod,
-
/* i2c class */
&omap3xxx_i2c1_hwmod,
&omap3xxx_i2c2_hwmod,
@@ -3635,6 +3651,15 @@ static __initdata struct omap_hwmod *am35xx_hwmods[] = {
NULL
};
+static __initdata struct omap_hwmod *omap3xxx_dss_hwmods[] = {
+ /* dss class */
+ &omap3xxx_dss_dispc_hwmod,
+ &omap3xxx_dss_dsi1_hwmod,
+ &omap3xxx_dss_rfbi_hwmod,
+ &omap3xxx_dss_venc_hwmod,
+ NULL
+};
+
int __init omap3xxx_hwmod_init(void)
{
int r;
@@ -3708,6 +3733,21 @@ int __init omap3xxx_hwmod_init(void)
if (h)
r = omap_hwmod_register(h);
+ if (r < 0)
+ return r;
+
+ /*
+ * DSS code presumes that dss_core hwmod is handled first,
+ * _before_ any other DSS related hwmods so register common
+ * DSS hwmods last to ensure that dss_core is already registered.
+ * Otherwise some change things may happen, for ex. if dispc
+ * is handled before dss_core and DSS is enabled in bootloader
+ * DIPSC will be reset with outputs enabled which sometimes leads
+ * to unrecoverable L3 error.
+ * XXX The long-term fix to this is to ensure modules are set up
+ * in dependency order in the hwmod core code.
+ */
+ r = omap_hwmod_register(omap3xxx_dss_hwmods);
return r;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index f9f151081760..ef0524c10a84 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -1031,6 +1031,7 @@ static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = {
static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = {
{
+ .name = "mpu",
.pa_start = 0x4012e000,
.pa_end = 0x4012e07f,
.flags = ADDR_TYPE_RT
@@ -1049,6 +1050,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = {
static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = {
{
+ .name = "dma",
.pa_start = 0x4902e000,
.pa_end = 0x4902e07f,
.flags = ADDR_TYPE_RT
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index c1c4d86a79a8..9ce765407ad5 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -19,6 +19,7 @@
#include "common.h"
#include
#include
+#include
#include "vp.h"
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 247d89478f24..f590afc1f673 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -107,18 +107,18 @@ static void omap_uart_set_noidle(struct platform_device *pdev)
omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
}
-static void omap_uart_set_forceidle(struct platform_device *pdev)
+static void omap_uart_set_smartidle(struct platform_device *pdev)
{
struct omap_device *od = to_omap_device(pdev);
- omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
+ omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART);
}
#else
static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
{}
static void omap_uart_set_noidle(struct platform_device *pdev) {}
-static void omap_uart_set_forceidle(struct platform_device *pdev) {}
+static void omap_uart_set_smartidle(struct platform_device *pdev) {}
#endif /* CONFIG_PM */
#ifdef CONFIG_OMAP_MUX
@@ -349,7 +349,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
omap_up.flags = UPF_BOOT_AUTOCONF;
omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
- omap_up.set_forceidle = omap_uart_set_forceidle;
+ omap_up.set_forceidle = omap_uart_set_smartidle;
omap_up.set_noidle = omap_uart_set_noidle;
omap_up.enable_wakeup = omap_uart_enable_wakeup;
omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 9dd93453e563..7e755bb0ffc4 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -897,7 +897,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
ret = sr_late_init(sr_info);
if (ret) {
pr_warning("%s: Error in SR late init\n", __func__);
- return ret;
+ goto err_iounmap;
}
}
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 6eeff0e0ae01..5c9acea95761 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -270,7 +270,7 @@ static struct clocksource clocksource_gpt = {
static u32 notrace dmtimer_read_sched_clock(void)
{
if (clksrc.reserved)
- return __omap_dm_timer_read_counter(clksrc.io_base, 1);
+ return __omap_dm_timer_read_counter(&clksrc, 1);
return 0;
}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 6fcf304d3cdf..a83cf51fc099 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -662,6 +662,7 @@ static struct sh_dmae_pdata usb_dma0_platform_data = {
.dmaor_is_32bit = 1,
.needs_tend_set = 1,
.no_dmars = 1,
+ .slave_only = 1,
};
static struct resource sh7372_usb_dmae0_resources[] = {
@@ -723,6 +724,7 @@ static struct sh_dmae_pdata usb_dma1_platform_data = {
.dmaor_is_32bit = 1,
.needs_tend_set = 1,
.no_dmars = 1,
+ .slave_only = 1,
};
static struct resource sh7372_usb_dmae1_resources[] = {
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index ba159370fa5f..80632e8d7538 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -225,8 +225,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
if ((area->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
continue;
if (__phys_to_pfn(area->phys_addr) > pfn ||
- __pfn_to_phys(pfn) + offset + size-1 >
- area->phys_addr + area->size-1)
+ __pfn_to_phys(pfn) + size-1 > area->phys_addr + area->size-1)
continue;
/* we can drop the lock here as we know *area is static */
read_unlock(&vmlist_lock);
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 197e96f70405..3dea7231f637 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -8,6 +8,7 @@ config AVR32
select HAVE_KPROBES
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
+ select GENERIC_ATOMIC64
select HARDIRQS_SW_RESEND
select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index d4fc1a971779..604cd9dd1333 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -26,7 +26,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -227,23 +226,5 @@ static int __init setup_bus_notifier(void)
return 0;
}
+
arch_initcall(setup_bus_notifier);
-
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
-static int __init topology_init(void)
-{
- int i, ret;
-
- for_each_present_cpu(i) {
- struct cpu *c = &per_cpu(cpu_devices, i);
-
- ret = register_cpu(c, i);
- if (ret)
- printk(KERN_WARNING "topology_init: register_cpu %d "
- "failed (%d)\n", i, ret);
- }
-
- return 0;
-}
-subsys_initcall(topology_init);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index c4c1312473fb..5ab6e89603c5 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2356,6 +2356,7 @@ config PCI
depends on HW_HAS_PCI
select PCI_DOMAINS
select GENERIC_PCI_IOMAP
+ select NO_GENERIC_PCI_IOPORT_MAP
help
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c
index 2635b1a96333..fd35daa45314 100644
--- a/arch/mips/lib/iomap-pci.c
+++ b/arch/mips/lib/iomap-pci.c
@@ -10,8 +10,8 @@
#include
#include
-static void __iomem *ioport_map_pci(struct pci_dev *dev,
- unsigned long port, unsigned int nr)
+void __iomem *__pci_ioport_map(struct pci_dev *dev,
+ unsigned long port, unsigned int nr)
{
struct pci_controller *ctrl = dev->bus->sysdata;
unsigned long base = ctrl->io_map_base;
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 3c8db65c89e5..713fb58ca507 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -859,6 +859,7 @@ config PCI
depends on SYS_SUPPORTS_PCI
select PCI_DOMAINS
select GENERIC_PCI_IOMAP
+ select NO_GENERIC_PCI_IOPORT_MAP
help
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 8f18dd090a66..1e7b0e2e764d 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -356,8 +356,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
#ifndef CONFIG_GENERIC_IOMAP
-static void __iomem *ioport_map_pci(struct pci_dev *dev,
- unsigned long port, unsigned int nr)
+void __iomem *__pci_ioport_map(struct pci_dev *dev,
+ unsigned long port, unsigned int nr)
{
struct pci_channel *chan = dev->sysdata;
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 96657992a72e..ca5580e4d813 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -33,6 +33,7 @@ config SPARC
config SPARC32
def_bool !64BIT
select GENERIC_ATOMIC64
+ select CLZ_TAB
config SPARC64
def_bool 64BIT
diff --git a/arch/sparc/lib/divdi3.S b/arch/sparc/lib/divdi3.S
index 681b3683da9e..d74bc0925f2d 100644
--- a/arch/sparc/lib/divdi3.S
+++ b/arch/sparc/lib/divdi3.S
@@ -17,23 +17,9 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
- .data
- .align 8
- .globl __clz_tab
-__clz_tab:
- .byte 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
- .byte 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
- .byte 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
- .byte 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .size __clz_tab,256
- .global .udiv
-
.text
.align 4
+ .global .udiv
.globl __divdi3
__divdi3:
save %sp,-104,%sp
diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h
index 0c9fa2745f13..b3b733262909 100644
--- a/arch/x86/include/asm/cmpxchg.h
+++ b/arch/x86/include/asm/cmpxchg.h
@@ -145,13 +145,13 @@ extern void __add_wrong_size(void)
#ifdef __HAVE_ARCH_CMPXCHG
#define cmpxchg(ptr, old, new) \
- __cmpxchg((ptr), (old), (new), sizeof(*ptr))
+ __cmpxchg(ptr, old, new, sizeof(*(ptr)))
#define sync_cmpxchg(ptr, old, new) \
- __sync_cmpxchg((ptr), (old), (new), sizeof(*ptr))
+ __sync_cmpxchg(ptr, old, new, sizeof(*(ptr)))
#define cmpxchg_local(ptr, old, new) \
- __cmpxchg_local((ptr), (old), (new), sizeof(*ptr))
+ __cmpxchg_local(ptr, old, new, sizeof(*(ptr)))
#endif
/*
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index ab4092e3214e..7b9cfc4878af 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -190,6 +190,9 @@ struct x86_emulate_ops {
int (*intercept)(struct x86_emulate_ctxt *ctxt,
struct x86_instruction_info *info,
enum x86_intercept_stage stage);
+
+ bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
};
typedef u32 __attribute__((vector_size(16))) sse128_t;
@@ -298,6 +301,19 @@ struct x86_emulate_ctxt {
#define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
X86EMUL_MODE_PROT64)
+/* CPUID vendors */
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
+
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
+
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
+
enum x86_intercept_stage {
X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */
X86_ICPT_PRE_EXCEPT,
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 73da6b64f5b7..d6bd49faa40c 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -439,7 +439,6 @@ void intel_pmu_pebs_enable(struct perf_event *event)
hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
cpuc->pebs_enabled |= 1ULL << hwc->idx;
- WARN_ON_ONCE(cpuc->enabled);
if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
intel_pmu_lbr_enable(event);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 3fab3de3ce96..47a7e63bfe54 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -72,8 +72,6 @@ void intel_pmu_lbr_enable(struct perf_event *event)
if (!x86_pmu.lbr_nr)
return;
- WARN_ON_ONCE(cpuc->enabled);
-
/*
* Reset the LBR stack if we changed task context to
* avoid data leaks.
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 1aae78f775fc..4025fe4f928f 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -252,7 +252,8 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
unsigned short ss;
unsigned long sp;
#endif
- printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
+ printk(KERN_DEFAULT
+ "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
#ifdef CONFIG_PREEMPT
printk("PREEMPT ");
#endif
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 6d728d9284bd..17107bd6e1f0 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -129,7 +129,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
if (!stack) {
if (regs)
stack = (unsigned long *)regs->sp;
- else if (task && task != current)
+ else if (task != current)
stack = (unsigned long *)task->thread.sp;
else
stack = &dummy;
@@ -269,11 +269,11 @@ void show_registers(struct pt_regs *regs)
unsigned char c;
u8 *ip;
- printk(KERN_EMERG "Stack:\n");
+ printk(KERN_DEFAULT "Stack:\n");
show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
- 0, KERN_EMERG);
+ 0, KERN_DEFAULT);
- printk(KERN_EMERG "Code: ");
+ printk(KERN_DEFAULT "Code: ");
ip = (u8 *)regs->ip - code_prologue;
if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 37a458b521a6..d840e69a853c 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -39,6 +39,14 @@ static int reboot_mode;
enum reboot_type reboot_type = BOOT_ACPI;
int reboot_force;
+/* This variable is used privately to keep track of whether or not
+ * reboot_type is still set to its default value (i.e., reboot= hasn't
+ * been set on the command line). This is needed so that we can
+ * suppress DMI scanning for reboot quirks. Without it, it's
+ * impossible to override a faulty reboot quirk without recompiling.
+ */
+static int reboot_default = 1;
+
#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
static int reboot_cpu = -1;
#endif
@@ -67,6 +75,12 @@ bool port_cf9_safe = false;
static int __init reboot_setup(char *str)
{
for (;;) {
+ /* Having anything passed on the command line via
+ * reboot= will cause us to disable DMI checking
+ * below.
+ */
+ reboot_default = 0;
+
switch (*str) {
case 'w':
reboot_mode = 0x1234;
@@ -295,14 +309,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
},
},
- { /* Handle problems with rebooting on VersaLogic Menlow boards */
- .callback = set_bios_reboot,
- .ident = "VersaLogic Menlow based board",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "VersaLogic Corporation"),
- DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
- },
- },
{ /* Handle reboot issue on Acer Aspire one */
.callback = set_kbd_reboot,
.ident = "Acer Aspire One A110",
@@ -316,7 +322,12 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
static int __init reboot_init(void)
{
- dmi_check_system(reboot_dmi_table);
+ /* Only do the DMI check if reboot_type hasn't been overridden
+ * on the command line
+ */
+ if (reboot_default) {
+ dmi_check_system(reboot_dmi_table);
+ }
return 0;
}
core_initcall(reboot_init);
@@ -465,7 +476,12 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
static int __init pci_reboot_init(void)
{
- dmi_check_system(pci_reboot_dmi_table);
+ /* Only do the DMI check if reboot_type hasn't been overridden
+ * on the command line
+ */
+ if (reboot_default) {
+ dmi_check_system(pci_reboot_dmi_table);
+ }
return 0;
}
core_initcall(pci_reboot_init);
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 05a562b85025..0982507b962a 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1891,6 +1891,51 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
ss->p = 1;
}
+static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
+{
+ struct x86_emulate_ops *ops = ctxt->ops;
+ u32 eax, ebx, ecx, edx;
+
+ /*
+ * syscall should always be enabled in longmode - so only become
+ * vendor specific (cpuid) if other modes are active...
+ */
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
+ return true;
+
+ eax = 0x00000000;
+ ecx = 0x00000000;
+ if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) {
+ /*
+ * Intel ("GenuineIntel")
+ * remark: Intel CPUs only support "syscall" in 64bit
+ * longmode. Also an 64bit guest with a
+ * 32bit compat-app running will #UD !! While this
+ * behaviour can be fixed (by emulating) into AMD
+ * response - CPUs of AMD can't behave like Intel.
+ */
+ if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
+ ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
+ edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
+ return false;
+
+ /* AMD ("AuthenticAMD") */
+ if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
+ ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
+ edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
+ return true;
+
+ /* AMD ("AMDisbetter!") */
+ if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
+ ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
+ edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
+ return true;
+ }
+
+ /* default: (not Intel, not AMD), apply Intel's stricter rules... */
+ return false;
+}
+
static int em_syscall(struct x86_emulate_ctxt *ctxt)
{
struct x86_emulate_ops *ops = ctxt->ops;
@@ -1904,9 +1949,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
ctxt->mode == X86EMUL_MODE_VM86)
return emulate_ud(ctxt);
+ if (!(em_syscall_is_enabled(ctxt)))
+ return emulate_ud(ctxt);
+
ops->get_msr(ctxt, MSR_EFER, &efer);
setup_syscalls_segments(ctxt, &cs, &ss);
+ if (!(efer & EFER_SCE))
+ return emulate_ud(ctxt);
+
ops->get_msr(ctxt, MSR_STAR, &msr_data);
msr_data >>= 32;
cs_sel = (u16)(msr_data & 0xfffc);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 14d6cadc4ba6..9cbfc0698118 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1495,6 +1495,8 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
+ bool pr = false;
+
switch (msr) {
case MSR_EFER:
return set_efer(vcpu, data);
@@ -1635,6 +1637,18 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
"0x%x data 0x%llx\n", msr, data);
break;
+ case MSR_P6_PERFCTR0:
+ case MSR_P6_PERFCTR1:
+ pr = true;
+ case MSR_P6_EVNTSEL0:
+ case MSR_P6_EVNTSEL1:
+ if (kvm_pmu_msr(vcpu, msr))
+ return kvm_pmu_set_msr(vcpu, msr, data);
+
+ if (pr || data != 0)
+ pr_unimpl(vcpu, "disabled perfctr wrmsr: "
+ "0x%x data 0x%llx\n", msr, data);
+ break;
case MSR_K7_CLK_CTL:
/*
* Ignore all writes to this no longer documented MSR.
@@ -1835,6 +1849,14 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_FAM10H_MMIO_CONF_BASE:
data = 0;
break;
+ case MSR_P6_PERFCTR0:
+ case MSR_P6_PERFCTR1:
+ case MSR_P6_EVNTSEL0:
+ case MSR_P6_EVNTSEL1:
+ if (kvm_pmu_msr(vcpu, msr))
+ return kvm_pmu_get_msr(vcpu, msr, pdata);
+ data = 0;
+ break;
case MSR_IA32_UCODE_REV:
data = 0x100000000ULL;
break;
@@ -4180,6 +4202,28 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
}
+static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
+{
+ struct kvm_cpuid_entry2 *cpuid = NULL;
+
+ if (eax && ecx)
+ cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt),
+ *eax, *ecx);
+
+ if (cpuid) {
+ *eax = cpuid->eax;
+ *ecx = cpuid->ecx;
+ if (ebx)
+ *ebx = cpuid->ebx;
+ if (edx)
+ *edx = cpuid->edx;
+ return true;
+ }
+
+ return false;
+}
+
static struct x86_emulate_ops emulate_ops = {
.read_std = kvm_read_guest_virt_system,
.write_std = kvm_write_guest_virt_system,
@@ -4211,6 +4255,7 @@ static struct x86_emulate_ops emulate_ops = {
.get_fpu = emulator_get_fpu,
.put_fpu = emulator_put_fpu,
.intercept = emulator_intercept,
+ .get_cpuid = emulator_get_cpuid,
};
static void cache_all_regs(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 9d74824a708d..f0b4caf85c1a 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -673,7 +673,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
stackend = end_of_stack(tsk);
if (tsk != &init_task && *stackend != STACK_END_MAGIC)
- printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
+ printk(KERN_EMERG "Thread overran stack, or stack corrupted\n");
tsk->thread.cr2 = address;
tsk->thread.trap_no = 14;
@@ -684,7 +684,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
sig = 0;
/* Executive summary in case the body of the oops scrolled away */
- printk(KERN_EMERG "CR2: %016lx\n", address);
+ printk(KERN_DEFAULT "CR2: %016lx\n", address);
oops_end(flags, regs, sig);
}
diff --git a/arch/xtensa/include/asm/string.h b/arch/xtensa/include/asm/string.h
index 5fb8c27cbef5..405a8c49ff2c 100644
--- a/arch/xtensa/include/asm/string.h
+++ b/arch/xtensa/include/asm/string.h
@@ -118,7 +118,4 @@ extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
/* Don't build bcopy at all ... */
#define __HAVE_ARCH_BCOPY
-#define __HAVE_ARCH_MEMSCAN
-#define memscan memchr
-
#endif /* _XTENSA_STRING_H */
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 2b805d7ef317..8ae05ce18500 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -579,13 +579,6 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
goto err_free_cpumask;
}
- /*
- * Do not start hotplugged CPUs now, but when they
- * are onlined the first time
- */
- if (pr->flags.need_hotplug_init)
- return 0;
-
/*
* Do not start hotplugged CPUs now, but when they
* are onlined the first time
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index db87e78d7459..4dabf5077c48 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -208,6 +208,25 @@ static ssize_t print_cpus_offline(struct device *dev,
}
static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
+static void cpu_device_release(struct device *dev)
+{
+ /*
+ * This is an empty function to prevent the driver core from spitting a
+ * warning at us. Yes, I know this is directly opposite of what the
+ * documentation for the driver core and kobjects say, and the author
+ * of this code has already been publically ridiculed for doing
+ * something as foolish as this. However, at this point in time, it is
+ * the only way to handle the issue of statically allocated cpu
+ * devices. The different architectures will have their cpu device
+ * code reworked to properly handle this in the near future, so this
+ * function will then be changed to correctly free up the memory held
+ * by the cpu device.
+ *
+ * Never copy this way of doing things, or you too will be made fun of
+ * on the linux-kerenl list, you have been warned.
+ */
+}
+
/*
* register_cpu - Setup a sysfs device for a CPU.
* @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -221,8 +240,10 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
int error;
cpu->node_id = cpu_to_node(num);
+ memset(&cpu->dev, 0x00, sizeof(struct device));
cpu->dev.id = num;
cpu->dev.bus = &cpu_subsys;
+ cpu->dev.release = cpu_device_release;
error = device_register(&cpu->dev);
if (!error && cpu->hotpluggable)
register_cpu_control(cpu);
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index ed5de58c340f..9e60dbe9fd94 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -572,19 +572,36 @@ static int init_memory_block(struct memory_block **memory,
}
static int add_memory_section(int nid, struct mem_section *section,
+ struct memory_block **mem_p,
unsigned long state, enum mem_add_context context)
{
- struct memory_block *mem;
+ struct memory_block *mem = NULL;
+ int scn_nr = __section_nr(section);
int ret = 0;
mutex_lock(&mem_sysfs_mutex);
- mem = find_memory_block(section);
+ if (context == BOOT) {
+ /* same memory block ? */
+ if (mem_p && *mem_p)
+ if (scn_nr >= (*mem_p)->start_section_nr &&
+ scn_nr <= (*mem_p)->end_section_nr) {
+ mem = *mem_p;
+ kobject_get(&mem->dev.kobj);
+ }
+ } else
+ mem = find_memory_block(section);
+
if (mem) {
mem->section_count++;
kobject_put(&mem->dev.kobj);
- } else
+ } else {
ret = init_memory_block(&mem, section, state);
+ /* store memory_block pointer for next loop */
+ if (!ret && context == BOOT)
+ if (mem_p)
+ *mem_p = mem;
+ }
if (!ret) {
if (context == HOTPLUG &&
@@ -627,7 +644,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
*/
int register_new_memory(int nid, struct mem_section *section)
{
- return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG);
+ return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG);
}
int unregister_memory_section(struct mem_section *section)
@@ -647,6 +664,7 @@ int __init memory_dev_init(void)
int ret;
int err;
unsigned long block_sz;
+ struct memory_block *mem = NULL;
ret = subsys_system_register(&memory_subsys, NULL);
if (ret)
@@ -662,7 +680,10 @@ int __init memory_dev_init(void)
for (i = 0; i < NR_MEM_SECTIONS; i++) {
if (!present_section_nr(i))
continue;
- err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE,
+ /* don't need to reuse memory_block if only one per block */
+ err = add_memory_section(0, __nr_to_section(i),
+ (sections_per_block == 1) ? NULL : &mem,
+ MEM_ONLINE,
BOOT);
if (!ret)
ret = err;
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 44f427a66117..90aa2a11a933 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -456,7 +456,15 @@ static int link_mem_sections(int nid)
if (!present_section_nr(section_nr))
continue;
mem_sect = __nr_to_section(section_nr);
+
+ /* same memblock ? */
+ if (mem_blk)
+ if ((section_nr >= mem_blk->start_section_nr) &&
+ (section_nr <= mem_blk->end_section_nr))
+ continue;
+
mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
+
ret = register_mem_sect_under_node(mem_blk, nid);
if (!err)
err = ret;
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index febbc0a1222a..ec31f7dd5549 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -169,10 +169,8 @@ int bcma_bus_register(struct bcma_bus *bus)
err = bcma_sprom_get(bus);
if (err == -ENOENT) {
pr_err("No SPROM available\n");
- } else if (err) {
+ } else if (err)
pr_err("Failed to get SPROM: %d\n", err);
- return -ENOENT;
- }
/* Register found cores */
bcma_register_cores(bus);
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 3fd31dec8c9c..a6278e7e61a0 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -380,6 +380,7 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
rbdc = __rbd_client_find(opt);
if (rbdc) {
ceph_destroy_options(opt);
+ kfree(rbd_opts);
/* using an existing client */
kref_get(&rbdc->kref);
@@ -406,15 +407,15 @@ done_err:
/*
* Destroy ceph client
+ *
+ * Caller must hold node_lock.
*/
static void rbd_client_release(struct kref *kref)
{
struct rbd_client *rbdc = container_of(kref, struct rbd_client, kref);
dout("rbd_release_client %p\n", rbdc);
- spin_lock(&node_lock);
list_del(&rbdc->node);
- spin_unlock(&node_lock);
ceph_destroy_client(rbdc->client);
kfree(rbdc->rbd_opts);
@@ -427,7 +428,9 @@ static void rbd_client_release(struct kref *kref)
*/
static void rbd_put_client(struct rbd_device *rbd_dev)
{
+ spin_lock(&node_lock);
kref_put(&rbd_dev->rbd_client->kref, rbd_client_release);
+ spin_unlock(&node_lock);
rbd_dev->rbd_client = NULL;
rbd_dev->client = NULL;
}
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 97f87b29b9f3..f4aed5fc2cb6 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1343,7 +1343,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
tasklet_init(&atchan->tasklet, atc_tasklet,
(unsigned long)atchan);
- atc_enable_irq(atchan);
+ atc_enable_chan_irq(atdma, i);
}
/* set base routines */
@@ -1410,7 +1410,7 @@ static int __exit at_dma_remove(struct platform_device *pdev)
struct at_dma_chan *atchan = to_at_dma_chan(chan);
/* Disable interrupts */
- atc_disable_irq(atchan);
+ atc_disable_chan_irq(atdma, chan->chan_id);
tasklet_disable(&atchan->tasklet);
tasklet_kill(&atchan->tasklet);
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index dcaedfc181cf..a8d3277d60b5 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -327,28 +327,27 @@ static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli)
}
-static void atc_setup_irq(struct at_dma_chan *atchan, int on)
+static void atc_setup_irq(struct at_dma *atdma, int chan_id, int on)
{
- struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
- u32 ebci;
+ u32 ebci;
/* enable interrupts on buffer transfer completion & error */
- ebci = AT_DMA_BTC(atchan->chan_common.chan_id)
- | AT_DMA_ERR(atchan->chan_common.chan_id);
+ ebci = AT_DMA_BTC(chan_id)
+ | AT_DMA_ERR(chan_id);
if (on)
dma_writel(atdma, EBCIER, ebci);
else
dma_writel(atdma, EBCIDR, ebci);
}
-static inline void atc_enable_irq(struct at_dma_chan *atchan)
+static void atc_enable_chan_irq(struct at_dma *atdma, int chan_id)
{
- atc_setup_irq(atchan, 1);
+ atc_setup_irq(atdma, chan_id, 1);
}
-static inline void atc_disable_irq(struct at_dma_chan *atchan)
+static void atc_disable_chan_irq(struct at_dma *atdma, int chan_id)
{
- atc_setup_irq(atchan, 0);
+ atc_setup_irq(atdma, chan_id, 0);
}
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 2b8661b54eaf..24225f0fdcd8 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -599,7 +599,7 @@ static int dmatest_add_channel(struct dma_chan *chan)
}
if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) {
cnt = dmatest_add_threads(dtc, DMA_PQ);
- thread_count += cnt > 0 ?: 0;
+ thread_count += cnt > 0 ? cnt : 0;
}
pr_info("dmatest: Started %u threads using %s\n",
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index a8af379680c1..8bc5acf36ee5 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1102,11 +1102,13 @@ static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
case DMA_SLAVE_CONFIG:
if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
sdmac->per_address = dmaengine_cfg->src_addr;
- sdmac->watermark_level = dmaengine_cfg->src_maxburst;
+ sdmac->watermark_level = dmaengine_cfg->src_maxburst *
+ dmaengine_cfg->src_addr_width;
sdmac->word_size = dmaengine_cfg->src_addr_width;
} else {
sdmac->per_address = dmaengine_cfg->dst_addr;
- sdmac->watermark_level = dmaengine_cfg->dst_maxburst;
+ sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
+ dmaengine_cfg->dst_addr_width;
sdmac->word_size = dmaengine_cfg->dst_addr_width;
}
sdmac->direction = dmaengine_cfg->direction;
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 54043cd831c8..812fd76e9c18 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -1262,7 +1262,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&shdev->common.channels);
- dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
+ if (!pdata->slave_only)
+ dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
if (pdata->slave && pdata->slave_num)
dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 6628feaa7622..7f5f0da726da 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -263,6 +263,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
static char ohci_driver_name[] = KBUILD_MODNAME;
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
+#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020
@@ -289,6 +290,9 @@ static const struct {
{PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
QUIRK_NO_MSI},
+ {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,
+ QUIRK_RESET_PACKET},
+
{PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
QUIRK_NO_MSI},
@@ -299,7 +303,7 @@ static const struct {
QUIRK_NO_MSI},
{PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
- QUIRK_CYCLE_TIMER},
+ QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
{PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c
index 5b6948081f8f..ddfacc5ce56d 100644
--- a/drivers/gpio/gpio-lpc32xx.c
+++ b/drivers/gpio/gpio-lpc32xx.c
@@ -96,7 +96,7 @@ static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
};
static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
- "gpi000", "gpio01", "gpio02", "gpio03",
+ "gpio00", "gpio01", "gpio02", "gpio03",
"gpio04", "gpio05"
};
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c
index 03d6dd5dcb77..f0febe5b8221 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -448,6 +448,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
chip->reg = chip->base;
chip->ch = i;
mutex_init(&chip->lock);
+ spin_lock_init(&chip->spinlock);
ioh_gpio_setup(chip, num_ports[i]);
ret = gpiochip_add(&chip->gpio);
if (ret) {
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c
index 68fa55e86eb1..e8729cc2ba2b 100644
--- a/drivers/gpio/gpio-pch.c
+++ b/drivers/gpio/gpio-pch.c
@@ -392,6 +392,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev,
chip->reg = chip->base;
pci_set_drvdata(pdev, chip);
mutex_init(&chip->lock);
+ spin_lock_init(&chip->spinlock);
pch_gpio_setup(chip);
ret = gpiochip_add(&chip->gpio);
if (ret) {
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index a7661773c052..0a79a1167a25 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -2387,27 +2387,30 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
};
#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
-static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np,
- const void *gpio_spec, u32 *flags)
+static int exynos4_gpio_xlate(struct gpio_chip *gc,
+ const struct of_phandle_args *gpiospec, u32 *flags)
{
- const __be32 *gpio = gpio_spec;
- const u32 n = be32_to_cpup(gpio);
- unsigned int pin = gc->base + be32_to_cpu(gpio[0]);
+ unsigned int pin;
if (WARN_ON(gc->of_gpio_n_cells < 4))
return -EINVAL;
- if (n > gc->ngpio)
+ if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
- if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1]))))
+ if (gpiospec->args[0] > gc->ngpio)
+ return -EINVAL;
+
+ pin = gc->base + gpiospec->args[0];
+
+ if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
pr_warn("gpio_xlate: failed to set pin function\n");
- if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2])))
+ if (s3c_gpio_setpull(pin, gpiospec->args[2]))
pr_warn("gpio_xlate: failed to set pin pull up/down\n");
- if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3])))
+ if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
pr_warn("gpio_xlate: failed to set pin drive strength\n");
- return n;
+ return gpiospec->args[0];
}
static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index ddd70db45f76..637fcc3766c7 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -315,7 +315,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
if (err)
return err;
- if (__get_user(c32.auth, &client->auth)
+ if (__get_user(c32.idx, &client->idx)
+ || __get_user(c32.auth, &client->auth)
|| __get_user(c32.pid, &client->pid)
|| __get_user(c32.uid, &client->uid)
|| __get_user(c32.magic, &client->magic)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b3b51c43dad0..00fbff5ddd81 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1872,7 +1872,7 @@ static void intel_update_fbc(struct drm_device *dev)
if (enable_fbc < 0) {
DRM_DEBUG_KMS("fbc set to per-chip default\n");
enable_fbc = 1;
- if (INTEL_INFO(dev)->gen <= 5)
+ if (INTEL_INFO(dev)->gen <= 6)
enable_fbc = 0;
}
if (!enable_fbc) {
@@ -5307,6 +5307,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
}
}
+ pipeconf &= ~PIPECONF_INTERLACE_MASK;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
/* the chip adds 2 halflines automatically */
@@ -5317,7 +5318,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
adjusted_mode->crtc_vsync_end -= 1;
adjusted_mode->crtc_vsync_start -= 1;
} else
- pipeconf &= ~PIPECONF_INTERLACE_MASK; /* progressive */
+ pipeconf |= PIPECONF_PROGRESSIVE;
I915_WRITE(HTOTAL(pipe),
(adjusted_mode->crtc_hdisplay - 1) |
@@ -5902,6 +5903,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
}
}
+ pipeconf &= ~PIPECONF_INTERLACE_MASK;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
/* the chip adds 2 halflines automatically */
@@ -5912,7 +5914,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
adjusted_mode->crtc_vsync_end -= 1;
adjusted_mode->crtc_vsync_start -= 1;
} else
- pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */
+ pipeconf |= PIPECONF_PROGRESSIVE;
I915_WRITE(HTOTAL(pipe),
(adjusted_mode->crtc_hdisplay - 1) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index db3b461ad412..94f860cce3f7 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -208,17 +208,8 @@ intel_dp_link_clock(uint8_t link_bw)
*/
static int
-intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp)
+intel_dp_link_required(int pixel_clock, int bpp)
{
- struct drm_crtc *crtc = intel_dp->base.base.crtc;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int bpp = 24;
-
- if (check_bpp)
- bpp = check_bpp;
- else if (intel_crtc)
- bpp = intel_crtc->bpp;
-
return (pixel_clock * bpp + 9) / 10;
}
@@ -245,12 +236,11 @@ intel_dp_mode_valid(struct drm_connector *connector,
return MODE_PANEL;
}
- mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0);
+ mode_rate = intel_dp_link_required(mode->clock, 24);
max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
if (mode_rate > max_rate) {
- mode_rate = intel_dp_link_required(intel_dp,
- mode->clock, 18);
+ mode_rate = intel_dp_link_required(mode->clock, 18);
if (mode_rate > max_rate)
return MODE_CLOCK_HIGH;
else
@@ -683,7 +673,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
int lane_count, clock;
int max_lane_count = intel_dp_max_lane_count(intel_dp);
int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
- int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0;
+ int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -701,7 +691,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
- if (intel_dp_link_required(intel_dp, mode->clock, bpp)
+ if (intel_dp_link_required(mode->clock, bpp)
<= link_avail) {
intel_dp->link_bw = bws[clock];
intel_dp->lane_count = lane_count;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 798f6e1aa544..aa84832b0e1a 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -692,6 +692,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
},
},
+ {
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "AOpen i45GMx-I",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+ DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
+ },
+ },
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Aopen i945GTt-VFA",
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 1e382ad5a2b8..a37c31e358aa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -54,9 +54,10 @@ struct bit_entry {
int bit_table(struct drm_device *, u8 id, struct bit_entry *);
enum dcb_gpio_tag {
- DCB_GPIO_TVDAC0 = 0xc,
+ DCB_GPIO_PANEL_POWER = 0x01,
+ DCB_GPIO_TVDAC0 = 0x0c,
DCB_GPIO_TVDAC1 = 0x2d,
- DCB_GPIO_PWM_FAN = 0x9,
+ DCB_GPIO_PWM_FAN = 0x09,
DCB_GPIO_FAN_SENSE = 0x3d,
DCB_GPIO_UNUSED = 0xff
};
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 3cb52bc52b21..795a9e3c990a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -219,6 +219,16 @@ nouveau_display_init(struct drm_device *dev)
if (ret)
return ret;
+ /* power on internal panel if it's not already. the init tables of
+ * some vbios default this to off for some reason, causing the
+ * panel to not work after resume
+ */
+ if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) {
+ nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true);
+ msleep(300);
+ }
+
+ /* enable polling for external displays */
drm_kms_helper_poll_enable(dev);
/* enable hotplug interrupts */
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index e4a7cfe7898d..81d7962e7252 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -124,7 +124,7 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n");
int nouveau_ctxfw;
module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
-MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n");
+MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS\n");
int nouveau_mxmdcb = 1;
module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400);
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 5f0bc57fdaab..7ce3fde40743 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -379,6 +379,25 @@ retry:
return 0;
}
+static int
+validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo)
+{
+ struct nouveau_fence *fence = NULL;
+ int ret = 0;
+
+ spin_lock(&nvbo->bo.bdev->fence_lock);
+ if (nvbo->bo.sync_obj)
+ fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+ spin_unlock(&nvbo->bo.bdev->fence_lock);
+
+ if (fence) {
+ ret = nouveau_fence_sync(fence, chan);
+ nouveau_fence_unref(&fence);
+ }
+
+ return ret;
+}
+
static int
validate_list(struct nouveau_channel *chan, struct list_head *list,
struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr)
@@ -393,7 +412,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
list_for_each_entry(nvbo, list, entry) {
struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
- ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
+ ret = validate_sync(chan, nvbo);
if (unlikely(ret)) {
NV_ERROR(dev, "fail pre-validate sync\n");
return ret;
@@ -416,7 +435,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
return ret;
}
- ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
+ ret = validate_sync(chan, nvbo);
if (unlikely(ret)) {
NV_ERROR(dev, "fail post-validate sync\n");
return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mxm.c b/drivers/gpu/drm/nouveau/nouveau_mxm.c
index 8bccddf4eff0..e5a64f0f4cb7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mxm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mxm.c
@@ -656,7 +656,16 @@ nouveau_mxm_init(struct drm_device *dev)
if (mxm_shadow(dev, mxm[0])) {
MXM_MSG(dev, "failed to locate valid SIS\n");
+#if 0
+ /* we should, perhaps, fall back to some kind of limited
+ * mode here if the x86 vbios hasn't already done the
+ * work for us (so we prevent loading with completely
+ * whacked vbios tables).
+ */
return -EINVAL;
+#else
+ return 0;
+#endif
}
MXM_MSG(dev, "MXMS Version %d.%d\n",
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index 03937212e9d8..ec5481dfcd82 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -495,9 +495,9 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv50_pm_state *info;
struct pll_lims pll;
- int ret = -EINVAL;
+ int clk, ret = -EINVAL;
int N, M, P1, P2;
- u32 clk, out;
+ u32 out;
if (dev_priv->chipset == 0xaa ||
dev_priv->chipset == 0xac)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 891935271d34..742f17f009a9 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1184,7 +1184,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
- crtc->mode.vdisplay);
+ target_fb->height);
x &= ~3;
y &= ~1;
WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
@@ -1353,7 +1353,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
- crtc->mode.vdisplay);
+ target_fb->height);
x &= ~3;
y &= ~1;
WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index a71557ce01dc..552b436451fd 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -564,9 +564,21 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
ENCODER_OBJECT_ID_NUTMEG)
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
- ENCODER_OBJECT_ID_TRAVIS)
- panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
- else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ ENCODER_OBJECT_ID_TRAVIS) {
+ u8 id[6];
+ int i;
+ for (i = 0; i < 6; i++)
+ id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i);
+ if (id[0] == 0x73 &&
+ id[1] == 0x69 &&
+ id[2] == 0x76 &&
+ id[3] == 0x61 &&
+ id[4] == 0x72 &&
+ id[5] == 0x54)
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
+ else
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+ } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index ae09fe82afbc..9be353b894cc 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3191,6 +3191,7 @@ static int evergreen_startup(struct radeon_device *rdev)
if (r) {
DRM_ERROR("radeon: failed testing IB (%d).\n", r);
rdev->accel_working = false;
+ return r;
}
r = r600_audio_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index d996f4381130..accc032c103f 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -468,27 +468,42 @@ set_default_state(struct radeon_device *rdev)
radeon_ring_write(ring, sq_stack_resource_mgmt_2);
}
+#define I2F_MAX_BITS 15
+#define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1)
+#define I2F_SHIFT (24 - I2F_MAX_BITS)
+
+/*
+ * Converts unsigned integer into 32-bit IEEE floating point representation.
+ * Conversion is not universal and only works for the range from 0
+ * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between
+ * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary,
+ * I2F_MAX_BITS can be increased, but that will add to the loop iterations
+ * and slow us down. Conversion is done by shifting the input and counting
+ * down until the first 1 reaches bit position 23. The resulting counter
+ * and the shifted input are, respectively, the exponent and the fraction.
+ * The sign is always zero.
+ */
static uint32_t i2f(uint32_t input)
{
u32 result, i, exponent, fraction;
- if ((input & 0x3fff) == 0)
- result = 0; /* 0 is a special case */
+ WARN_ON_ONCE(input > I2F_MAX_INPUT);
+
+ if ((input & I2F_MAX_INPUT) == 0)
+ result = 0;
else {
- exponent = 140; /* exponent biased by 127; */
- fraction = (input & 0x3fff) << 10; /* cheat and only
- handle numbers below 2^^15 */
- for (i = 0; i < 14; i++) {
+ exponent = 126 + I2F_MAX_BITS;
+ fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT;
+
+ for (i = 0; i < I2F_MAX_BITS; i++) {
if (fraction & 0x800000)
break;
else {
- fraction = fraction << 1; /* keep
- shifting left until top bit = 1 */
+ fraction = fraction << 1;
exponent = exponent - 1;
}
}
- result = exponent << 23 | (fraction & 0x7fffff); /* mask
- off top bit; assumed 1 */
+ result = exponent << 23 | (fraction & 0x7fffff);
}
return result;
}
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 13ac63ba6075..98724fcb0088 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -59,8 +59,9 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
obj = (union acpi_object *)buffer.pointer;
memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+ len = obj->buffer.length;
kfree(buffer.pointer);
- return obj->buffer.length;
+ return len;
}
bool radeon_atrm_supported(struct pci_dev *pdev)
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index cec51a5b69dd..49f7cb7e226b 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -883,6 +883,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
+ drm_kms_helper_poll_disable(dev);
+
/* turn off display hw */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
@@ -972,6 +974,8 @@ int radeon_resume_kms(struct drm_device *dev)
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
}
+
+ drm_kms_helper_poll_enable(dev);
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index e2a393ff0c44..98a8ad680109 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -958,6 +958,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
+ i2c->adapter.dev.parent = &dev->pdev->dev;
i2c->dev = dev;
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon aux bus %s", name);
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
index 0c33ae9cf0f0..406632472c1b 100644
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -548,6 +548,7 @@ static int mousevsc_remove(struct hv_device *dev)
struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
vmbus_close(dev->channel);
+ hid_hw_stop(input_dev->hid_device);
hid_destroy_device(input_dev->hid_device);
mousevsc_free_device(input_dev);
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index b47e58b52d9f..acab74cde727 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -531,7 +531,6 @@ static int wacom_probe(struct hid_device *hdev,
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
- power_supply_powers(&wdata->battery, &hdev->dev);
ret = power_supply_register(&hdev->dev, &wdata->battery);
if (ret) {
@@ -540,6 +539,8 @@ static int wacom_probe(struct hid_device *hdev,
goto err_battery;
}
+ power_supply_powers(&wdata->battery, &hdev->dev);
+
wdata->ac.properties = wacom_ac_props;
wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
wdata->ac.get_property = wacom_ac_get_property;
@@ -547,14 +548,14 @@ static int wacom_probe(struct hid_device *hdev,
wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
wdata->ac.use_for_apm = 0;
- power_supply_powers(&wdata->battery, &hdev->dev);
-
ret = power_supply_register(&hdev->dev, &wdata->ac);
if (ret) {
hid_warn(hdev,
"can't create ac battery attribute, err: %d\n", ret);
goto err_ac;
}
+
+ power_supply_powers(&wdata->ac, &hdev->dev);
#endif
return 0;
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index fc253b472f9d..cac3589b1ed5 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -1226,14 +1226,14 @@ static int wiimote_hid_probe(struct hid_device *hdev,
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
- power_supply_powers(&wdata->battery, &hdev->dev);
-
ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
if (ret) {
hid_err(hdev, "Cannot register battery device\n");
goto err_battery;
}
+ power_supply_powers(&wdata->battery, &hdev->dev);
+
ret = wiimote_leds_create(wdata);
if (ret)
goto err_free;
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 7c297d305d5d..b1ec0e2aeb57 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -922,11 +922,11 @@ void hiddev_disconnect(struct hid_device *hid)
struct hiddev *hiddev = hid->hiddev;
struct usbhid_device *usbhid = hid->driver_data;
+ usb_deregister_dev(usbhid->intf, &hiddev_class);
+
mutex_lock(&hiddev->existancelock);
hiddev->exist = 0;
- usb_deregister_dev(usbhid->intf, &hiddev_class);
-
if (hiddev->open) {
mutex_unlock(&hiddev->existancelock);
usbhid_close(hiddev->hid);
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index eedf574ab539..f609b5727ba9 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -172,7 +172,7 @@ static inline void f75375_write8(struct i2c_client *client, u8 reg,
static inline void f75375_write16(struct i2c_client *client, u8 reg,
u16 value)
{
- int err = i2c_smbus_write_byte_data(client, reg, (value << 8));
+ int err = i2c_smbus_write_byte_data(client, reg, (value >> 8));
if (err)
return;
i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
@@ -200,9 +200,6 @@ static struct f75375_data *f75375_update_device(struct device *dev)
f75375_read16(client, F75375_REG_FAN_MIN(nr));
data->fan_target[nr] =
f75375_read16(client, F75375_REG_FAN_EXP(nr));
- data->pwm[nr] = f75375_read8(client,
- F75375_REG_FAN_PWM_DUTY(nr));
-
}
for (nr = 0; nr < 4; nr++) {
data->in_max[nr] =
@@ -218,6 +215,8 @@ static struct f75375_data *f75375_update_device(struct device *dev)
if (time_after(jiffies, data->last_updated + 2 * HZ)
|| !data->valid) {
for (nr = 0; nr < 2; nr++) {
+ data->pwm[nr] = f75375_read8(client,
+ F75375_REG_FAN_PWM_DUTY(nr));
/* assign MSB, therefore shift it by 8 bits */
data->temp11[nr] =
f75375_read8(client, F75375_REG_TEMP(nr)) << 8;
@@ -369,7 +368,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
fanmode |= (3 << FAN_CTRL_MODE(nr));
break;
case 2: /* AUTOMATIC*/
- fanmode |= (2 << FAN_CTRL_MODE(nr));
+ fanmode |= (1 << FAN_CTRL_MODE(nr));
break;
case 3: /* fan speed */
break;
@@ -723,7 +722,7 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
if (data->kind == f75387) {
bool manu, duty;
- if (!(conf & (1 << F75387_FAN_CTRL_LINEAR(nr))))
+ if (!(mode & (1 << F75387_FAN_CTRL_LINEAR(nr))))
data->pwm_mode[nr] = 1;
manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 2dfae7d7cc5b..5276d1933dbc 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -1920,9 +1920,26 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
fan4min = 0;
fan5pin = 0;
} else if (sio_data->kind == nct6776) {
- fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
- fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
- fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+ bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
+
+ superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+ regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
+
+ if (regval & 0x80)
+ fan3pin = gpok;
+ else
+ fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
+
+ if (regval & 0x40)
+ fan4pin = gpok;
+ else
+ fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
+
+ if (regval & 0x20)
+ fan5pin = gpok;
+ else
+ fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+
fan4min = fan4pin;
} else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
fan3pin = 1;
@@ -2332,11 +2349,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
/* Read fan clock dividers immediately */
w83627ehf_update_fan_div_common(dev, data);
- /* Read pwm data to save original values */
- w83627ehf_update_pwm_common(dev, data);
- for (i = 0; i < data->pwm_num; i++)
- data->pwm_enable_orig[i] = data->pwm_enable[i];
-
/* Read pwm data to save original values */
w83627ehf_update_pwm_common(dev, data);
for (i = 0; i < data->pwm_num; i++)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f713eac55047..801df6000e9b 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1018,7 +1018,7 @@ omap_i2c_probe(struct platform_device *pdev)
goto err_release_region;
}
- match = of_match_device(omap_i2c_of_match, &pdev->dev);
+ match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
if (match) {
u32 freq = 100000; /* default to 100000 Hz */
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index b37b0c02a7b9..5034a87cc72d 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -808,9 +808,12 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf,
return PTR_ERR(ctx);
if (cmd.conn_param.valid) {
- ctx->uid = cmd.uid;
ucma_copy_conn_param(&conn_param, &cmd.conn_param);
+ mutex_lock(&file->mut);
ret = rdma_accept(ctx->cm_id, &conn_param);
+ if (!ret)
+ ctx->uid = cmd.uid;
+ mutex_unlock(&file->mut);
} else
ret = rdma_accept(ctx->cm_id, NULL);
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index b930da4c0c63..4d27e4c3fe34 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1485,6 +1485,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
qp->event_handler = attr.event_handler;
qp->qp_context = attr.qp_context;
qp->qp_type = attr.qp_type;
+ atomic_set(&qp->usecnt, 0);
atomic_inc(&pd->usecnt);
atomic_inc(&attr.send_cq->usecnt);
if (attr.recv_cq)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 602b1bd723a9..575b78045aaf 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -421,6 +421,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->uobject = NULL;
qp->qp_type = qp_init_attr->qp_type;
+ atomic_set(&qp->usecnt, 0);
if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
qp->event_handler = __ib_shared_qp_event_handler;
qp->qp_context = qp;
@@ -430,7 +431,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->xrcd = qp_init_attr->xrcd;
atomic_inc(&qp_init_attr->xrcd->usecnt);
INIT_LIST_HEAD(&qp->open_list);
- atomic_set(&qp->usecnt, 0);
real_qp = qp;
qp = __ib_open_qp(real_qp, qp_init_attr->event_handler,
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index b7d4216db3c3..a4de9d58e9b4 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -89,7 +89,7 @@ static int create_file(const char *name, umode_t mode,
error = ipathfs_mknod(parent->d_inode, *dentry,
mode, fops, data);
else
- error = PTR_ERR(dentry);
+ error = PTR_ERR(*dentry);
mutex_unlock(&parent->d_inode->i_mutex);
return error;
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 95c94d8f0254..259b0670b51c 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -257,12 +257,9 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
return IB_MAD_RESULT_SUCCESS;
/*
- * Don't process SMInfo queries or vendor-specific
- * MADs -- the SMA can't handle them.
+ * Don't process SMInfo queries -- the SMA can't handle them.
*/
- if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO ||
- ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) ==
- IB_SMP_ATTR_VENDOR_MASK))
+ if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO)
return IB_MAD_RESULT_SUCCESS;
} else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 ||
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 7013da5e9eda..7140199f562e 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 568b4f11380a..c438e4691b3c 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index fc5192ee928b..c5e4cb2d3223 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -233,6 +233,7 @@ static int send_mpa_reject(struct nes_cm_node *cm_node)
u8 *start_ptr = &start_addr;
u8 **start_buff = &start_ptr;
u16 buff_len = 0;
+ struct ietf_mpa_v1 *mpa_frame;
skb = dev_alloc_skb(MAX_CM_BUFFER);
if (!skb) {
@@ -242,6 +243,8 @@ static int send_mpa_reject(struct nes_cm_node *cm_node)
/* send an MPA reject frame */
cm_build_mpa_frame(cm_node, start_buff, &buff_len, NULL, MPA_KEY_REPLY);
+ mpa_frame = (struct ietf_mpa_v1 *)*start_buff;
+ mpa_frame->flags |= IETF_MPA_FLAGS_REJECT;
form_cm_frame(skb, cm_node, NULL, 0, *start_buff, buff_len, SET_ACK | SET_FIN);
cm_node->state = NES_CM_STATE_FIN_WAIT1;
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index bdfa1fbb35fc..4646e6666087 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_context.h b/drivers/infiniband/hw/nes/nes_context.h
index b4393a16099d..a69eef16d72d 100644
--- a/drivers/infiniband/hw/nes/nes_context.h
+++ b/drivers/infiniband/hw/nes/nes_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 055f4b545df0..d42c9f435b1b 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index 0b590e152c6a..d748e4b31b8d 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+* Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_mgt.c b/drivers/infiniband/hw/nes/nes_mgt.c
index b3b2a240c6e9..3ba7be369452 100644
--- a/drivers/infiniband/hw/nes/nes_mgt.c
+++ b/drivers/infiniband/hw/nes/nes_mgt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_mgt.h b/drivers/infiniband/hw/nes/nes_mgt.h
index 8c8af254555a..4f7f701c4a81 100644
--- a/drivers/infiniband/hw/nes/nes_mgt.h
+++ b/drivers/infiniband/hw/nes/nes_mgt.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2010 Intel-NE, Inc. All rights reserved.
+* Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 4b3fa711a247..f3a3ecf8d09e 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h
index 71e133ab209b..4926de744488 100644
--- a/drivers/infiniband/hw/nes/nes_user.h
+++ b/drivers/infiniband/hw/nes/nes_user.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c
index 8b4c2ff54888..e98f4fc0b768 100644
--- a/drivers/infiniband/hw/nes/nes_utils.c
+++ b/drivers/infiniband/hw/nes/nes_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 5095bc41c6cc..0927b5cc65d3 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -3427,6 +3427,8 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
set_wqe_32bit_value(wqe->wqe_words,
NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX,
ib_wr->wr.fast_reg.length);
+ set_wqe_32bit_value(wqe->wqe_words,
+ NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0);
set_wqe_32bit_value(wqe->wqe_words,
NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX,
ib_wr->wr.fast_reg.rkey);
@@ -3724,7 +3726,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
entry->opcode = IB_WC_SEND;
break;
case NES_IWARP_SQ_OP_LOCINV:
- entry->opcode = IB_WR_LOCAL_INV;
+ entry->opcode = IB_WC_LOCAL_INV;
break;
case NES_IWARP_SQ_OP_FAST_REG:
entry->opcode = IB_WC_FAST_REG_MR;
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h
index fe6b6e92fa90..0eff7c44d76b 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.h
+++ b/drivers/infiniband/hw/nes/nes_verbs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c
index 4f18e2d332df..d0c64d514813 100644
--- a/drivers/infiniband/hw/qib/qib_iba6120.c
+++ b/drivers/infiniband/hw/qib/qib_iba6120.c
@@ -2105,7 +2105,7 @@ static void alloc_dummy_hdrq(struct qib_devdata *dd)
dd->cspec->dummy_hdrq = dma_alloc_coherent(&dd->pcidev->dev,
dd->rcd[0]->rcvhdrq_size,
&dd->cspec->dummy_hdrq_phys,
- GFP_KERNEL | __GFP_COMP);
+ GFP_ATOMIC | __GFP_COMP);
if (!dd->cspec->dummy_hdrq) {
qib_devinfo(dd->pcidev, "Couldn't allocate dummy hdrq\n");
/* fallback to just 0'ing */
diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c
index f695061d688e..0fde788e1100 100644
--- a/drivers/infiniband/hw/qib/qib_pcie.c
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -560,7 +560,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd)
* BIOS may not set PCIe bus-utilization parameters for best performance.
* Check and optionally adjust them to maximize our throughput.
*/
-static int qib_pcie_caps = 0x51;
+static int qib_pcie_caps;
module_param_named(pcie_caps, qib_pcie_caps, int, S_IRUGO);
MODULE_PARM_DESC(pcie_caps, "Max PCIe tuning: Payload (0..3), ReadReq (4..7)");
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index cd5d05e22a77..2b73d43cd691 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -69,8 +69,8 @@ MODULE_LICENSE("Dual BSD/GPL");
*/
static u64 srpt_service_guid;
-static spinlock_t srpt_dev_lock; /* Protects srpt_dev_list. */
-static struct list_head srpt_dev_list; /* List of srpt_device structures. */
+static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */
+static LIST_HEAD(srpt_dev_list); /* List of srpt_device structures. */
static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE;
module_param(srp_max_req_size, int, 0444);
@@ -687,6 +687,7 @@ err:
while (--i >= 0)
srpt_free_ioctx(sdev, ring[i], dma_size, dir);
kfree(ring);
+ ring = NULL;
out:
return ring;
}
@@ -2595,7 +2596,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
}
ch->sess = transport_init_session();
- if (!ch->sess) {
+ if (IS_ERR(ch->sess)) {
rej->reason = __constant_cpu_to_be32(
SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
pr_debug("Failed to create session\n");
@@ -3264,8 +3265,7 @@ static void srpt_add_one(struct ib_device *device)
for (i = 0; i < sdev->srq_size; ++i)
srpt_post_recv(sdev, sdev->ioctx_ring[i]);
- WARN_ON(sdev->device->phys_port_cnt
- > sizeof(sdev->port)/sizeof(sdev->port[0]));
+ WARN_ON(sdev->device->phys_port_cnt > ARRAY_SIZE(sdev->port));
for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
sport = &sdev->port[i - 1];
@@ -4010,13 +4010,10 @@ static int __init srpt_init_module(void)
goto out;
}
- spin_lock_init(&srpt_dev_lock);
- INIT_LIST_HEAD(&srpt_dev_list);
-
- ret = -ENODEV;
srpt_target = target_fabric_configfs_init(THIS_MODULE, "srpt");
- if (!srpt_target) {
+ if (IS_ERR(srpt_target)) {
printk(KERN_ERR "couldn't register\n");
+ ret = PTR_ERR(srpt_target);
goto out;
}
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
index b4b4bbcd7f16..61e52b830816 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
@@ -35,7 +35,6 @@
#ifndef IB_SRPT_H
#define IB_SRPT_H
-#include
#include
#include
#include
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 76457d50bc34..afc166fcc3d9 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -386,7 +386,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
struct input_event event;
- int retval;
+ int retval = 0;
if (count < input_event_size())
return -EINVAL;
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c
index a588578037eb..67bec14e8b96 100644
--- a/drivers/input/keyboard/twl4030_keypad.c
+++ b/drivers/input/keyboard/twl4030_keypad.c
@@ -34,7 +34,6 @@
#include
#include
-
/*
* The TWL4030 family chips include a keypad controller that supports
* up to an 8x8 switch matrix. The controller can issue system wakeup
@@ -302,7 +301,7 @@ static int __devinit twl4030_kp_program(struct twl4030_keypad *kp)
if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0)
return -EIO;
- /* Set timeout period to 100 ms */
+ /* Set timeout period to 200 ms */
i = KEYP_PERIOD_US(200000, PTV_PRESCALER);
if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0)
return -EIO;
@@ -466,4 +465,3 @@ MODULE_AUTHOR("Texas Instruments");
MODULE_DESCRIPTION("TWL4030 Keypad Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:twl4030_keypad");
-
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index b4cfc6c8be89..5ec774d6c82b 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -512,6 +512,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
},
},
+ {
+ /* Lenovo Ideapad U455 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
+ },
+ },
{ }
};
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 8250299fd64f..4494233d331a 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -164,7 +164,8 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
struct serio_raw_client *client = file->private_data;
struct serio_raw *serio_raw = client->serio_raw;
char uninitialized_var(c);
- ssize_t retval = 0;
+ ssize_t read = 0;
+ int retval;
if (serio_raw->dead)
return -ENODEV;
@@ -180,13 +181,15 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
if (serio_raw->dead)
return -ENODEV;
- while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
- if (put_user(c, buffer++))
- return -EFAULT;
- retval++;
+ while (read < count && serio_raw_fetch_byte(serio_raw, &c)) {
+ if (put_user(c, buffer++)) {
+ retval = -EFAULT;
+ break;
+ }
+ read++;
}
- return retval;
+ return read ?: retval;
}
static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index cce1f03b8895..f75e0608be5b 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2863,6 +2863,9 @@ static unsigned device_dma_ops_init(void)
for_each_pci_dev(pdev) {
if (!check_device(&pdev->dev)) {
+
+ iommu_ignore_device(&pdev->dev);
+
unhandled += 1;
continue;
}
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 08a90b88e40d..cee307e86606 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -482,23 +482,19 @@ static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
priv = domain->priv;
- if (!priv) {
- ret = -ENODEV;
+ if (!priv)
goto fail;
- }
fl_table = priv->pgtable;
if (len != SZ_16M && len != SZ_1M &&
len != SZ_64K && len != SZ_4K) {
pr_debug("Bad length: %d\n", len);
- ret = -EINVAL;
goto fail;
}
if (!fl_table) {
pr_debug("Null page table\n");
- ret = -EINVAL;
goto fail;
}
@@ -507,7 +503,6 @@ static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
if (*fl_pte == 0) {
pr_debug("First level PTE is 0\n");
- ret = -ENODEV;
goto fail;
}
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 2339d7396b9e..802ab87a78b6 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1901,7 +1901,7 @@ static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
{
isdn_net_local *lp = netdev_priv(dev);
unsigned char *p;
- ushort len = 0;
+ int len = 0;
switch (lp->p_encap) {
case ISDN_NET_ENCAP_ETHER:
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 45e6878d7374..e59c166a0ce2 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -164,8 +164,8 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
if (drvdata->mode == LM3530_BL_MODE_ALS) {
if (pltfm->als_vmax == 0) {
- pltfm->als_vmin = als_vmin = 0;
- pltfm->als_vmin = als_vmax = LM3530_ALS_WINDOW_mV;
+ pltfm->als_vmin = 0;
+ pltfm->als_vmax = LM3530_ALS_WINDOW_mV;
}
als_vmin = pltfm->als_vmin;
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index c2907d836e4e..86cb7e5d83d5 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -56,7 +56,8 @@ struct raid_dev {
struct raid_set {
struct dm_target *ti;
- uint64_t print_flags;
+ uint32_t bitmap_loaded;
+ uint32_t print_flags;
struct mddev md;
struct raid_type *raid_type;
@@ -1085,7 +1086,7 @@ static int raid_status(struct dm_target *ti, status_type_t type,
raid_param_cnt += 2;
}
- raid_param_cnt += (hweight64(rs->print_flags & ~DMPF_REBUILD) * 2);
+ raid_param_cnt += (hweight32(rs->print_flags & ~DMPF_REBUILD) * 2);
if (rs->print_flags & (DMPF_SYNC | DMPF_NOSYNC))
raid_param_cnt--;
@@ -1197,7 +1198,12 @@ static void raid_resume(struct dm_target *ti)
{
struct raid_set *rs = ti->private;
- bitmap_load(&rs->md);
+ if (!rs->bitmap_loaded) {
+ bitmap_load(&rs->md);
+ rs->bitmap_loaded = 1;
+ } else
+ md_wakeup_thread(rs->md.thread);
+
mddev_resume(&rs->md);
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9417ae2fa0bb..ce88755baf4a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7333,7 +7333,8 @@ void md_do_sync(struct mddev *mddev)
printk(KERN_INFO
"md: checkpointing %s of %s.\n",
desc, mdname(mddev));
- mddev->recovery_cp = mddev->curr_resync;
+ mddev->recovery_cp =
+ mddev->curr_resync_completed;
}
} else
mddev->recovery_cp = MaxSector;
@@ -7351,9 +7352,9 @@ void md_do_sync(struct mddev *mddev)
rcu_read_unlock();
}
}
+ skip:
set_bit(MD_CHANGE_DEVS, &mddev->flags);
- skip:
if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
/* We completed so min/max setting can be forgotten if used. */
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index dda86293dc9f..b2d8e512d3cb 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -282,6 +282,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
/* Default PLL configuration after power up */
twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
twl6040->sysclk = 19200000;
+ twl6040->mclk = 32768;
} else {
/* already powered-down */
if (!twl6040->power_count) {
@@ -305,6 +306,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
twl6040_power_down(twl6040);
}
twl6040->sysclk = 0;
+ twl6040->mclk = 0;
}
out:
@@ -324,23 +326,38 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL);
lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL);
+ /* Force full reconfiguration when switching between PLL */
+ if (pll_id != twl6040->pll) {
+ twl6040->sysclk = 0;
+ twl6040->mclk = 0;
+ }
+
switch (pll_id) {
case TWL6040_SYSCLK_SEL_LPPLL:
/* low-power PLL divider */
- switch (freq_out) {
- case 17640000:
- lppllctl |= TWL6040_LPLLFIN;
- break;
- case 19200000:
- lppllctl &= ~TWL6040_LPLLFIN;
- break;
- default:
- dev_err(twl6040->dev,
- "freq_out %d not supported\n", freq_out);
- ret = -EINVAL;
- goto pll_out;
+ /* Change the sysclk configuration only if it has been canged */
+ if (twl6040->sysclk != freq_out) {
+ switch (freq_out) {
+ case 17640000:
+ lppllctl |= TWL6040_LPLLFIN;
+ break;
+ case 19200000:
+ lppllctl &= ~TWL6040_LPLLFIN;
+ break;
+ default:
+ dev_err(twl6040->dev,
+ "freq_out %d not supported\n",
+ freq_out);
+ ret = -EINVAL;
+ goto pll_out;
+ }
+ twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
+ lppllctl);
}
- twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
+
+ /* The PLL in use has not been change, we can exit */
+ if (twl6040->pll == pll_id)
+ break;
switch (freq_in) {
case 32768:
@@ -371,48 +388,56 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
goto pll_out;
}
- hppllctl &= ~TWL6040_MCLK_MSK;
+ if (twl6040->mclk != freq_in) {
+ hppllctl &= ~TWL6040_MCLK_MSK;
+
+ switch (freq_in) {
+ case 12000000:
+ /* PLL enabled, active mode */
+ hppllctl |= TWL6040_MCLK_12000KHZ |
+ TWL6040_HPLLENA;
+ break;
+ case 19200000:
+ /*
+ * PLL disabled
+ * (enable PLL if MCLK jitter quality
+ * doesn't meet specification)
+ */
+ hppllctl |= TWL6040_MCLK_19200KHZ;
+ break;
+ case 26000000:
+ /* PLL enabled, active mode */
+ hppllctl |= TWL6040_MCLK_26000KHZ |
+ TWL6040_HPLLENA;
+ break;
+ case 38400000:
+ /* PLL enabled, active mode */
+ hppllctl |= TWL6040_MCLK_38400KHZ |
+ TWL6040_HPLLENA;
+ break;
+ default:
+ dev_err(twl6040->dev,
+ "freq_in %d not supported\n", freq_in);
+ ret = -EINVAL;
+ goto pll_out;
+ }
- switch (freq_in) {
- case 12000000:
- /* PLL enabled, active mode */
- hppllctl |= TWL6040_MCLK_12000KHZ |
- TWL6040_HPLLENA;
- break;
- case 19200000:
/*
- * PLL disabled
- * (enable PLL if MCLK jitter quality
- * doesn't meet specification)
+ * enable clock slicer to ensure input waveform is
+ * square
*/
- hppllctl |= TWL6040_MCLK_19200KHZ;
- break;
- case 26000000:
- /* PLL enabled, active mode */
- hppllctl |= TWL6040_MCLK_26000KHZ |
- TWL6040_HPLLENA;
- break;
- case 38400000:
- /* PLL enabled, active mode */
- hppllctl |= TWL6040_MCLK_38400KHZ |
- TWL6040_HPLLENA;
- break;
- default:
- dev_err(twl6040->dev,
- "freq_in %d not supported\n", freq_in);
- ret = -EINVAL;
- goto pll_out;
+ hppllctl |= TWL6040_HPLLSQRENA;
+
+ twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL,
+ hppllctl);
+ usleep_range(500, 700);
+ lppllctl |= TWL6040_HPLLSEL;
+ twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
+ lppllctl);
+ lppllctl &= ~TWL6040_LPLLENA;
+ twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
+ lppllctl);
}
-
- /* enable clock slicer to ensure input waveform is square */
- hppllctl |= TWL6040_HPLLSQRENA;
-
- twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL, hppllctl);
- usleep_range(500, 700);
- lppllctl |= TWL6040_HPLLSEL;
- twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
- lppllctl &= ~TWL6040_LPLLENA;
- twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
break;
default:
dev_err(twl6040->dev, "unknown pll id %d\n", pll_id);
@@ -421,6 +446,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
}
twl6040->sysclk = freq_out;
+ twl6040->mclk = freq_in;
twl6040->pll = pll_id;
pll_out:
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6a1a092db146..c7795096d43b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -2,24 +2,14 @@
# Misc strange devices
#
-# This one has to live outside of the MISC_DEVICES conditional,
-# because it may be selected by drivers/platform/x86/hp_accel.
+menu "Misc devices"
+
config SENSORS_LIS3LV02D
tristate
depends on INPUT
select INPUT_POLLDEV
default n
-menuconfig MISC_DEVICES
- bool "Misc devices"
- ---help---
- Say Y here to get to see options for device drivers from various
- different categories. This option alone does not add any kernel code.
-
- If you say N, all options in this submenu will be skipped and disabled.
-
-if MISC_DEVICES
-
config AD525X_DPOT
tristate "Analog Devices Digital Potentiometers"
depends on (I2C || SPI) && SYSFS
@@ -516,5 +506,4 @@ source "drivers/misc/ti-st/Kconfig"
source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
source "drivers/misc/altera-stapl/Kconfig"
-
-endif # MISC_DEVICES
+endmenu
diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c
index 778fc3fdfb9b..5484301d57d9 100644
--- a/drivers/misc/c2port/c2port-duramar2150.c
+++ b/drivers/misc/c2port/c2port-duramar2150.c
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#define DATA_PORT 0x325
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
index 68cd05b6d829..85cc7710193c 100644
--- a/drivers/misc/cb710/core.c
+++ b/drivers/misc/cb710/core.c
@@ -245,6 +245,7 @@ static int __devinit cb710_probe(struct pci_dev *pdev,
if (err)
return err;
+ spin_lock_init(&chip->irq_lock);
chip->pdev = pdev;
chip->iobase = pcim_iomap_table(pdev)[0];
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c
index bc685bfc4c33..87a390de054c 100644
--- a/drivers/misc/cs5535-mfgpt.c
+++ b/drivers/misc/cs5535-mfgpt.c
@@ -262,7 +262,7 @@ static void __init reset_all_timers(void)
* In other cases (such as with VSAless OpenFirmware), the system firmware
* leaves timers available for us to use.
*/
-static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt)
+static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt)
{
struct cs5535_mfgpt_timer timer = { .chip = mfgpt };
unsigned long flags;
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index 150cd7061b80..28adefe70f96 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -354,6 +354,7 @@ static void lkdtm_do_action(enum ctype which)
static void lkdtm_handler(void)
{
unsigned long flags;
+ bool do_it = false;
spin_lock_irqsave(&count_lock, flags);
count--;
@@ -361,10 +362,13 @@ static void lkdtm_handler(void)
cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
if (count == 0) {
- lkdtm_do_action(cptype);
+ do_it = true;
count = cpoint_count;
}
spin_unlock_irqrestore(&count_lock, flags);
+
+ if (do_it)
+ lkdtm_do_action(cptype);
}
static int lkdtm_register_cpoint(enum cname which)
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index cd41d403c9df..cb56e270da11 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -314,7 +314,7 @@ static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target)
* fear that guest will need it. Host may reject some pages, we need to
* check the return value and maybe submit a different page.
*/
-static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
+static int vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
unsigned int *hv_status)
{
unsigned long status, dummy;
@@ -322,17 +322,17 @@ static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
pfn32 = (u32)pfn;
if (pfn32 != pfn)
- return false;
+ return -1;
STATS_INC(b->stats.lock);
*hv_status = status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
if (vmballoon_check_status(b, status))
- return true;
+ return 0;
pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
STATS_INC(b->stats.lock_fail);
- return false;
+ return 1;
}
/*
@@ -411,7 +411,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
struct page *page;
gfp_t flags;
unsigned int hv_status;
- bool locked = false;
+ int locked;
flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
do {
@@ -431,7 +431,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
/* inform monitor */
locked = vmballoon_send_lock_page(b, page_to_pfn(page), &hv_status);
- if (!locked) {
+ if (locked > 0) {
STATS_INC(b->stats.refused_alloc);
if (hv_status == VMW_BALLOON_ERROR_RESET ||
@@ -449,7 +449,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED)
return -EIO;
}
- } while (!locked);
+ } while (locked != 0);
/* track allocated page */
list_add(&page->lru, &b->pages);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index cf444b0ca2cc..00fcbed1afd2 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -477,7 +477,6 @@ config MMC_SDHI
config MMC_CB710
tristate "ENE CB710 MMC/SD Interface support"
depends on PCI
- select MISC_DEVICES
select CB710_CORE
help
This option enables support for MMC/SD part of ENE CB710/720 Flash
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 6ae9ca01388b..9a9ce71a71fc 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -119,7 +119,7 @@ static int mtd_cls_suspend(struct device *dev, pm_message_t state)
{
struct mtd_info *mtd = dev_get_drvdata(dev);
- return mtd_suspend(mtd);
+ return mtd ? mtd_suspend(mtd) : 0;
}
static int mtd_cls_resume(struct device *dev)
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 4dd056e2e16a..35b4fb55dbd6 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -161,6 +161,37 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
!!host->board->rdy_pin_active_low;
}
+/*
+ * Minimal-overhead PIO for data access.
+ */
+static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+
+ __raw_readsb(nand_chip->IO_ADDR_R, buf, len);
+}
+
+static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+
+ __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2);
+}
+
+static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+
+ __raw_writesb(nand_chip->IO_ADDR_W, buf, len);
+}
+
+static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+
+ __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2);
+}
+
static void dma_complete_func(void *completion)
{
complete(completion);
@@ -235,27 +266,33 @@ err_buf:
static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
{
struct nand_chip *chip = mtd->priv;
+ struct atmel_nand_host *host = chip->priv;
if (use_dma && len > mtd->oobsize)
/* only use DMA for bigger than oob size: better performances */
if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
return;
- /* if no DMA operation possible, use PIO */
- memcpy_fromio(buf, chip->IO_ADDR_R, len);
+ if (host->board->bus_width_16)
+ atmel_read_buf16(mtd, buf, len);
+ else
+ atmel_read_buf8(mtd, buf, len);
}
static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
{
struct nand_chip *chip = mtd->priv;
+ struct atmel_nand_host *host = chip->priv;
if (use_dma && len > mtd->oobsize)
/* only use DMA for bigger than oob size: better performances */
if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
return;
- /* if no DMA operation possible, use PIO */
- memcpy_toio(chip->IO_ADDR_W, buf, len);
+ if (host->board->bus_width_16)
+ atmel_write_buf16(mtd, buf, len);
+ else
+ atmel_write_buf8(mtd, buf, len);
}
/*
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 7f680420bfab..7db6555ed3ba 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -69,17 +69,19 @@ static int clear_poll_bit(void __iomem *addr, u32 mask)
* [1] enable the module.
* [2] reset the module.
*
- * In most of the cases, it's ok. But there is a hardware bug in the BCH block.
+ * In most of the cases, it's ok.
+ * But in MX23, there is a hardware bug in the BCH block (see erratum #2847).
* If you try to soft reset the BCH block, it becomes unusable until
* the next hard reset. This case occurs in the NAND boot mode. When the board
* boots by NAND, the ROM of the chip will initialize the BCH blocks itself.
* So If the driver tries to reset the BCH again, the BCH will not work anymore.
- * You will see a DMA timeout in this case.
+ * You will see a DMA timeout in this case. The bug has been fixed
+ * in the following chips, such as MX28.
*
* To avoid this bug, just add a new parameter `just_enable` for
* the mxs_reset_block(), and rewrite it here.
*/
-int gpmi_reset_block(void __iomem *reset_addr, bool just_enable)
+static int gpmi_reset_block(void __iomem *reset_addr, bool just_enable)
{
int ret;
int timeout = 0x400;
@@ -206,7 +208,15 @@ int bch_set_geometry(struct gpmi_nand_data *this)
if (ret)
goto err_out;
- ret = gpmi_reset_block(r->bch_regs, true);
+ /*
+ * Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this
+ * chip, otherwise it will lock up. So we skip resetting BCH on the MX23.
+ * On the other hand, the MX28 needs the reset, because one case has been
+ * seen where the BCH produced ECC errors constantly after 10000
+ * consecutive reboots. The latter case has not been seen on the MX23 yet,
+ * still we don't know if it could happen there as well.
+ */
+ ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
if (ret)
goto err_out;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 35b4565050f1..8a393f9e6027 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2588,7 +2588,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
instr->state = MTD_ERASING;
while (len) {
- /* Heck if we have a bad block, we do not erase bad blocks! */
+ /* Check if we have a bad block, we do not erase bad blocks! */
if (nand_block_checkbad(mtd, ((loff_t) page) <<
chip->page_shift, 0, allowbbt)) {
pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 6e6a684359b5..518ec5c6872d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -523,7 +523,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
skb = build_skb(data);
if (likely(skb)) {
-
#ifdef BNX2X_STOP_ON_ERROR
if (pad + len > fp->rx_buf_size) {
BNX2X_ERR("skb_put is about to fail... "
@@ -557,7 +556,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
return;
}
-
+ kfree(new_data);
drop:
/* drop the packet and keep the buffer in the bin */
DP(NETIF_MSG_RX_STATUS,
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index a27c601af3d1..ab753d7334a6 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -946,7 +946,7 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL);
if (!flash_attr)
- return -ENOMEM;
+ return 0;
fcomp.bnad = bnad;
fcomp.comp_status = 0;
@@ -958,7 +958,7 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
if (ret != BFA_STATUS_OK) {
spin_unlock_irqrestore(&bnad->bna_lock, flags);
kfree(flash_attr);
- goto out_err;
+ return 0;
}
spin_unlock_irqrestore(&bnad->bna_lock, flags);
wait_for_completion(&fcomp.comp);
@@ -978,8 +978,6 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
}
kfree(flash_attr);
return flash_part;
-out_err:
- return -EINVAL;
}
static int
@@ -1006,7 +1004,7 @@ bnad_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
/* Query the flash partition based on the offset */
flash_part = bnad_get_flash_partition_by_offset(bnad,
eeprom->offset, &base_offset);
- if (flash_part <= 0)
+ if (flash_part == 0)
return -EFAULT;
fcomp.bnad = bnad;
@@ -1048,7 +1046,7 @@ bnad_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
/* Query the flash partition based on the offset */
flash_part = bnad_get_flash_partition_by_offset(bnad,
eeprom->offset, &base_offset);
- if (flash_part <= 0)
+ if (flash_part == 0)
return -EFAULT;
fcomp.bnad = bnad;
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 1f86a70b88af..e72dc8175955 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -4962,12 +4962,14 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
e1000_setup_rctl(adapter);
e1000_set_rx_mode(netdev);
+ rctl = er32(RCTL);
+
/* turn on all-multi mode if wake on multicast is enabled */
- if (wufc & E1000_WUFC_MC) {
- rctl = er32(RCTL);
+ if (wufc & E1000_WUFC_MC)
rctl |= E1000_RCTL_MPE;
- ew32(RCTL, rctl);
- }
+
+ /* enable receives in the hardware */
+ ew32(RCTL, rctl | E1000_RCTL_EN);
if (hw->mac_type >= e1000_82540) {
ctrl = er32(CTRL);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index fd911cac1ac5..fda824735e18 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -5014,7 +5014,8 @@ static int igb_find_enabled_vfs(struct igb_adapter *adapter)
vf_devfn = pdev->devfn + 0x80;
pvfdev = pci_get_device(hw->vendor_id, device_id, NULL);
while (pvfdev) {
- if (pvfdev->devfn == vf_devfn)
+ if (pvfdev->devfn == vf_devfn &&
+ (pvfdev->bus->number >= pdev->bus->number))
vfs_found++;
vf_devfn += vf_stride;
pvfdev = pci_get_device(hw->vendor_id,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index 005e5f25600d..79a92fe987b9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -112,6 +112,8 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
{
u8 err = 0;
+ u8 prio_tc[MAX_USER_PRIORITY] = {0};
+ int i;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
/* Fail command if not in CEE mode */
@@ -122,10 +124,15 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
if (!!state != !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
return err;
- if (state > 0)
+ if (state > 0) {
err = ixgbe_setup_tc(netdev, adapter->dcb_cfg.num_tcs.pg_tcs);
- else
+ ixgbe_dcb_unpack_map(&adapter->dcb_cfg, DCB_TX_CONFIG, prio_tc);
+ } else {
err = ixgbe_setup_tc(netdev, 0);
+ }
+
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
+ netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
return err;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 1f31a04d3c91..a62975480e37 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -120,19 +120,23 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
#endif /* IXGBE_FCOE */
};
-#define IXGBE_QUEUE_STATS_LEN \
- ((((struct ixgbe_adapter *)netdev_priv(netdev))->num_tx_queues + \
- ((struct ixgbe_adapter *)netdev_priv(netdev))->num_rx_queues) * \
+/* ixgbe allocates num_tx_queues and num_rx_queues symmetrically so
+ * we set the num_rx_queues to evaluate to num_tx_queues. This is
+ * used because we do not have a good way to get the max number of
+ * rx queues with CONFIG_RPS disabled.
+ */
+#define IXGBE_NUM_RX_QUEUES netdev->num_tx_queues
+
+#define IXGBE_QUEUE_STATS_LEN ( \
+ (netdev->num_tx_queues + IXGBE_NUM_RX_QUEUES) * \
(sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
#define IXGBE_PB_STATS_LEN ( \
- (((struct ixgbe_adapter *)netdev_priv(netdev))->flags & \
- IXGBE_FLAG_DCB_ENABLED) ? \
- (sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \
- sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \
- sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \
- sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \
- / sizeof(u64) : 0)
+ (sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \
+ sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \
+ sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \
+ sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \
+ / sizeof(u64))
#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + \
IXGBE_PB_STATS_LEN + \
IXGBE_QUEUE_STATS_LEN)
@@ -1078,8 +1082,15 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
- for (j = 0; j < adapter->num_tx_queues; j++) {
+ for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
ring = adapter->tx_ring[j];
+ if (!ring) {
+ data[i] = 0;
+ data[i+1] = 0;
+ i += 2;
+ continue;
+ }
+
do {
start = u64_stats_fetch_begin_bh(&ring->syncp);
data[i] = ring->stats.packets;
@@ -1087,8 +1098,15 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
i += 2;
}
- for (j = 0; j < adapter->num_rx_queues; j++) {
+ for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
ring = adapter->rx_ring[j];
+ if (!ring) {
+ data[i] = 0;
+ data[i+1] = 0;
+ i += 2;
+ continue;
+ }
+
do {
start = u64_stats_fetch_begin_bh(&ring->syncp);
data[i] = ring->stats.packets;
@@ -1096,22 +1114,20 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
i += 2;
}
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) {
- data[i++] = adapter->stats.pxontxc[j];
- data[i++] = adapter->stats.pxofftxc[j];
- }
- for (j = 0; j < MAX_RX_PACKET_BUFFERS; j++) {
- data[i++] = adapter->stats.pxonrxc[j];
- data[i++] = adapter->stats.pxoffrxc[j];
- }
+
+ for (j = 0; j < IXGBE_MAX_PACKET_BUFFERS; j++) {
+ data[i++] = adapter->stats.pxontxc[j];
+ data[i++] = adapter->stats.pxofftxc[j];
+ }
+ for (j = 0; j < IXGBE_MAX_PACKET_BUFFERS; j++) {
+ data[i++] = adapter->stats.pxonrxc[j];
+ data[i++] = adapter->stats.pxoffrxc[j];
}
}
static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
char *p = (char *)data;
int i;
@@ -1126,31 +1142,29 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
- for (i = 0; i < adapter->num_tx_queues; i++) {
+ for (i = 0; i < netdev->num_tx_queues; i++) {
sprintf(p, "tx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "tx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
}
- for (i = 0; i < adapter->num_rx_queues; i++) {
+ for (i = 0; i < IXGBE_NUM_RX_QUEUES; i++) {
sprintf(p, "rx_queue_%u_packets", i);
p += ETH_GSTRING_LEN;
sprintf(p, "rx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
}
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
- sprintf(p, "tx_pb_%u_pxon", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "tx_pb_%u_pxoff", i);
- p += ETH_GSTRING_LEN;
- }
- for (i = 0; i < MAX_RX_PACKET_BUFFERS; i++) {
- sprintf(p, "rx_pb_%u_pxon", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rx_pb_%u_pxoff", i);
- p += ETH_GSTRING_LEN;
- }
+ for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+ sprintf(p, "tx_pb_%u_pxon", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "tx_pb_%u_pxoff", i);
+ p += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+ sprintf(p, "rx_pb_%u_pxon", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "rx_pb_%u_pxoff", i);
+ p += ETH_GSTRING_LEN;
}
/* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
break;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ecc46ce8b2c3..6441acc34c23 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -2638,22 +2638,22 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
/*
* we must limit the number of descriptors so that the
* total size of max desc * buf_len is not greater
- * than 65535
+ * than 65536
*/
if (ring_is_ps_enabled(ring)) {
-#if (MAX_SKB_FRAGS > 16)
+#if (PAGE_SIZE < 8192)
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
-#elif (MAX_SKB_FRAGS > 8)
+#elif (PAGE_SIZE < 16384)
rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
-#elif (MAX_SKB_FRAGS > 4)
+#elif (PAGE_SIZE < 32768)
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
#else
rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
#endif
} else {
- if (rx_buf_len < IXGBE_RXBUFFER_4K)
+ if (rx_buf_len <= IXGBE_RXBUFFER_4K)
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
- else if (rx_buf_len < IXGBE_RXBUFFER_8K)
+ else if (rx_buf_len <= IXGBE_RXBUFFER_8K)
rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
else
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
@@ -2835,7 +2835,7 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
vf_shift = adapter->num_vfs % 32;
- reg_offset = (adapter->num_vfs > 32) ? 1 : 0;
+ reg_offset = (adapter->num_vfs >= 32) ? 1 : 0;
/* Enable only the PF's pool for Tx/Rx */
IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
@@ -4335,6 +4335,10 @@ static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
adapter->num_tx_queues = 1;
done:
+ if ((adapter->netdev->reg_state == NETREG_UNREGISTERED) ||
+ (adapter->netdev->reg_state == NETREG_UNREGISTERING))
+ return 0;
+
/* Notify the stack of the (possibly) reduced queue counts. */
netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
return netif_set_real_num_rx_queues(adapter->netdev,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 8d8cdbc22df0..b01ecb4d2bb1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -67,7 +67,8 @@ static int ixgbe_find_enabled_vfs(struct ixgbe_adapter *adapter)
vf_devfn = pdev->devfn + 0x80;
pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID, device_id, NULL);
while (pvfdev) {
- if (pvfdev->devfn == vf_devfn)
+ if (pvfdev->devfn == vf_devfn &&
+ (pvfdev->bus->number >= pdev->bus->number))
vfs_found++;
vf_devfn += 2;
pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID,
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 1d61eaac8587..5a30bf823099 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -931,20 +931,17 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base)
}
/* Allocate and setup a new buffer for receiving */
-static int skge_rx_setup(struct pci_dev *pdev,
- struct skge_element *e,
- struct sk_buff *skb, unsigned int bufsize)
+static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+ struct sk_buff *skb, unsigned int bufsize)
{
struct skge_rx_desc *rd = e->desc;
- dma_addr_t map;
+ u64 map;
- map = pci_map_single(pdev, skb->data, bufsize,
+ map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, map))
- goto mapping_error;
- rd->dma_lo = lower_32_bits(map);
- rd->dma_hi = upper_32_bits(map);
+ rd->dma_lo = map;
+ rd->dma_hi = map >> 32;
e->skb = skb;
rd->csum1_start = ETH_HLEN;
rd->csum2_start = ETH_HLEN;
@@ -956,13 +953,6 @@ static int skge_rx_setup(struct pci_dev *pdev,
rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
dma_unmap_addr_set(e, mapaddr, map);
dma_unmap_len_set(e, maplen, bufsize);
- return 0;
-
-mapping_error:
- if (net_ratelimit())
- dev_warn(&pdev->dev, "%s: rx mapping error\n",
- skb->dev->name);
- return -EIO;
}
/* Resume receiving using existing skb,
@@ -1024,11 +1014,7 @@ static int skge_rx_fill(struct net_device *dev)
return -ENOMEM;
skb_reserve(skb, NET_IP_ALIGN);
- if (skge_rx_setup(skge->hw->pdev, e, skb, skge->rx_buf_size)) {
- kfree_skb(skb);
- return -ENOMEM;
- }
-
+ skge_rx_setup(skge, e, skb, skge->rx_buf_size);
} while ((e = e->next) != ring->start);
ring->to_clean = ring->start;
@@ -2743,7 +2729,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
struct skge_tx_desc *td;
int i;
u32 control, len;
- dma_addr_t map;
+ u64 map;
if (skb_padto(skb, ETH_ZLEN))
return NETDEV_TX_OK;
@@ -2757,14 +2743,11 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
e->skb = skb;
len = skb_headlen(skb);
map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(hw->pdev, map))
- goto mapping_error;
-
dma_unmap_addr_set(e, mapaddr, map);
dma_unmap_len_set(e, maplen, len);
- td->dma_lo = lower_32_bits(map);
- td->dma_hi = upper_32_bits(map);
+ td->dma_lo = map;
+ td->dma_hi = map >> 32;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
const int offset = skb_checksum_start_offset(skb);
@@ -2795,16 +2778,14 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
skb_frag_size(frag), DMA_TO_DEVICE);
- if (dma_mapping_error(&hw->pdev->dev, map))
- goto mapping_unwind;
e = e->next;
e->skb = skb;
tf = e->desc;
BUG_ON(tf->control & BMU_OWN);
- tf->dma_lo = lower_32_bits(map);
- tf->dma_hi = upper_32_bits(map);
+ tf->dma_lo = map;
+ tf->dma_hi = (u64) map >> 32;
dma_unmap_addr_set(e, mapaddr, map);
dma_unmap_len_set(e, maplen, skb_frag_size(frag));
@@ -2834,28 +2815,6 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
}
return NETDEV_TX_OK;
-
-mapping_unwind:
- /* unroll any pages that were already mapped. */
- if (e != skge->tx_ring.to_use) {
- struct skge_element *u;
-
- for (u = skge->tx_ring.to_use->next; u != e; u = u->next)
- pci_unmap_page(hw->pdev, dma_unmap_addr(u, mapaddr),
- dma_unmap_len(u, maplen),
- PCI_DMA_TODEVICE);
- e = skge->tx_ring.to_use;
- }
- /* undo the mapping for the skb header */
- pci_unmap_single(hw->pdev, dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
- PCI_DMA_TODEVICE);
-mapping_error:
- /* mapping error causes error message and packet to be discarded. */
- if (net_ratelimit())
- dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
}
@@ -3099,17 +3058,13 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
if (!nskb)
goto resubmit;
- if (unlikely(skge_rx_setup(skge->hw->pdev, e, nskb, skge->rx_buf_size))) {
- dev_kfree_skb(nskb);
- goto resubmit;
- }
-
pci_unmap_single(skge->hw->pdev,
dma_unmap_addr(e, mapaddr),
dma_unmap_len(e, maplen),
PCI_DMA_FROMDEVICE);
skb = e->skb;
prefetch(skb->data);
+ skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
}
skb_put(skb, len);
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 1831ddeebc42..48d5c48d7ce8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1616,12 +1616,12 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]);
}
kfree(priv->mfunc.master.slave_state);
- iounmap(priv->mfunc.comm);
- dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
- priv->mfunc.vhcr,
- priv->mfunc.vhcr_dma);
- priv->mfunc.vhcr = NULL;
}
+
+ iounmap(priv->mfunc.comm);
+ dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
+ priv->mfunc.vhcr, priv->mfunc.vhcr_dma);
+ priv->mfunc.vhcr = NULL;
}
void mlx4_cmd_cleanup(struct mlx4_dev *dev)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 25e6480479df..9fe4f94c6da7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -892,7 +892,8 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv)
for (i = 0; i < priv->rx_ring_num; i++) {
if (priv->rx_ring[i].rx_info)
- mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i]);
+ mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i],
+ priv->prof->rx_ring_size, priv->stride);
if (priv->rx_cq[i].buf)
mlx4_en_destroy_cq(priv, &priv->rx_cq[i]);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index fb6e899f38d3..d703ef2c9c91 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -168,8 +168,12 @@ static int mlx4_en_prepare_rx_desc(struct mlx4_en_priv *priv,
return 0;
err:
- while (i--)
+ while (i--) {
+ dma_addr_t dma = be64_to_cpu(rx_desc->data[i].addr);
+ pci_unmap_single(priv->mdev->pdev, dma, skb_frags[i].size,
+ PCI_DMA_FROMDEVICE);
put_page(skb_frags[i].page);
+ }
return -ENOMEM;
}
@@ -379,12 +383,12 @@ err_allocator:
}
void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
- struct mlx4_en_rx_ring *ring)
+ struct mlx4_en_rx_ring *ring, u32 size, u16 stride)
{
struct mlx4_en_dev *mdev = priv->mdev;
mlx4_en_unmap_buffer(&ring->wqres.buf);
- mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE);
+ mlx4_free_hwq_res(mdev->dev, &ring->wqres, size * stride + TXBB_SIZE);
vfree(ring->rx_info);
ring->rx_info = NULL;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 0785d9b2a265..ca574d850b39 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -136,7 +136,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port,
u32 prot;
int err;
- s_steer = &mlx4_priv(dev)->steer[0];
+ s_steer = &mlx4_priv(dev)->steer[port - 1];
new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
if (!new_entry)
return -ENOMEM;
@@ -220,7 +220,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
struct mlx4_promisc_qp *pqp;
struct mlx4_promisc_qp *dqp;
- s_steer = &mlx4_priv(dev)->steer[0];
+ s_steer = &mlx4_priv(dev)->steer[port - 1];
pqp = get_promisc_qp(dev, 0, steer, qpn);
if (!pqp)
@@ -265,7 +265,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
struct mlx4_steer_index *tmp_entry, *entry = NULL;
struct mlx4_promisc_qp *dqp, *tmp_dqp;
- s_steer = &mlx4_priv(dev)->steer[0];
+ s_steer = &mlx4_priv(dev)->steer[port - 1];
/* if qp is not promisc, it cannot be duplicated */
if (!get_promisc_qp(dev, 0, steer, qpn))
@@ -306,7 +306,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
bool ret = false;
int i;
- s_steer = &mlx4_priv(dev)->steer[0];
+ s_steer = &mlx4_priv(dev)->steer[port - 1];
mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
@@ -361,7 +361,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
int err;
struct mlx4_priv *priv = mlx4_priv(dev);
- s_steer = &mlx4_priv(dev)->steer[0];
+ s_steer = &mlx4_priv(dev)->steer[port - 1];
mutex_lock(&priv->mcg_table.mutex);
@@ -466,7 +466,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
int loc, i;
int err;
- s_steer = &mlx4_priv(dev)->steer[0];
+ s_steer = &mlx4_priv(dev)->steer[port - 1];
mutex_lock(&priv->mcg_table.mutex);
pqp = get_promisc_qp(dev, 0, steer, qpn);
@@ -1004,7 +1004,7 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove);
int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
{
- if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
+ if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
return 0;
if (mlx4_is_mfunc(dev))
@@ -1016,7 +1016,7 @@ EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add);
int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
{
- if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
+ if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
return 0;
if (mlx4_is_mfunc(dev))
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 35f08840813c..d60335f3c473 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -528,7 +528,8 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_rx_ring *ring,
u32 size, u16 stride);
void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
- struct mlx4_en_rx_ring *ring);
+ struct mlx4_en_rx_ring *ring,
+ u32 size, u16 stride);
int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv);
void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_rx_ring *ring);
diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig
index 1ea811cf515b..fe42fc00d8d3 100644
--- a/drivers/net/ethernet/micrel/Kconfig
+++ b/drivers/net/ethernet/micrel/Kconfig
@@ -42,7 +42,6 @@ config KS8851
select NET_CORE
select MII
select CRC32
- select MISC_DEVICES
select EEPROM_93CX6
---help---
SPI driver for Micrel KS8851 SPI attached network chip.
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 1a69504ed9c5..cfad09107054 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include "sh_eth.h"
@@ -816,7 +817,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
sh_eth_write(ndev, 0, TRIMD);
/* Recv frame limit set register */
- sh_eth_write(ndev, RFLR_VALUE, RFLR);
+ sh_eth_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN,
+ RFLR);
sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index ba72976926fd..cb07add8638f 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -575,9 +575,6 @@ enum RPADIR_BIT {
RPADIR_PADR = 0x0003f,
};
-/* RFLR */
-#define RFLR_VALUE 0x1000
-
/* FDR */
#define DEFAULT_FDR_INIT 0x00000707
diff --git a/drivers/net/ethernet/toshiba/Kconfig b/drivers/net/ethernet/toshiba/Kconfig
index 051764704559..74acb5cf6099 100644
--- a/drivers/net/ethernet/toshiba/Kconfig
+++ b/drivers/net/ethernet/toshiba/Kconfig
@@ -5,7 +5,7 @@
config NET_VENDOR_TOSHIBA
bool "Toshiba devices"
default y
- depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB) || PPC_PS3
+ depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB || MIPS) || PPC_PS3
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index cf69cbf6fec3..8a5d7c100a5e 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -2491,9 +2491,6 @@ static int velocity_close(struct net_device *dev)
if (dev->irq != 0)
free_irq(dev->irq, dev);
- /* Power down the chip */
- pci_set_power_state(vptr->pdev, PCI_D3hot);
-
velocity_free_rings(vptr);
vptr->flags &= (~VELOCITY_FLAGS_OPENED);
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
index c7e0149d1514..45550d42b368 100644
--- a/drivers/net/tokenring/Kconfig
+++ b/drivers/net/tokenring/Kconfig
@@ -7,7 +7,6 @@ menuconfig TR
bool "Token Ring driver support"
depends on NETDEVICES && !UML
depends on (PCI || ISA || MCA || CCW || PCMCIA)
- select LLC
help
Token Ring is IBM's way of communication on a local network; the
rest of the world uses Ethernet. To participate on a Token Ring
@@ -20,6 +19,10 @@ menuconfig TR
if TR
+config WANT_LLC
+ def_bool y
+ select LLC
+
config PCMCIA_IBMTR
tristate "IBM PCMCIA tokenring adapter support"
depends on IBMTR!=y && PCMCIA
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index ee7759575050..87db1ee1c298 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1037,13 +1037,16 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
/*
* Workaround for early ACK timeouts, add an offset to match the
- * initval's 64us ack timeout value.
+ * initval's 64us ack timeout value. Use 48us for the CTS timeout.
* This was initially only meant to work around an issue with delayed
* BA frames in some implementations, but it has been found to fix ACK
* timeout issues in other cases as well.
*/
- if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
+ if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) {
acktimeout += 64 - sifstime - ah->slottime;
+ ctstimeout += 48 - sifstime - ah->slottime;
+ }
+
ath9k_hw_set_sifs_time(ah, sifstime);
ath9k_hw_setslottime(ah, slottime);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index abf943557dee..53a005d288aa 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -822,6 +822,11 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
ARRAY_SIZE(ath9k_tpt_blink));
#endif
+ INIT_WORK(&sc->hw_reset_work, ath_reset_work);
+ INIT_WORK(&sc->hw_check_work, ath_hw_check);
+ INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+ INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
+
/* Register with mac80211 */
error = ieee80211_register_hw(hw);
if (error)
@@ -840,10 +845,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
goto error_world;
}
- INIT_WORK(&sc->hw_reset_work, ath_reset_work);
- INIT_WORK(&sc->hw_check_work, ath_hw_check);
- INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
- INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
ath_init_leds(sc);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 0e666fbe0842..7e1a91af1497 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -822,6 +822,14 @@ static bool ath9k_rx_accept(struct ath_common *common,
(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
ATH9K_RXERR_KEYMISS));
+ /*
+ * Key miss events are only relevant for pairwise keys where the
+ * descriptor does contain a valid key index. This has been observed
+ * mostly with CCMP encryption.
+ */
+ if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
+ rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
+
if (!rx_stats->rs_datalen)
return false;
/*
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index e13b6d99171a..84fcb741a296 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -382,7 +382,8 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
adapter->if_ops.cleanup_if(adapter);
- dev_kfree_skb_any(adapter->sleep_cfm);
+ if (adapter->sleep_cfm)
+ dev_kfree_skb_any(adapter->sleep_cfm);
}
/*
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 80e44566bf6e..790a3796483c 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -811,7 +811,9 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
continue;
rtnl_lock();
- mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
+ if (priv->wdev && priv->netdev)
+ mwifiex_del_virtual_intf(priv->wdev->wiphy,
+ priv->netdev);
rtnl_unlock();
}
@@ -819,9 +821,11 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
if (!priv)
goto exit_remove;
- wiphy_unregister(priv->wdev->wiphy);
- wiphy_free(priv->wdev->wiphy);
- kfree(priv->wdev);
+ if (priv->wdev) {
+ wiphy_unregister(priv->wdev->wiphy);
+ wiphy_free(priv->wdev->wiphy);
+ kfree(priv->wdev);
+ }
mwifiex_terminate_workqueue(adapter);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 470ca75ec250..b0fbf5d4fea0 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -54,7 +54,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
{
bool cancel_flag = false;
- int status = adapter->cmd_wait_q.status;
+ int status;
struct cmd_ctrl_node *cmd_queued;
if (!adapter->cmd_queued)
@@ -79,6 +79,8 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
mwifiex_cancel_pending_ioctl(adapter);
dev_dbg(adapter->dev, "cmd cancel\n");
}
+
+ status = adapter->cmd_wait_q.status;
adapter->cmd_wait_q.status = 0;
return status;
@@ -240,6 +242,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
if (!netif_queue_stopped(priv->netdev))
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
/* Clear any past association response stored for
* application retrieval */
@@ -271,6 +275,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
if (!netif_queue_stopped(priv->netdev))
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
if (!ret) {
dev_dbg(adapter->dev, "info: network found in scan"
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 0a70149df3fc..98a574a4a465 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -866,6 +866,14 @@ static int fill_ctrlset(struct zd_mac *mac,
ZD_ASSERT(frag_len <= 0xffff);
+ /*
+ * Firmware computes the duration itself (for all frames except PSPoll)
+ * and needs the field set to 0 at input, otherwise firmware messes up
+ * duration_id and sets bits 14 and 15 on.
+ */
+ if (!ieee80211_is_pspoll(hdr->frame_control))
+ hdr->duration_id = 0;
+
txrate = ieee80211_get_tx_rate(mac->hw, info);
cs->modulation = txrate->hw_value;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 749c2a16012c..1932029de48d 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -1269,10 +1269,8 @@ static int pcmcia_bus_add(struct pcmcia_socket *skt)
static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
{
- if (!verify_cis_cache(skt)) {
- pcmcia_put_socket(skt);
+ if (!verify_cis_cache(skt))
return 0;
- }
dev_dbg(&skt->dev, "cis mismatch - different card\n");
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 3f9a47ec67dc..8293658e7cf9 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -299,7 +299,7 @@ config SPI_S3C24XX_FIQ
config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI"
- depends on (ARCH_S3C64XX || ARCH_S5P64X0)
+ depends on (ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS)
select S3C64XX_DMA if ARCH_S3C64XX
help
SPI driver for Samsung S3C64XX and newer SoCs.
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index 2a6429d8c363..10182eb50068 100644
--- a/drivers/spi/spi-topcliff-pch.c
+++ b/drivers/spi/spi-topcliff-pch.c
@@ -1720,7 +1720,7 @@ static int pch_spi_resume(struct pci_dev *pdev)
#endif
-static struct pci_driver pch_spi_pcidev = {
+static struct pci_driver pch_spi_pcidev_driver = {
.name = "pch_spi",
.id_table = pch_spi_pcidev_id,
.probe = pch_spi_probe,
@@ -1736,7 +1736,7 @@ static int __init pch_spi_init(void)
if (ret)
return ret;
- ret = pci_register_driver(&pch_spi_pcidev);
+ ret = pci_register_driver(&pch_spi_pcidev_driver);
if (ret)
return ret;
@@ -1746,7 +1746,7 @@ module_init(pch_spi_init);
static void __exit pch_spi_exit(void)
{
- pci_unregister_driver(&pch_spi_pcidev);
+ pci_unregister_driver(&pch_spi_pcidev_driver);
platform_driver_unregister(&pch_spi_pd_driver);
}
module_exit(pch_spi_exit);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 21e2f4b87f14..9e6347249783 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -60,8 +60,6 @@ source "drivers/staging/rts5139/Kconfig"
source "drivers/staging/frontier/Kconfig"
-source "drivers/staging/pohmelfs/Kconfig"
-
source "drivers/staging/phison/Kconfig"
source "drivers/staging/line6/Kconfig"
@@ -120,8 +118,6 @@ source "drivers/staging/cptm1217/Kconfig"
source "drivers/staging/ste_rmi4/Kconfig"
-source "drivers/staging/gma500/Kconfig"
-
source "drivers/staging/mei/Kconfig"
source "drivers/staging/nvec/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 7c5808d7212d..943e14830753 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_RTS_PSTOR) += rts_pstor/
obj-$(CONFIG_RTS5139) += rts5139/
obj-$(CONFIG_TRANZPORT) += frontier/
-obj-$(CONFIG_POHMELFS) += pohmelfs/
obj-$(CONFIG_IDE_PHISON) += phison/
obj-$(CONFIG_LINE6_USB) += line6/
obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
@@ -52,7 +51,6 @@ obj-$(CONFIG_FT1000) += ft1000/
obj-$(CONFIG_SPEAKUP) += speakup/
obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
-obj-$(CONFIG_DRM_PSB) += gma500/
obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_MFD_NVEC) += nvec/
obj-$(CONFIG_DRM_OMAP) += omapdrm/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index becf711117ef..fef3580ce8de 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -27,6 +27,7 @@ config ANDROID_LOGGER
config ANDROID_RAM_CONSOLE
bool "Android RAM buffer console"
+ depends on !S390 && !UML
default n
config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
@@ -99,10 +100,6 @@ config ANDROID_LOW_MEMORY_KILLER
---help---
Register processes to be killed when memory is low
-config ANDROID_PMEM
- bool "Android pmem allocator"
- depends on ARM
-
source "drivers/staging/android/switch/Kconfig"
endif # if ANDROID
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index eaed1ff64f0f..5fcc24ffdd58 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -5,5 +5,4 @@ obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o
obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o
obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o
obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
-obj-$(CONFIG_ANDROID_PMEM) += pmem.o
obj-$(CONFIG_ANDROID_SWITCH) += switch/
diff --git a/drivers/staging/android/android_pmem.h b/drivers/staging/android/android_pmem.h
deleted file mode 100644
index f633621f5be3..000000000000
--- a/drivers/staging/android/android_pmem.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* include/linux/android_pmem.h
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _ANDROID_PMEM_H_
-#define _ANDROID_PMEM_H_
-
-#define PMEM_IOCTL_MAGIC 'p'
-#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
-#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
-#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
-#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
-/* This ioctl will allocate pmem space, backing the file, it will fail
- * if the file already has an allocation, pass it the len as the argument
- * to the ioctl */
-#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
-/* This will connect a one pmem file to another, pass the file that is already
- * backed in memory as the argument to the ioctl
- */
-#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
-/* Returns the total size of the pmem region it is sent to as a pmem_region
- * struct (with offset set to 0).
- */
-#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
-#define PMEM_CACHE_FLUSH _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
-
-struct android_pmem_platform_data
-{
- const char* name;
- /* starting physical address of memory region */
- unsigned long start;
- /* size of memory region */
- unsigned long size;
- /* set to indicate the region should not be managed with an allocator */
- unsigned no_allocator;
- /* set to indicate maps of this region should be cached, if a mix of
- * cached and uncached is desired, set this and open the device with
- * O_SYNC to get an uncached region */
- unsigned cached;
- /* The MSM7k has bits to enable a write buffer in the bus controller*/
- unsigned buffered;
-};
-
-struct pmem_region {
- unsigned long offset;
- unsigned long len;
-};
-
-#ifdef CONFIG_ANDROID_PMEM
-int is_pmem_file(struct file *file);
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
- unsigned long *end, struct file **filp);
-int get_pmem_user_addr(struct file *file, unsigned long *start,
- unsigned long *end);
-void put_pmem_file(struct file* file);
-void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
-int pmem_setup(struct android_pmem_platform_data *pdata,
- long (*ioctl)(struct file *, unsigned int, unsigned long),
- int (*release)(struct inode *, struct file *));
-int pmem_remap(struct pmem_region *region, struct file *file,
- unsigned operation);
-
-#else
-static inline int is_pmem_file(struct file *file) { return 0; }
-static inline int get_pmem_file(int fd, unsigned long *start,
- unsigned long *vstart, unsigned long *end,
- struct file **filp) { return -ENOSYS; }
-static inline int get_pmem_user_addr(struct file *file, unsigned long *start,
- unsigned long *end) { return -ENOSYS; }
-static inline void put_pmem_file(struct file* file) { return; }
-static inline void flush_pmem_file(struct file *file, unsigned long start,
- unsigned long len) { return; }
-static inline int pmem_setup(struct android_pmem_platform_data *pdata,
- long (*ioctl)(struct file *, unsigned int, unsigned long),
- int (*release)(struct inode *, struct file *)) { return -ENOSYS; }
-
-static inline int pmem_remap(struct pmem_region *region, struct file *file,
- unsigned operation) { return -ENOSYS; }
-#endif
-
-#endif //_ANDROID_PPP_H_
-
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 7491801a661c..f0b7e6605ab5 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -38,6 +38,7 @@
static DEFINE_MUTEX(binder_lock);
static DEFINE_MUTEX(binder_deferred_lock);
+static DEFINE_MUTEX(binder_mmap_lock);
static HLIST_HEAD(binder_procs);
static HLIST_HEAD(binder_deferred_list);
@@ -632,6 +633,11 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
if (mm) {
down_write(&mm->mmap_sem);
vma = proc->vma;
+ if (vma && mm != vma->vm_mm) {
+ pr_err("binder: %d: vma mm and task mm mismatch\n",
+ proc->pid);
+ vma = NULL;
+ }
}
if (allocate == 0)
@@ -2759,7 +2765,6 @@ static void binder_vma_open(struct vm_area_struct *vma)
proc->pid, vma->vm_start, vma->vm_end,
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
(unsigned long)pgprot_val(vma->vm_page_prot));
- dump_stack();
}
static void binder_vma_close(struct vm_area_struct *vma)
@@ -2803,6 +2808,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
}
vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
+ mutex_lock(&binder_mmap_lock);
if (proc->buffer) {
ret = -EBUSY;
failure_string = "already mapped";
@@ -2817,6 +2823,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
}
proc->buffer = area->addr;
proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
+ mutex_unlock(&binder_mmap_lock);
#ifdef CONFIG_CPU_CACHE_VIPT
if (cache_is_vipt_aliasing()) {
@@ -2849,7 +2856,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
binder_insert_free_buffer(proc, buffer);
proc->free_async_space = proc->buffer_size / 2;
barrier();
- proc->files = get_files_struct(current);
+ proc->files = get_files_struct(proc->tsk);
proc->vma = vma;
/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
@@ -2860,10 +2867,12 @@ err_alloc_small_buf_failed:
kfree(proc->pages);
proc->pages = NULL;
err_alloc_pages_failed:
+ mutex_lock(&binder_mmap_lock);
vfree(proc->buffer);
proc->buffer = NULL;
err_get_vm_area_failed:
err_already_mapped:
+ mutex_unlock(&binder_mmap_lock);
err_bad_arg:
printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 2d8d2b796101..efc7dc1f4831 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -54,6 +54,7 @@ static size_t lowmem_minfree[6] = {
static int lowmem_minfree_size = 4;
static struct task_struct *lowmem_deathpending;
+static unsigned long lowmem_deathpending_timeout;
#define lowmem_print(level, x...) \
do { \
@@ -103,7 +104,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
* Note: Currently you need CONFIG_PROFILING
* for this to work correctly.
*/
- if (lowmem_deathpending)
+ if (lowmem_deathpending &&
+ time_before_eq(jiffies, lowmem_deathpending_timeout))
return 0;
if (lowmem_adj_size < array_size)
@@ -178,6 +180,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
*/
#ifdef CONFIG_PROFILING
lowmem_deathpending = selected;
+ lowmem_deathpending_timeout = jiffies + HZ;
task_handoff_register(&task_nb);
#endif
force_sig(SIGKILL, selected);
diff --git a/drivers/staging/android/pmem.c b/drivers/staging/android/pmem.c
deleted file mode 100644
index 7d97032c6508..000000000000
--- a/drivers/staging/android/pmem.c
+++ /dev/null
@@ -1,1345 +0,0 @@
-/* pmem.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "android_pmem.h"
-
-#define PMEM_MAX_DEVICES 10
-#define PMEM_MAX_ORDER 128
-#define PMEM_MIN_ALLOC PAGE_SIZE
-
-#define PMEM_DEBUG 1
-
-/* indicates that a refernce to this file has been taken via get_pmem_file,
- * the file should not be released until put_pmem_file is called */
-#define PMEM_FLAGS_BUSY 0x1
-/* indicates that this is a suballocation of a larger master range */
-#define PMEM_FLAGS_CONNECTED 0x1 << 1
-/* indicates this is a master and not a sub allocation and that it is mmaped */
-#define PMEM_FLAGS_MASTERMAP 0x1 << 2
-/* submap and unsubmap flags indicate:
- * 00: subregion has never been mmaped
- * 10: subregion has been mmaped, reference to the mm was taken
- * 11: subretion has ben released, refernece to the mm still held
- * 01: subretion has been released, reference to the mm has been released
- */
-#define PMEM_FLAGS_SUBMAP 0x1 << 3
-#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
-
-
-struct pmem_data {
- /* in alloc mode: an index into the bitmap
- * in no_alloc mode: the size of the allocation */
- int index;
- /* see flags above for descriptions */
- unsigned int flags;
- /* protects this data field, if the mm_mmap sem will be held at the
- * same time as this sem, the mm sem must be taken first (as this is
- * the order for vma_open and vma_close ops */
- struct rw_semaphore sem;
- /* info about the mmaping process */
- struct vm_area_struct *vma;
- /* task struct of the mapping process */
- struct task_struct *task;
- /* process id of teh mapping process */
- pid_t pid;
- /* file descriptor of the master */
- int master_fd;
- /* file struct of the master */
- struct file *master_file;
- /* a list of currently available regions if this is a suballocation */
- struct list_head region_list;
- /* a linked list of data so we can access them for debugging */
- struct list_head list;
-#if PMEM_DEBUG
- int ref;
-#endif
-};
-
-struct pmem_bits {
- unsigned allocated:1; /* 1 if allocated, 0 if free */
- unsigned order:7; /* size of the region in pmem space */
-};
-
-struct pmem_region_node {
- struct pmem_region region;
- struct list_head list;
-};
-
-#define PMEM_DEBUG_MSGS 0
-#if PMEM_DEBUG_MSGS
-#define DLOG(fmt,args...) \
- do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
- ##args); } \
- while (0)
-#else
-#define DLOG(x...) do {} while (0)
-#endif
-
-struct pmem_info {
- struct miscdevice dev;
- /* physical start address of the remaped pmem space */
- unsigned long base;
- /* vitual start address of the remaped pmem space */
- unsigned char __iomem *vbase;
- /* total size of the pmem space */
- unsigned long size;
- /* number of entries in the pmem space */
- unsigned long num_entries;
- /* pfn of the garbage page in memory */
- unsigned long garbage_pfn;
- /* index of the garbage page in the pmem space */
- int garbage_index;
- /* the bitmap for the region indicating which entries are allocated
- * and which are free */
- struct pmem_bits *bitmap;
- /* indicates the region should not be managed with an allocator */
- unsigned no_allocator;
- /* indicates maps of this region should be cached, if a mix of
- * cached and uncached is desired, set this and open the device with
- * O_SYNC to get an uncached region */
- unsigned cached;
- unsigned buffered;
- /* in no_allocator mode the first mapper gets the whole space and sets
- * this flag */
- unsigned allocated;
- /* for debugging, creates a list of pmem file structs, the
- * data_list_lock should be taken before pmem_data->sem if both are
- * needed */
- struct mutex data_list_lock;
- struct list_head data_list;
- /* pmem_sem protects the bitmap array
- * a write lock should be held when modifying entries in bitmap
- * a read lock should be held when reading data from bits or
- * dereferencing a pointer into bitmap
- *
- * pmem_data->sem protects the pmem data of a particular file
- * Many of the function that require the pmem_data->sem have a non-
- * locking version for when the caller is already holding that sem.
- *
- * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
- * down(pmem_data->sem) => down(bitmap_sem)
- */
- struct rw_semaphore bitmap_sem;
-
- long (*ioctl)(struct file *, unsigned int, unsigned long);
- int (*release)(struct inode *, struct file *);
-};
-
-static struct pmem_info pmem[PMEM_MAX_DEVICES];
-static int id_count;
-
-#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
-#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
-#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
-#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
-#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
-#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
-#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
-#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
- PMEM_LEN(id, index))
-#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
-#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
- PMEM_LEN(id, index))
-#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
-#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
-#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
- (!(data->flags & PMEM_FLAGS_UNSUBMAP)))
-
-static int pmem_release(struct inode *, struct file *);
-static int pmem_mmap(struct file *, struct vm_area_struct *);
-static int pmem_open(struct inode *, struct file *);
-static long pmem_ioctl(struct file *, unsigned int, unsigned long);
-
-struct file_operations pmem_fops = {
- .release = pmem_release,
- .mmap = pmem_mmap,
- .open = pmem_open,
- .unlocked_ioctl = pmem_ioctl,
-};
-
-static int get_id(struct file *file)
-{
- return MINOR(file->f_dentry->d_inode->i_rdev);
-}
-
-int is_pmem_file(struct file *file)
-{
- int id;
-
- if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
- return 0;
- id = get_id(file);
- if (unlikely(id >= PMEM_MAX_DEVICES))
- return 0;
- if (unlikely(file->f_dentry->d_inode->i_rdev !=
- MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
- return 0;
- return 1;
-}
-
-static int has_allocation(struct file *file)
-{
- struct pmem_data *data;
- /* check is_pmem_file first if not accessed via pmem_file_ops */
-
- if (unlikely(!file->private_data))
- return 0;
- data = (struct pmem_data *)file->private_data;
- if (unlikely(data->index < 0))
- return 0;
- return 1;
-}
-
-static int is_master_owner(struct file *file)
-{
- struct file *master_file;
- struct pmem_data *data;
- int put_needed, ret = 0;
-
- if (!is_pmem_file(file) || !has_allocation(file))
- return 0;
- data = (struct pmem_data *)file->private_data;
- if (PMEM_FLAGS_MASTERMAP & data->flags)
- return 1;
- master_file = fget_light(data->master_fd, &put_needed);
- if (master_file && data->master_file == master_file)
- ret = 1;
- fput_light(master_file, put_needed);
- return ret;
-}
-
-static int pmem_free(int id, int index)
-{
- /* caller should hold the write lock on pmem_sem! */
- int buddy, curr = index;
- DLOG("index %d\n", index);
-
- if (pmem[id].no_allocator) {
- pmem[id].allocated = 0;
- return 0;
- }
- /* clean up the bitmap, merging any buddies */
- pmem[id].bitmap[curr].allocated = 0;
- /* find a slots buddy Buddy# = Slot# ^ (1 << order)
- * if the buddy is also free merge them
- * repeat until the buddy is not free or end of the bitmap is reached
- */
- do {
- buddy = PMEM_BUDDY_INDEX(id, curr);
- if (PMEM_IS_FREE(id, buddy) &&
- PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
- PMEM_ORDER(id, buddy)++;
- PMEM_ORDER(id, curr)++;
- curr = min(buddy, curr);
- } else {
- break;
- }
- } while (curr < pmem[id].num_entries);
-
- return 0;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data);
-
-static int pmem_release(struct inode *inode, struct file *file)
-{
- struct pmem_data *data = (struct pmem_data *)file->private_data;
- struct pmem_region_node *region_node;
- struct list_head *elt, *elt2;
- int id = get_id(file), ret = 0;
-
-
- mutex_lock(&pmem[id].data_list_lock);
- /* if this file is a master, revoke all the memory in the connected
- * files */
- if (PMEM_FLAGS_MASTERMAP & data->flags) {
- struct pmem_data *sub_data;
- list_for_each(elt, &pmem[id].data_list) {
- sub_data = list_entry(elt, struct pmem_data, list);
- down_read(&sub_data->sem);
- if (PMEM_IS_SUBMAP(sub_data) &&
- file == sub_data->master_file) {
- up_read(&sub_data->sem);
- pmem_revoke(file, sub_data);
- } else
- up_read(&sub_data->sem);
- }
- }
- list_del(&data->list);
- mutex_unlock(&pmem[id].data_list_lock);
-
-
- down_write(&data->sem);
-
- /* if its not a conencted file and it has an allocation, free it */
- if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
- down_write(&pmem[id].bitmap_sem);
- ret = pmem_free(id, data->index);
- up_write(&pmem[id].bitmap_sem);
- }
-
- /* if this file is a submap (mapped, connected file), downref the
- * task struct */
- if (PMEM_FLAGS_SUBMAP & data->flags)
- if (data->task) {
- put_task_struct(data->task);
- data->task = NULL;
- }
-
- file->private_data = NULL;
-
- list_for_each_safe(elt, elt2, &data->region_list) {
- region_node = list_entry(elt, struct pmem_region_node, list);
- list_del(elt);
- kfree(region_node);
- }
- BUG_ON(!list_empty(&data->region_list));
-
- up_write(&data->sem);
- kfree(data);
- if (pmem[id].release)
- ret = pmem[id].release(inode, file);
-
- return ret;
-}
-
-static int pmem_open(struct inode *inode, struct file *file)
-{
- struct pmem_data *data;
- int id = get_id(file);
- int ret = 0;
-
- DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
- /* setup file->private_data to indicate its unmapped */
- /* you can only open a pmem device one time */
- if (file->private_data != NULL)
- return -1;
- data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
- if (!data) {
- printk("pmem: unable to allocate memory for pmem metadata.");
- return -1;
- }
- data->flags = 0;
- data->index = -1;
- data->task = NULL;
- data->vma = NULL;
- data->pid = 0;
- data->master_file = NULL;
-#if PMEM_DEBUG
- data->ref = 0;
-#endif
- INIT_LIST_HEAD(&data->region_list);
- init_rwsem(&data->sem);
-
- file->private_data = data;
- INIT_LIST_HEAD(&data->list);
-
- mutex_lock(&pmem[id].data_list_lock);
- list_add(&data->list, &pmem[id].data_list);
- mutex_unlock(&pmem[id].data_list_lock);
- return ret;
-}
-
-static unsigned long pmem_order(unsigned long len)
-{
- int i;
-
- len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
- len--;
- for (i = 0; i < sizeof(len)*8; i++)
- if (len >> i == 0)
- break;
- return i;
-}
-
-static int pmem_allocate(int id, unsigned long len)
-{
- /* caller should hold the write lock on pmem_sem! */
- /* return the corresponding pdata[] entry */
- int curr = 0;
- int end = pmem[id].num_entries;
- int best_fit = -1;
- unsigned long order = pmem_order(len);
-
- if (pmem[id].no_allocator) {
- DLOG("no allocator");
- if ((len > pmem[id].size) || pmem[id].allocated)
- return -1;
- pmem[id].allocated = 1;
- return len;
- }
-
- if (order > PMEM_MAX_ORDER)
- return -1;
- DLOG("order %lx\n", order);
-
- /* look through the bitmap:
- * if you find a free slot of the correct order use it
- * otherwise, use the best fit (smallest with size > order) slot
- */
- while (curr < end) {
- if (PMEM_IS_FREE(id, curr)) {
- if (PMEM_ORDER(id, curr) == (unsigned char)order) {
- /* set the not free bit and clear others */
- best_fit = curr;
- break;
- }
- if (PMEM_ORDER(id, curr) > (unsigned char)order &&
- (best_fit < 0 ||
- PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
- best_fit = curr;
- }
- curr = PMEM_NEXT_INDEX(id, curr);
- }
-
- /* if best_fit < 0, there are no suitable slots,
- * return an error
- */
- if (best_fit < 0) {
- printk("pmem: no space left to allocate!\n");
- return -1;
- }
-
- /* now partition the best fit:
- * split the slot into 2 buddies of order - 1
- * repeat until the slot is of the correct order
- */
- while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
- int buddy;
- PMEM_ORDER(id, best_fit) -= 1;
- buddy = PMEM_BUDDY_INDEX(id, best_fit);
- PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
- }
- pmem[id].bitmap[best_fit].allocated = 1;
- return best_fit;
-}
-
-static pgprot_t pmem_access_prot(struct file *file, pgprot_t vma_prot)
-{
- int id = get_id(file);
-#ifdef pgprot_noncached
- if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
- return pgprot_noncached(vma_prot);
-#endif
-#ifdef pgprot_ext_buffered
- else if (pmem[id].buffered)
- return pgprot_ext_buffered(vma_prot);
-#endif
- return vma_prot;
-}
-
-static unsigned long pmem_start_addr(int id, struct pmem_data *data)
-{
- if (pmem[id].no_allocator)
- return PMEM_START_ADDR(id, 0);
- else
- return PMEM_START_ADDR(id, data->index);
-
-}
-
-static void *pmem_start_vaddr(int id, struct pmem_data *data)
-{
- return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
-}
-
-static unsigned long pmem_len(int id, struct pmem_data *data)
-{
- if (pmem[id].no_allocator)
- return data->index;
- else
- return PMEM_LEN(id, data->index);
-}
-
-static int pmem_map_garbage(int id, struct vm_area_struct *vma,
- struct pmem_data *data, unsigned long offset,
- unsigned long len)
-{
- int i, garbage_pages = len >> PAGE_SHIFT;
-
- vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
- for (i = 0; i < garbage_pages; i++) {
- if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
- pmem[id].garbage_pfn))
- return -EAGAIN;
- }
- return 0;
-}
-
-static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
- struct pmem_data *data, unsigned long offset,
- unsigned long len)
-{
- int garbage_pages;
- DLOG("unmap offset %lx len %lx\n", offset, len);
-
- BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
-
- garbage_pages = len >> PAGE_SHIFT;
- zap_page_range(vma, vma->vm_start + offset, len, NULL);
- pmem_map_garbage(id, vma, data, offset, len);
- return 0;
-}
-
-static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
- struct pmem_data *data, unsigned long offset,
- unsigned long len)
-{
- DLOG("map offset %lx len %lx\n", offset, len);
- BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
- BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
- BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
- BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
-
- if (io_remap_pfn_range(vma, vma->vm_start + offset,
- (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
- len, vma->vm_page_prot)) {
- return -EAGAIN;
- }
- return 0;
-}
-
-static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
- struct pmem_data *data, unsigned long offset,
- unsigned long len)
-{
- /* hold the mm semp for the vma you are modifying when you call this */
- BUG_ON(!vma);
- zap_page_range(vma, vma->vm_start + offset, len, NULL);
- return pmem_map_pfn_range(id, vma, data, offset, len);
-}
-
-static void pmem_vma_open(struct vm_area_struct *vma)
-{
- struct file *file = vma->vm_file;
- struct pmem_data *data = file->private_data;
- int id = get_id(file);
- /* this should never be called as we don't support copying pmem
- * ranges via fork */
- BUG_ON(!has_allocation(file));
- down_write(&data->sem);
- /* remap the garbage pages, forkers don't get access to the data */
- pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
- up_write(&data->sem);
-}
-
-static void pmem_vma_close(struct vm_area_struct *vma)
-{
- struct file *file = vma->vm_file;
- struct pmem_data *data = file->private_data;
-
- DLOG("current %u ppid %u file %p count %d\n", current->pid,
- current->parent->pid, file, file_count(file));
- if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
- printk(KERN_WARNING "pmem: something is very wrong, you are "
- "closing a vm backing an allocation that doesn't "
- "exist!\n");
- return;
- }
- down_write(&data->sem);
- if (data->vma == vma) {
- data->vma = NULL;
- if ((data->flags & PMEM_FLAGS_CONNECTED) &&
- (data->flags & PMEM_FLAGS_SUBMAP))
- data->flags |= PMEM_FLAGS_UNSUBMAP;
- }
- /* the kernel is going to free this vma now anyway */
- up_write(&data->sem);
-}
-
-static struct vm_operations_struct vm_ops = {
- .open = pmem_vma_open,
- .close = pmem_vma_close,
-};
-
-static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct pmem_data *data;
- int index;
- unsigned long vma_size = vma->vm_end - vma->vm_start;
- int ret = 0, id = get_id(file);
-
- if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
-#if PMEM_DEBUG
- printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
- " and a multiple of pages_size.\n");
-#endif
- return -EINVAL;
- }
-
- data = (struct pmem_data *)file->private_data;
- down_write(&data->sem);
- /* check this file isn't already mmaped, for submaps check this file
- * has never been mmaped */
- if ((data->flags & PMEM_FLAGS_SUBMAP) ||
- (data->flags & PMEM_FLAGS_UNSUBMAP)) {
-#if PMEM_DEBUG
- printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
- "this file is already mmaped. %x\n", data->flags);
-#endif
- ret = -EINVAL;
- goto error;
- }
- /* if file->private_data == unalloced, alloc*/
- if (data && data->index == -1) {
- down_write(&pmem[id].bitmap_sem);
- index = pmem_allocate(id, vma->vm_end - vma->vm_start);
- up_write(&pmem[id].bitmap_sem);
- data->index = index;
- }
- /* either no space was available or an error occured */
- if (!has_allocation(file)) {
- ret = -EINVAL;
- printk("pmem: could not find allocation for map.\n");
- goto error;
- }
-
- if (pmem_len(id, data) < vma_size) {
-#if PMEM_DEBUG
- printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
- "size of backing region [%lu].\n", vma_size,
- pmem_len(id, data));
-#endif
- ret = -EINVAL;
- goto error;
- }
-
- vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
- vma->vm_page_prot = pmem_access_prot(file, vma->vm_page_prot);
-
- if (data->flags & PMEM_FLAGS_CONNECTED) {
- struct pmem_region_node *region_node;
- struct list_head *elt;
- if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
- printk("pmem: mmap failed in kernel!\n");
- ret = -EAGAIN;
- goto error;
- }
- list_for_each(elt, &data->region_list) {
- region_node = list_entry(elt, struct pmem_region_node,
- list);
- DLOG("remapping file: %p %lx %lx\n", file,
- region_node->region.offset,
- region_node->region.len);
- if (pmem_remap_pfn_range(id, vma, data,
- region_node->region.offset,
- region_node->region.len)) {
- ret = -EAGAIN;
- goto error;
- }
- }
- data->flags |= PMEM_FLAGS_SUBMAP;
- get_task_struct(current->group_leader);
- data->task = current->group_leader;
- data->vma = vma;
-#if PMEM_DEBUG
- data->pid = current->pid;
-#endif
- DLOG("submmapped file %p vma %p pid %u\n", file, vma,
- current->pid);
- } else {
- if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
- printk(KERN_INFO "pmem: mmap failed in kernel!\n");
- ret = -EAGAIN;
- goto error;
- }
- data->flags |= PMEM_FLAGS_MASTERMAP;
- data->pid = current->pid;
- }
- vma->vm_ops = &vm_ops;
-error:
- up_write(&data->sem);
- return ret;
-}
-
-/* the following are the api for accessing pmem regions by other drivers
- * from inside the kernel */
-int get_pmem_user_addr(struct file *file, unsigned long *start,
- unsigned long *len)
-{
- struct pmem_data *data;
- if (!is_pmem_file(file) || !has_allocation(file)) {
-#if PMEM_DEBUG
- printk(KERN_INFO "pmem: requested pmem data from invalid"
- "file.\n");
-#endif
- return -1;
- }
- data = (struct pmem_data *)file->private_data;
- down_read(&data->sem);
- if (data->vma) {
- *start = data->vma->vm_start;
- *len = data->vma->vm_end - data->vma->vm_start;
- } else {
- *start = 0;
- *len = 0;
- }
- up_read(&data->sem);
- return 0;
-}
-
-int get_pmem_addr(struct file *file, unsigned long *start,
- unsigned long *vstart, unsigned long *len)
-{
- struct pmem_data *data;
- int id;
-
- if (!is_pmem_file(file) || !has_allocation(file)) {
- return -1;
- }
-
- data = (struct pmem_data *)file->private_data;
- if (data->index == -1) {
-#if PMEM_DEBUG
- printk(KERN_INFO "pmem: requested pmem data from file with no "
- "allocation.\n");
- return -1;
-#endif
- }
- id = get_id(file);
-
- down_read(&data->sem);
- *start = pmem_start_addr(id, data);
- *len = pmem_len(id, data);
- *vstart = (unsigned long)pmem_start_vaddr(id, data);
- up_read(&data->sem);
-#if PMEM_DEBUG
- down_write(&data->sem);
- data->ref++;
- up_write(&data->sem);
-#endif
- return 0;
-}
-
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
- unsigned long *len, struct file **filp)
-{
- struct file *file;
-
- file = fget(fd);
- if (unlikely(file == NULL)) {
- printk(KERN_INFO "pmem: requested data from file descriptor "
- "that doesn't exist.");
- return -1;
- }
-
- if (get_pmem_addr(file, start, vstart, len))
- goto end;
-
- if (filp)
- *filp = file;
- return 0;
-end:
- fput(file);
- return -1;
-}
-
-void put_pmem_file(struct file *file)
-{
- struct pmem_data *data;
- int id;
-
- if (!is_pmem_file(file))
- return;
- id = get_id(file);
- data = (struct pmem_data *)file->private_data;
-#if PMEM_DEBUG
- down_write(&data->sem);
- if (data->ref == 0) {
- printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
- pmem[id].dev.name, data->pid);
- BUG();
- }
- data->ref--;
- up_write(&data->sem);
-#endif
- fput(file);
-}
-
-void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
-{
- struct pmem_data *data;
- int id;
- void *vaddr;
- struct pmem_region_node *region_node;
- struct list_head *elt;
- void *flush_start, *flush_end;
-
- if (!is_pmem_file(file) || !has_allocation(file)) {
- return;
- }
-
- id = get_id(file);
- data = (struct pmem_data *)file->private_data;
- if (!pmem[id].cached || file->f_flags & O_SYNC)
- return;
-
- down_read(&data->sem);
- vaddr = pmem_start_vaddr(id, data);
- /* if this isn't a submmapped file, flush the whole thing */
- if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
- dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
- goto end;
- }
- /* otherwise, flush the region of the file we are drawing */
- list_for_each(elt, &data->region_list) {
- region_node = list_entry(elt, struct pmem_region_node, list);
- if ((offset >= region_node->region.offset) &&
- ((offset + len) <= (region_node->region.offset +
- region_node->region.len))) {
- flush_start = vaddr + region_node->region.offset;
- flush_end = flush_start + region_node->region.len;
- dmac_flush_range(flush_start, flush_end);
- break;
- }
- }
-end:
- up_read(&data->sem);
-}
-
-static int pmem_connect(unsigned long connect, struct file *file)
-{
- struct pmem_data *data = (struct pmem_data *)file->private_data;
- struct pmem_data *src_data;
- struct file *src_file;
- int ret = 0, put_needed;
-
- down_write(&data->sem);
- /* retrieve the src file and check it is a pmem file with an alloc */
- src_file = fget_light(connect, &put_needed);
- DLOG("connect %p to %p\n", file, src_file);
- if (!src_file) {
- printk("pmem: src file not found!\n");
- ret = -EINVAL;
- goto err_no_file;
- }
- if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
- printk(KERN_INFO "pmem: src file is not a pmem file or has no "
- "alloc!\n");
- ret = -EINVAL;
- goto err_bad_file;
- }
- src_data = (struct pmem_data *)src_file->private_data;
-
- if (has_allocation(file) && (data->index != src_data->index)) {
- printk("pmem: file is already mapped but doesn't match this"
- " src_file!\n");
- ret = -EINVAL;
- goto err_bad_file;
- }
- data->index = src_data->index;
- data->flags |= PMEM_FLAGS_CONNECTED;
- data->master_fd = connect;
- data->master_file = src_file;
-
-err_bad_file:
- fput_light(src_file, put_needed);
-err_no_file:
- up_write(&data->sem);
- return ret;
-}
-
-static void pmem_unlock_data_and_mm(struct pmem_data *data,
- struct mm_struct *mm)
-{
- up_write(&data->sem);
- if (mm != NULL) {
- up_write(&mm->mmap_sem);
- mmput(mm);
- }
-}
-
-static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
- struct mm_struct **locked_mm)
-{
- int ret = 0;
- struct mm_struct *mm = NULL;
- *locked_mm = NULL;
-lock_mm:
- down_read(&data->sem);
- if (PMEM_IS_SUBMAP(data)) {
- mm = get_task_mm(data->task);
- if (!mm) {
-#if PMEM_DEBUG
- printk("pmem: can't remap task is gone!\n");
-#endif
- up_read(&data->sem);
- return -1;
- }
- }
- up_read(&data->sem);
-
- if (mm)
- down_write(&mm->mmap_sem);
-
- down_write(&data->sem);
- /* check that the file didn't get mmaped before we could take the
- * data sem, this should be safe b/c you can only submap each file
- * once */
- if (PMEM_IS_SUBMAP(data) && !mm) {
- pmem_unlock_data_and_mm(data, mm);
- up_write(&data->sem);
- goto lock_mm;
- }
- /* now check that vma.mm is still there, it could have been
- * deleted by vma_close before we could get the data->sem */
- if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
- /* might as well release this */
- if (data->flags & PMEM_FLAGS_SUBMAP) {
- put_task_struct(data->task);
- data->task = NULL;
- /* lower the submap flag to show the mm is gone */
- data->flags &= ~(PMEM_FLAGS_SUBMAP);
- }
- pmem_unlock_data_and_mm(data, mm);
- return -1;
- }
- *locked_mm = mm;
- return ret;
-}
-
-int pmem_remap(struct pmem_region *region, struct file *file,
- unsigned operation)
-{
- int ret;
- struct pmem_region_node *region_node;
- struct mm_struct *mm = NULL;
- struct list_head *elt, *elt2;
- int id = get_id(file);
- struct pmem_data *data = (struct pmem_data *)file->private_data;
-
- /* pmem region must be aligned on a page boundry */
- if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
- !PMEM_IS_PAGE_ALIGNED(region->len))) {
-#if PMEM_DEBUG
- printk("pmem: request for unaligned pmem suballocation "
- "%lx %lx\n", region->offset, region->len);
-#endif
- return -EINVAL;
- }
-
- /* if userspace requests a region of len 0, there's nothing to do */
- if (region->len == 0)
- return 0;
-
- /* lock the mm and data */
- ret = pmem_lock_data_and_mm(file, data, &mm);
- if (ret)
- return 0;
-
- /* only the owner of the master file can remap the client fds
- * that back in it */
- if (!is_master_owner(file)) {
-#if PMEM_DEBUG
- printk("pmem: remap requested from non-master process\n");
-#endif
- ret = -EINVAL;
- goto err;
- }
-
- /* check that the requested range is within the src allocation */
- if (unlikely((region->offset > pmem_len(id, data)) ||
- (region->len > pmem_len(id, data)) ||
- (region->offset + region->len > pmem_len(id, data)))) {
-#if PMEM_DEBUG
- printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
-#endif
- ret = -EINVAL;
- goto err;
- }
-
- if (operation == PMEM_MAP) {
- region_node = kmalloc(sizeof(struct pmem_region_node),
- GFP_KERNEL);
- if (!region_node) {
- ret = -ENOMEM;
-#if PMEM_DEBUG
- printk(KERN_INFO "No space to allocate metadata!");
-#endif
- goto err;
- }
- region_node->region = *region;
- list_add(®ion_node->list, &data->region_list);
- } else if (operation == PMEM_UNMAP) {
- int found = 0;
- list_for_each_safe(elt, elt2, &data->region_list) {
- region_node = list_entry(elt, struct pmem_region_node,
- list);
- if (region->len == 0 ||
- (region_node->region.offset == region->offset &&
- region_node->region.len == region->len)) {
- list_del(elt);
- kfree(region_node);
- found = 1;
- }
- }
- if (!found) {
-#if PMEM_DEBUG
- printk("pmem: Unmap region does not map any mapped "
- "region!");
-#endif
- ret = -EINVAL;
- goto err;
- }
- }
-
- if (data->vma && PMEM_IS_SUBMAP(data)) {
- if (operation == PMEM_MAP)
- ret = pmem_remap_pfn_range(id, data->vma, data,
- region->offset, region->len);
- else if (operation == PMEM_UNMAP)
- ret = pmem_unmap_pfn_range(id, data->vma, data,
- region->offset, region->len);
- }
-
-err:
- pmem_unlock_data_and_mm(data, mm);
- return ret;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data)
-{
- struct pmem_region_node *region_node;
- struct list_head *elt, *elt2;
- struct mm_struct *mm = NULL;
- int id = get_id(file);
- int ret = 0;
-
- data->master_file = NULL;
- ret = pmem_lock_data_and_mm(file, data, &mm);
- /* if lock_data_and_mm fails either the task that mapped the fd, or
- * the vma that mapped it have already gone away, nothing more
- * needs to be done */
- if (ret)
- return;
- /* unmap everything */
- /* delete the regions and region list nothing is mapped any more */
- if (data->vma)
- list_for_each_safe(elt, elt2, &data->region_list) {
- region_node = list_entry(elt, struct pmem_region_node,
- list);
- pmem_unmap_pfn_range(id, data->vma, data,
- region_node->region.offset,
- region_node->region.len);
- list_del(elt);
- kfree(region_node);
- }
- /* delete the master file */
- pmem_unlock_data_and_mm(data, mm);
-}
-
-static void pmem_get_size(struct pmem_region *region, struct file *file)
-{
- struct pmem_data *data = (struct pmem_data *)file->private_data;
- int id = get_id(file);
-
- if (!has_allocation(file)) {
- region->offset = 0;
- region->len = 0;
- return;
- } else {
- region->offset = pmem_start_addr(id, data);
- region->len = pmem_len(id, data);
- }
- DLOG("offset %lx len %lx\n", region->offset, region->len);
-}
-
-
-static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct pmem_data *data;
- int id = get_id(file);
-
- switch (cmd) {
- case PMEM_GET_PHYS:
- {
- struct pmem_region region;
- DLOG("get_phys\n");
- if (!has_allocation(file)) {
- region.offset = 0;
- region.len = 0;
- } else {
- data = (struct pmem_data *)file->private_data;
- region.offset = pmem_start_addr(id, data);
- region.len = pmem_len(id, data);
- }
- printk(KERN_INFO "pmem: request for physical address of pmem region "
- "from process %d.\n", current->pid);
- if (copy_to_user((void __user *)arg, ®ion,
- sizeof(struct pmem_region)))
- return -EFAULT;
- break;
- }
- case PMEM_MAP:
- {
- struct pmem_region region;
- if (copy_from_user(®ion, (void __user *)arg,
- sizeof(struct pmem_region)))
- return -EFAULT;
- data = (struct pmem_data *)file->private_data;
- return pmem_remap(®ion, file, PMEM_MAP);
- }
- break;
- case PMEM_UNMAP:
- {
- struct pmem_region region;
- if (copy_from_user(®ion, (void __user *)arg,
- sizeof(struct pmem_region)))
- return -EFAULT;
- data = (struct pmem_data *)file->private_data;
- return pmem_remap(®ion, file, PMEM_UNMAP);
- break;
- }
- case PMEM_GET_SIZE:
- {
- struct pmem_region region;
- DLOG("get_size\n");
- pmem_get_size(®ion, file);
- if (copy_to_user((void __user *)arg, ®ion,
- sizeof(struct pmem_region)))
- return -EFAULT;
- break;
- }
- case PMEM_GET_TOTAL_SIZE:
- {
- struct pmem_region region;
- DLOG("get total size\n");
- region.offset = 0;
- get_id(file);
- region.len = pmem[id].size;
- if (copy_to_user((void __user *)arg, ®ion,
- sizeof(struct pmem_region)))
- return -EFAULT;
- break;
- }
- case PMEM_ALLOCATE:
- {
- if (has_allocation(file))
- return -EINVAL;
- data = (struct pmem_data *)file->private_data;
- data->index = pmem_allocate(id, arg);
- break;
- }
- case PMEM_CONNECT:
- DLOG("connect\n");
- return pmem_connect(arg, file);
- break;
- case PMEM_CACHE_FLUSH:
- {
- struct pmem_region region;
- DLOG("flush\n");
- if (copy_from_user(®ion, (void __user *)arg,
- sizeof(struct pmem_region)))
- return -EFAULT;
- flush_pmem_file(file, region.offset, region.len);
- break;
- }
- default:
- if (pmem[id].ioctl)
- return pmem[id].ioctl(file, cmd, arg);
- return -EINVAL;
- }
- return 0;
-}
-
-#if PMEM_DEBUG
-static ssize_t debug_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
-{
- struct list_head *elt, *elt2;
- struct pmem_data *data;
- struct pmem_region_node *region_node;
- int id = (int)file->private_data;
- const int debug_bufmax = 4096;
- static char buffer[4096];
- int n = 0;
-
- DLOG("debug open\n");
- n = scnprintf(buffer, debug_bufmax,
- "pid #: mapped regions (offset, len) (offset,len)...\n");
-
- mutex_lock(&pmem[id].data_list_lock);
- list_for_each(elt, &pmem[id].data_list) {
- data = list_entry(elt, struct pmem_data, list);
- down_read(&data->sem);
- n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
- data->pid);
- list_for_each(elt2, &data->region_list) {
- region_node = list_entry(elt2, struct pmem_region_node,
- list);
- n += scnprintf(buffer + n, debug_bufmax - n,
- "(%lx,%lx) ",
- region_node->region.offset,
- region_node->region.len);
- }
- n += scnprintf(buffer + n, debug_bufmax - n, "\n");
- up_read(&data->sem);
- }
- mutex_unlock(&pmem[id].data_list_lock);
-
- n++;
- buffer[n] = 0;
- return simple_read_from_buffer(buf, count, ppos, buffer, n);
-}
-
-static struct file_operations debug_fops = {
- .read = debug_read,
- .open = debug_open,
-};
-#endif
-
-#if 0
-static struct miscdevice pmem_dev = {
- .name = "pmem",
- .fops = &pmem_fops,
-};
-#endif
-
-int pmem_setup(struct android_pmem_platform_data *pdata,
- long (*ioctl)(struct file *, unsigned int, unsigned long),
- int (*release)(struct inode *, struct file *))
-{
- int err = 0;
- int i, index = 0;
- int id = id_count;
- id_count++;
-
- pmem[id].no_allocator = pdata->no_allocator;
- pmem[id].cached = pdata->cached;
- pmem[id].buffered = pdata->buffered;
- pmem[id].base = pdata->start;
- pmem[id].size = pdata->size;
- pmem[id].ioctl = ioctl;
- pmem[id].release = release;
- init_rwsem(&pmem[id].bitmap_sem);
- mutex_init(&pmem[id].data_list_lock);
- INIT_LIST_HEAD(&pmem[id].data_list);
- pmem[id].dev.name = pdata->name;
- pmem[id].dev.minor = id;
- pmem[id].dev.fops = &pmem_fops;
- printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
-
- err = misc_register(&pmem[id].dev);
- if (err) {
- printk(KERN_ALERT "Unable to register pmem driver!\n");
- goto err_cant_register_device;
- }
- pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
-
- pmem[id].bitmap = kmalloc(pmem[id].num_entries *
- sizeof(struct pmem_bits), GFP_KERNEL);
- if (!pmem[id].bitmap)
- goto err_no_mem_for_metadata;
-
- memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) *
- pmem[id].num_entries);
-
- for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
- if ((pmem[id].num_entries) & 1<name, S_IFREG | S_IRUGO, NULL, (void *)id,
- &debug_fops);
-#endif
- return 0;
-error_cant_remap:
- kfree(pmem[id].bitmap);
-err_no_mem_for_metadata:
- misc_deregister(&pmem[id].dev);
-err_cant_register_device:
- return -1;
-}
-
-static int pmem_probe(struct platform_device *pdev)
-{
- struct android_pmem_platform_data *pdata;
-
- if (!pdev || !pdev->dev.platform_data) {
- printk(KERN_ALERT "Unable to probe pmem!\n");
- return -1;
- }
- pdata = pdev->dev.platform_data;
- return pmem_setup(pdata, NULL, NULL);
-}
-
-
-static int pmem_remove(struct platform_device *pdev)
-{
- int id = pdev->id;
- __free_page(pfn_to_page(pmem[id].garbage_pfn));
- misc_deregister(&pmem[id].dev);
- return 0;
-}
-
-static struct platform_driver pmem_driver = {
- .probe = pmem_probe,
- .remove = pmem_remove,
- .driver = { .name = "android_pmem" }
-};
-
-
-static int __init pmem_init(void)
-{
- return platform_driver_register(&pmem_driver);
-}
-
-static void __exit pmem_exit(void)
-{
- platform_driver_unregister(&pmem_driver);
-}
-
-module_init(pmem_init);
-module_exit(pmem_exit);
-
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index e77e4e0396cf..1df9586f2730 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -355,7 +355,14 @@ static void send_data(struct asus_oled_dev *odev)
static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
{
- while (count-- > 0 && val) {
+ odev->last_val = val;
+
+ if (val == 0) {
+ odev->buf_offs += count;
+ return 0;
+ }
+
+ while (count-- > 0) {
size_t x = odev->buf_offs % odev->width;
size_t y = odev->buf_offs / odev->width;
size_t i;
@@ -406,7 +413,6 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
;
}
- odev->last_val = val;
odev->buf_offs++;
}
@@ -805,10 +811,9 @@ error:
static void __exit asus_oled_exit(void)
{
+ usb_deregister(&oled_driver);
class_remove_file(oled_class, &class_attr_version.attr);
class_destroy(oled_class);
-
- usb_deregister(&oled_driver);
}
module_init(asus_oled_init);
diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig
deleted file mode 100644
index c7a2b3bc0a18..000000000000
--- a/drivers/staging/gma500/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-config DRM_PSB
- tristate "Intel GMA5/600 KMS Framebuffer"
- depends on DRM && PCI && X86 && BROKEN
- select FB_CFB_COPYAREA
- select FB_CFB_FILLRECT
- select FB_CFB_IMAGEBLIT
- select DRM_KMS_HELPER
- select DRM_TTM
- help
- Say yes for an experimental 2D KMS framebuffer driver for the
- Intel GMA500 ('Poulsbo') and other Intel IMG based graphics
- devices.
-
-config DRM_PSB_MRST
- bool "Intel GMA600 support (Experimental)"
- depends on DRM_PSB
- help
- Say yes to include support for GMA600 (Intel Moorestown/Oaktrail)
- platforms with LVDS ports. HDMI and MIPI are not currently
- supported.
-
-config DRM_PSB_MFLD
- bool "Intel Medfield support (Experimental)"
- depends on DRM_PSB
- help
- Say yes to include support for Intel Medfield platforms with MIPI
- interfaces.
-
-config DRM_PSB_CDV
- bool "Intel Cedarview support (Experimental)"
- depends on DRM_PSB
- help
- Say yes to include support for Intel Cedarview platforms
diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
deleted file mode 100644
index c729868b1b10..000000000000
--- a/drivers/staging/gma500/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# KMS driver for the GMA500
-#
-ccflags-y += -Iinclude/drm
-
-psb_gfx-y += gem_glue.o \
- accel_2d.o \
- backlight.o \
- framebuffer.o \
- gem.o \
- gtt.o \
- intel_bios.o \
- intel_i2c.o \
- intel_opregion.o \
- mmu.o \
- power.o \
- psb_drv.o \
- psb_intel_display.o \
- psb_intel_lvds.o \
- psb_intel_modes.o \
- psb_intel_sdvo.o \
- psb_lid.o \
- psb_irq.o \
- psb_device.o \
- mid_bios.o
-
-psb_gfx-$(CONFIG_DRM_PSB_CDV) += cdv_device.o \
- cdv_intel_crt.o \
- cdv_intel_display.o \
- cdv_intel_hdmi.o \
- cdv_intel_lvds.o
-
-psb_gfx-$(CONFIG_DRM_PSB_MRST) += mrst_device.o \
- mrst_crtc.o \
- mrst_lvds.o \
- mrst_hdmi.o \
- mrst_hdmi_i2c.o
-
-psb_gfx-$(CONFIG_DRM_PSB_MFLD) += mdfld_device.o \
- mdfld_output.o \
- mdfld_pyr_cmd.o \
- mdfld_tmd_vid.o \
- mdfld_tpo_cmd.o \
- mdfld_tpo_vid.o \
- mdfld_dsi_pkg_sender.o \
- mdfld_dsi_dpi.o \
- mdfld_dsi_output.o \
- mdfld_dsi_dbi.o \
- mdfld_dsi_dbi_dpu.o \
- mdfld_intel_display.o
-
-obj-$(CONFIG_DRM_PSB) += psb_gfx.o
diff --git a/drivers/staging/gma500/TODO b/drivers/staging/gma500/TODO
deleted file mode 100644
index fc836158e74c..000000000000
--- a/drivers/staging/gma500/TODO
+++ /dev/null
@@ -1,15 +0,0 @@
-- Sort out the power management side. Not important for Poulsbo but
- matters for Moorestown/Medfield
-- Debug Oaktrail/Moorestown support (single pipe, no BIOS on mrst,
- some other differences)
-- Add 2D acceleration via console and DRM
-- Add scrolling acceleration using the GTT to do remapping on the main
- framebuffer.
-- HDMI testing
-- Oaktrail HDMI and other features
-- Oaktrail MIPI
-- Medfield needs a lot of further love
-
-As per kernel policy and the in the interest of the safety of various
-kittens there is no support or plans to add hooks for the closed user space
-stuff.
diff --git a/drivers/staging/gma500/accel_2d.c b/drivers/staging/gma500/accel_2d.c
deleted file mode 100644
index b8f78ebbb145..000000000000
--- a/drivers/staging/gma500/accel_2d.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- * develop this driver.
- *
- **************************************************************************/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "framebuffer.h"
-
-/**
- * psb_spank - reset the 2D engine
- * @dev_priv: our PSB DRM device
- *
- * Soft reset the graphics engine and then reload the necessary registers.
- * We use this at initialisation time but it will become relevant for
- * accelerated X later
- */
-void psb_spank(struct drm_psb_private *dev_priv)
-{
- PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET |
- _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET |
- _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET |
- _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET);
- PSB_RSGX32(PSB_CR_SOFT_RESET);
-
- msleep(1);
-
- PSB_WSGX32(0, PSB_CR_SOFT_RESET);
- wmb();
- PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT,
- PSB_CR_BIF_CTRL);
- wmb();
- (void) PSB_RSGX32(PSB_CR_BIF_CTRL);
-
- msleep(1);
- PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT,
- PSB_CR_BIF_CTRL);
- (void) PSB_RSGX32(PSB_CR_BIF_CTRL);
- PSB_WSGX32(dev_priv->gtt.gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
-}
-
-/**
- * psb2_2d_wait_available - wait for FIFO room
- * @dev_priv: our DRM device
- * @size: size (in dwords) of the command we want to issue
- *
- * Wait until there is room to load the FIFO with our data. If the
- * device is not responding then reset it
- */
-static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
- unsigned size)
-{
- uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
- unsigned long t = jiffies + HZ;
-
- while (avail < size) {
- avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
- if (time_after(jiffies, t)) {
- psb_spank(dev_priv);
- return -EIO;
- }
- }
- return 0;
-}
-
-/**
- * psb_2d_submit - submit a 2D command
- * @dev_priv: our DRM device
- * @cmdbuf: command to issue
- * @size: length (in dwords)
- *
- * Issue one or more 2D commands to the accelerator. This needs to be
- * serialized later when we add the GEM interfaces for acceleration
- */
-static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
- unsigned size)
-{
- int ret = 0;
- int i;
- unsigned submit_size;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->lock_2d, flags);
- while (size > 0) {
- submit_size = (size < 0x60) ? size : 0x60;
- size -= submit_size;
- ret = psb_2d_wait_available(dev_priv, submit_size);
- if (ret)
- break;
-
- submit_size <<= 2;
-
- for (i = 0; i < submit_size; i += 4)
- PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i);
-
- (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
- }
- spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
- return ret;
-}
-
-
-/**
- * psb_accel_2d_copy_direction - compute blit order
- * @xdir: X direction of move
- * @ydir: Y direction of move
- *
- * Compute the correct order setings to ensure that an overlapping blit
- * correctly copies all the pixels.
- */
-static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
-{
- if (xdir < 0)
- return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL :
- PSB_2D_COPYORDER_TR2BL;
- else
- return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR :
- PSB_2D_COPYORDER_TL2BR;
-}
-
-/**
- * psb_accel_2d_copy - accelerated 2D copy
- * @dev_priv: our DRM device
- * @src_offset in bytes
- * @src_stride in bytes
- * @src_format psb 2D format defines
- * @dst_offset in bytes
- * @dst_stride in bytes
- * @dst_format psb 2D format defines
- * @src_x offset in pixels
- * @src_y offset in pixels
- * @dst_x offset in pixels
- * @dst_y offset in pixels
- * @size_x of the copied area
- * @size_y of the copied area
- *
- * Format and issue a 2D accelerated copy command.
- */
-static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
- uint32_t src_offset, uint32_t src_stride,
- uint32_t src_format, uint32_t dst_offset,
- uint32_t dst_stride, uint32_t dst_format,
- uint16_t src_x, uint16_t src_y,
- uint16_t dst_x, uint16_t dst_y,
- uint16_t size_x, uint16_t size_y)
-{
- uint32_t blit_cmd;
- uint32_t buffer[10];
- uint32_t *buf;
- uint32_t direction;
-
- buf = buffer;
-
- direction =
- psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y);
-
- if (direction == PSB_2D_COPYORDER_BR2TL ||
- direction == PSB_2D_COPYORDER_TR2BL) {
- src_x += size_x - 1;
- dst_x += size_x - 1;
- }
- if (direction == PSB_2D_COPYORDER_BR2TL ||
- direction == PSB_2D_COPYORDER_BL2TR) {
- src_y += size_y - 1;
- dst_y += size_y - 1;
- }
-
- blit_cmd =
- PSB_2D_BLIT_BH |
- PSB_2D_ROT_NONE |
- PSB_2D_DSTCK_DISABLE |
- PSB_2D_SRCCK_DISABLE |
- PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction;
-
- *buf++ = PSB_2D_FENCE_BH;
- *buf++ =
- PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
- PSB_2D_DST_STRIDE_SHIFT);
- *buf++ = dst_offset;
- *buf++ =
- PSB_2D_SRC_SURF_BH | src_format | (src_stride <<
- PSB_2D_SRC_STRIDE_SHIFT);
- *buf++ = src_offset;
- *buf++ =
- PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) |
- (src_y << PSB_2D_SRCOFF_YSTART_SHIFT);
- *buf++ = blit_cmd;
- *buf++ =
- (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
- PSB_2D_DST_YSTART_SHIFT);
- *buf++ =
- (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
- PSB_2D_DST_YSIZE_SHIFT);
- *buf++ = PSB_2D_FLUSH_BH;
-
- return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
-}
-
-/**
- * psbfb_copyarea_accel - copyarea acceleration for /dev/fb
- * @info: our framebuffer
- * @a: copyarea parameters from the framebuffer core
- *
- * Perform a 2D copy via the accelerator
- */
-static void psbfb_copyarea_accel(struct fb_info *info,
- const struct fb_copyarea *a)
-{
- struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = &fbdev->pfb;
- struct drm_device *dev = psbfb->base.dev;
- struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
- struct drm_psb_private *dev_priv = dev->dev_private;
- uint32_t offset;
- uint32_t stride;
- uint32_t src_format;
- uint32_t dst_format;
-
- if (!fb)
- return;
-
- offset = psbfb->gtt->offset;
- stride = fb->pitches[0];
-
- switch (fb->depth) {
- case 8:
- src_format = PSB_2D_SRC_332RGB;
- dst_format = PSB_2D_DST_332RGB;
- break;
- case 15:
- src_format = PSB_2D_SRC_555RGB;
- dst_format = PSB_2D_DST_555RGB;
- break;
- case 16:
- src_format = PSB_2D_SRC_565RGB;
- dst_format = PSB_2D_DST_565RGB;
- break;
- case 24:
- case 32:
- /* this is wrong but since we don't do blending its okay */
- src_format = PSB_2D_SRC_8888ARGB;
- dst_format = PSB_2D_DST_8888ARGB;
- break;
- default:
- /* software fallback */
- cfb_copyarea(info, a);
- return;
- }
-
- if (!gma_power_begin(dev, false)) {
- cfb_copyarea(info, a);
- return;
- }
- psb_accel_2d_copy(dev_priv,
- offset, stride, src_format,
- offset, stride, dst_format,
- a->sx, a->sy, a->dx, a->dy, a->width, a->height);
- gma_power_end(dev);
-}
-
-/**
- * psbfb_copyarea - 2D copy interface
- * @info: our framebuffer
- * @region: region to copy
- *
- * Copy an area of the framebuffer console either by the accelerator
- * or directly using the cfb helpers according to the request
- */
-void psbfb_copyarea(struct fb_info *info,
- const struct fb_copyarea *region)
-{
- if (unlikely(info->state != FBINFO_STATE_RUNNING))
- return;
-
- /* Avoid the 8 pixel erratum */
- if (region->width == 8 || region->height == 8 ||
- (info->flags & FBINFO_HWACCEL_DISABLED))
- return cfb_copyarea(info, region);
-
- psbfb_copyarea_accel(info, region);
-}
-
-/**
- * psbfb_sync - synchronize 2D
- * @info: our framebuffer
- *
- * Wait for the 2D engine to quiesce so that we can do CPU
- * access to the framebuffer again
- */
-int psbfb_sync(struct fb_info *info)
-{
- struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = &fbdev->pfb;
- struct drm_device *dev = psbfb->base.dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- unsigned long _end = jiffies + DRM_HZ;
- int busy = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->lock_2d, flags);
- /*
- * First idle the 2D engine.
- */
-
- if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
- ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0))
- goto out;
-
- do {
- busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
- cpu_relax();
- } while (busy && !time_after_eq(jiffies, _end));
-
- if (busy)
- busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
- if (busy)
- goto out;
-
- do {
- busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
- _PSB_C2B_STATUS_BUSY) != 0);
- cpu_relax();
- } while (busy && !time_after_eq(jiffies, _end));
- if (busy)
- busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
- _PSB_C2B_STATUS_BUSY) != 0);
-
-out:
- spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
- return (busy) ? -EBUSY : 0;
-}
-
-int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_psb_2d_op *op = data;
- u32 *op_ptr = &op->cmd[0];
- int i;
- struct drm_gem_object *obj;
- struct gtt_range *gtt;
- int err = -EINVAL;
-
- if (!dev_priv->ops->accel_2d)
- return -EOPNOTSUPP;
- if (op->size > PSB_2D_OP_BUFLEN)
- return -EINVAL;
-
- /* The GEM object being used. We need to support separate src/dst/etc
- in the end but for now keep them all the same */
- obj = drm_gem_object_lookup(dev, file, op->src);
- if (obj == NULL)
- return -ENOENT;
- gtt = container_of(obj, struct gtt_range, gem);
-
- if (psb_gtt_pin(gtt) < 0)
- goto bad_2;
- for (i = 0; i < op->size; i++, op_ptr++) {
- u32 r = *op_ptr & 0xF0000000;
- /* Fill in the GTT offsets for the command buffer */
- if (r == PSB_2D_SRC_SURF_BH ||
- r == PSB_2D_DST_SURF_BH ||
- r == PSB_2D_MASK_SURF_BH ||
- r == PSB_2D_PAT_SURF_BH) {
- i++;
- op_ptr++;
- if (i == op->size)
- goto bad;
- if (*op_ptr)
- goto bad;
- *op_ptr = gtt->offset;
- continue;
- }
- }
- psbfb_2d_submit(dev_priv, op->cmd, op->size);
- err = 0;
-bad:
- psb_gtt_unpin(gtt);
-bad_2:
- drm_gem_object_unreference(obj);
- return err;
-}
diff --git a/drivers/staging/gma500/backlight.c b/drivers/staging/gma500/backlight.c
deleted file mode 100644
index 20793951fcac..000000000000
--- a/drivers/staging/gma500/backlight.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * GMA500 Backlight Interface
- *
- * Copyright (c) 2009-2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Eric Knopp
- *
- */
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_drv.h"
-#include "intel_bios.h"
-#include "power.h"
-
-int gma_backlight_init(struct drm_device *dev)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct drm_psb_private *dev_priv = dev->dev_private;
- return dev_priv->ops->backlight_init(dev);
-#else
- return 0;
-#endif
-}
-
-void gma_backlight_exit(struct drm_device *dev)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct drm_psb_private *dev_priv = dev->dev_private;
- if (dev_priv->backlight_device) {
- dev_priv->backlight_device->props.brightness = 0;
- backlight_update_status(dev_priv->backlight_device);
- backlight_device_unregister(dev_priv->backlight_device);
- }
-#endif
-}
diff --git a/drivers/staging/gma500/cdv_device.c b/drivers/staging/gma500/cdv_device.c
deleted file mode 100644
index 8ec10caab13e..000000000000
--- a/drivers/staging/gma500/cdv_device.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include
-#include
-#include
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-#include "cdv_device.h"
-
-#define VGA_SR_INDEX 0x3c4
-#define VGA_SR_DATA 0x3c5
-
-static void cdv_disable_vga(struct drm_device *dev)
-{
- u8 sr1;
- u32 vga_reg;
-
- vga_reg = VGACNTRL;
-
- outb(1, VGA_SR_INDEX);
- sr1 = inb(VGA_SR_DATA);
- outb(sr1 | 1<<5, VGA_SR_DATA);
- udelay(300);
-
- REG_WRITE(vga_reg, VGA_DISP_DISABLE);
- REG_READ(vga_reg);
-}
-
-static int cdv_output_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- cdv_disable_vga(dev);
-
- cdv_intel_crt_init(dev, &dev_priv->mode_dev);
- cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
-
- /* These bits indicate HDMI not SDVO on CDV, but we don't yet support
- the HDMI interface */
- if (REG_READ(SDVOB) & SDVO_DETECTED)
- cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
- if (REG_READ(SDVOC) & SDVO_DETECTED)
- cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
- return 0;
-}
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-/*
- * Poulsbo Backlight Interfaces
- */
-
-#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-
-#define PSB_BLC_PWM_PRECISION_FACTOR 10
-#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ 0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
-
-static int cdv_brightness;
-static struct backlight_device *cdv_backlight_device;
-
-static int cdv_get_brightness(struct backlight_device *bd)
-{
- /* return locally cached var instead of HW read (due to DPST etc.) */
- /* FIXME: ideally return actual value in case firmware fiddled with
- it */
- return cdv_brightness;
-}
-
-
-static int cdv_backlight_setup(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- unsigned long core_clock;
- /* u32 bl_max_freq; */
- /* unsigned long value; */
- u16 bl_max_freq;
- uint32_t value;
- uint32_t blc_pwm_precision_factor;
-
- /* get bl_max_freq and pol from dev_priv*/
- if (!dev_priv->lvds_bl) {
- dev_err(dev->dev, "Has no valid LVDS backlight info\n");
- return -ENOENT;
- }
- bl_max_freq = dev_priv->lvds_bl->freq;
- blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
-
- core_clock = dev_priv->core_freq;
-
- value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
- value *= blc_pwm_precision_factor;
- value /= bl_max_freq;
- value /= blc_pwm_precision_factor;
-
- if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
- value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
- return -ERANGE;
- else {
- /* FIXME */
- }
- return 0;
-}
-
-static int cdv_set_brightness(struct backlight_device *bd)
-{
- int level = bd->props.brightness;
-
- /* Percentage 1-100% being valid */
- if (level < 1)
- level = 1;
-
- /*cdv_intel_lvds_set_brightness(dev, level); FIXME */
- cdv_brightness = level;
- return 0;
-}
-
-static const struct backlight_ops cdv_ops = {
- .get_brightness = cdv_get_brightness,
- .update_status = cdv_set_brightness,
-};
-
-static int cdv_backlight_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- int ret;
- struct backlight_properties props;
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.max_brightness = 100;
- props.type = BACKLIGHT_PLATFORM;
-
- cdv_backlight_device = backlight_device_register("psb-bl",
- NULL, (void *)dev, &cdv_ops, &props);
- if (IS_ERR(cdv_backlight_device))
- return PTR_ERR(cdv_backlight_device);
-
- ret = cdv_backlight_setup(dev);
- if (ret < 0) {
- backlight_device_unregister(cdv_backlight_device);
- cdv_backlight_device = NULL;
- return ret;
- }
- cdv_backlight_device->props.brightness = 100;
- cdv_backlight_device->props.max_brightness = 100;
- backlight_update_status(cdv_backlight_device);
- dev_priv->backlight_device = cdv_backlight_device;
- return 0;
-}
-
-#endif
-
-/*
- * Provide the Cedarview specific chip logic and low level methods
- * for power management
- *
- * FIXME: we need to implement the apm/ospm base management bits
- * for this and the MID devices.
- */
-
-static inline u32 CDV_MSG_READ32(uint port, uint offset)
-{
- int mcr = (0x10<<24) | (port << 16) | (offset << 8);
- uint32_t ret_val = 0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
- pci_write_config_dword(pci_root, 0xD0, mcr);
- pci_read_config_dword(pci_root, 0xD4, &ret_val);
- pci_dev_put(pci_root);
- return ret_val;
-}
-
-static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value)
-{
- int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
- pci_write_config_dword(pci_root, 0xD4, value);
- pci_write_config_dword(pci_root, 0xD0, mcr);
- pci_dev_put(pci_root);
-}
-
-#define PSB_APM_CMD 0x0
-#define PSB_APM_STS 0x04
-#define PSB_PM_SSC 0x20
-#define PSB_PM_SSS 0x30
-#define PSB_PWRGT_GFX_MASK 0x3
-#define CDV_PWRGT_DISPLAY_CNTR 0x000fc00c
-#define CDV_PWRGT_DISPLAY_STS 0x000fc00c
-
-static void cdv_init_pm(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 pwr_cnt;
- int i;
-
- dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
- PSB_APMBA) & 0xFFFF;
- dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
- PSB_OSPMBA) & 0xFFFF;
-
- /* Force power on for now */
- pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
- pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
-
- outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
- for (i = 0; i < 5; i++) {
- u32 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
- if ((pwr_sts & PSB_PWRGT_GFX_MASK) == 0)
- break;
- udelay(10);
- }
- pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
- pwr_cnt &= ~CDV_PWRGT_DISPLAY_CNTR;
- outl(pwr_cnt, dev_priv->ospm_base + PSB_PM_SSC);
- for (i = 0; i < 5; i++) {
- u32 pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
- if ((pwr_sts & CDV_PWRGT_DISPLAY_STS) == 0)
- break;
- udelay(10);
- }
-}
-
-/**
- * cdv_save_display_registers - save registers lost on suspend
- * @dev: our DRM device
- *
- * Save the state we need in order to be able to restore the interface
- * upon resume from suspend
- *
- * FIXME: review
- */
-static int cdv_save_display_registers(struct drm_device *dev)
-{
- return 0;
-}
-
-/**
- * cdv_restore_display_registers - restore lost register state
- * @dev: our DRM device
- *
- * Restore register state that was lost during suspend and resume.
- *
- * FIXME: review
- */
-static int cdv_restore_display_registers(struct drm_device *dev)
-{
- return 0;
-}
-
-static int cdv_power_down(struct drm_device *dev)
-{
- return 0;
-}
-
-static int cdv_power_up(struct drm_device *dev)
-{
- return 0;
-}
-
-/* FIXME ? - shared with Poulsbo */
-static void cdv_get_core_freq(struct drm_device *dev)
-{
- uint32_t clock;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
- pci_read_config_dword(pci_root, 0xD4, &clock);
- pci_dev_put(pci_root);
-
- switch (clock & 0x07) {
- case 0:
- dev_priv->core_freq = 100;
- break;
- case 1:
- dev_priv->core_freq = 133;
- break;
- case 2:
- dev_priv->core_freq = 150;
- break;
- case 3:
- dev_priv->core_freq = 178;
- break;
- case 4:
- dev_priv->core_freq = 200;
- break;
- case 5:
- case 6:
- case 7:
- dev_priv->core_freq = 266;
- default:
- dev_priv->core_freq = 0;
- }
-}
-
-static int cdv_chip_setup(struct drm_device *dev)
-{
- cdv_get_core_freq(dev);
- gma_intel_opregion_init(dev);
- psb_intel_init_bios(dev);
- return 0;
-}
-
-/* CDV is much like Poulsbo but has MID like SGX offsets and PM */
-
-const struct psb_ops cdv_chip_ops = {
- .name = "Cedartrail",
- .accel_2d = 0,
- .pipes = 2,
- .sgx_offset = MRST_SGX_OFFSET,
- .chip_setup = cdv_chip_setup,
-
- .crtc_helper = &cdv_intel_helper_funcs,
- .crtc_funcs = &cdv_intel_crtc_funcs,
-
- .output_init = cdv_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- .backlight_init = cdv_backlight_init,
-#endif
-
- .init_pm = cdv_init_pm,
- .save_regs = cdv_save_display_registers,
- .restore_regs = cdv_restore_display_registers,
- .power_down = cdv_power_down,
- .power_up = cdv_power_up,
-};
diff --git a/drivers/staging/gma500/cdv_device.h b/drivers/staging/gma500/cdv_device.h
deleted file mode 100644
index 2a88b7beb551..000000000000
--- a/drivers/staging/gma500/cdv_device.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright © 2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-extern const struct drm_crtc_helper_funcs cdv_intel_helper_funcs;
-extern const struct drm_crtc_funcs cdv_intel_crtc_funcs;
-extern void cdv_intel_crt_init(struct drm_device *dev,
- struct psb_intel_mode_device *mode_dev);
-extern void cdv_intel_lvds_init(struct drm_device *dev,
- struct psb_intel_mode_device *mode_dev);
-extern void cdv_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev,
- int reg);
-extern struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
- struct drm_crtc *crtc);
-
-extern inline void cdv_intel_wait_for_vblank(struct drm_device *dev)
-{
- /* Wait for 20ms, i.e. one cycle at 50hz. */
- /* FIXME: msleep ?? */
- mdelay(20);
-}
-
-
diff --git a/drivers/staging/gma500/cdv_intel_crt.c b/drivers/staging/gma500/cdv_intel_crt.c
deleted file mode 100644
index efda63b97b45..000000000000
--- a/drivers/staging/gma500/cdv_intel_crt.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright © 2006-2007 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt
- */
-
-#include
-#include
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include
-
-
-static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
-{
- struct drm_device *dev = encoder->dev;
- u32 temp, reg;
- reg = ADPA;
-
- temp = REG_READ(reg);
- temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
- temp &= ~ADPA_DAC_ENABLE;
-
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- temp |= ADPA_DAC_ENABLE;
- break;
- case DRM_MODE_DPMS_STANDBY:
- temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
- break;
- case DRM_MODE_DPMS_SUSPEND:
- temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
- break;
- case DRM_MODE_DPMS_OFF:
- temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
- break;
- }
-
- REG_WRITE(reg, temp);
-}
-
-static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- int max_clock = 0;
- if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
- return MODE_NO_DBLESCAN;
-
- /* The lowest clock for CDV is 20000KHz */
- if (mode->clock < 20000)
- return MODE_CLOCK_LOW;
-
- /* The max clock for CDV is 355 instead of 400 */
- max_clock = 355000;
- if (mode->clock > max_clock)
- return MODE_CLOCK_HIGH;
-
- if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
- return MODE_PANEL;
-
- return MODE_OK;
-}
-
-static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return true;
-}
-
-static void cdv_intel_crt_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
-
- struct drm_device *dev = encoder->dev;
- struct drm_crtc *crtc = encoder->crtc;
- struct psb_intel_crtc *psb_intel_crtc =
- to_psb_intel_crtc(crtc);
- int dpll_md_reg;
- u32 adpa, dpll_md;
- u32 adpa_reg;
-
- if (psb_intel_crtc->pipe == 0)
- dpll_md_reg = DPLL_A_MD;
- else
- dpll_md_reg = DPLL_B_MD;
-
- adpa_reg = ADPA;
-
- /*
- * Disable separate mode multiplier used when cloning SDVO to CRT
- * XXX this needs to be adjusted when we really are cloning
- */
- {
- dpll_md = REG_READ(dpll_md_reg);
- REG_WRITE(dpll_md_reg,
- dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
- }
-
- adpa = 0;
- if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
- adpa |= ADPA_HSYNC_ACTIVE_HIGH;
- if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
- adpa |= ADPA_VSYNC_ACTIVE_HIGH;
-
- if (psb_intel_crtc->pipe == 0)
- adpa |= ADPA_PIPE_A_SELECT;
- else
- adpa |= ADPA_PIPE_B_SELECT;
-
- REG_WRITE(adpa_reg, adpa);
-}
-
-
-/**
- * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
- *
- * \return true if CRT is connected.
- * \return false if CRT is disconnected.
- */
-static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector,
- bool force)
-{
- struct drm_device *dev = connector->dev;
- u32 hotplug_en;
- int i, tries = 0, ret = false;
- u32 adpa_orig;
-
- /* disable the DAC when doing the hotplug detection */
-
- adpa_orig = REG_READ(ADPA);
-
- REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE));
-
- /*
- * On a CDV thep, CRT detect sequence need to be done twice
- * to get a reliable result.
- */
- tries = 2;
-
- hotplug_en = REG_READ(PORT_HOTPLUG_EN);
- hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
- hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
-
- hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
- hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
-
- for (i = 0; i < tries ; i++) {
- unsigned long timeout;
- /* turn on the FORCE_DETECT */
- REG_WRITE(PORT_HOTPLUG_EN, hotplug_en);
- timeout = jiffies + msecs_to_jiffies(1000);
- /* wait for FORCE_DETECT to go off */
- do {
- if (!(REG_READ(PORT_HOTPLUG_EN) &
- CRT_HOTPLUG_FORCE_DETECT))
- break;
- msleep(1);
- } while (time_after(timeout, jiffies));
- }
-
- if ((REG_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
- CRT_HOTPLUG_MONITOR_NONE)
- ret = true;
-
- /* Restore the saved ADPA */
- REG_WRITE(ADPA, adpa_orig);
- return ret;
-}
-
-static enum drm_connector_status cdv_intel_crt_detect(
- struct drm_connector *connector, bool force)
-{
- if (cdv_intel_crt_detect_hotplug(connector, force))
- return connector_status_connected;
- else
- return connector_status_disconnected;
-}
-
-static void cdv_intel_crt_destroy(struct drm_connector *connector)
-{
- struct psb_intel_output *intel_output = to_psb_intel_output(connector);
-
- psb_intel_i2c_destroy(intel_output->ddc_bus);
- drm_sysfs_connector_remove(connector);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
-
-static int cdv_intel_crt_get_modes(struct drm_connector *connector)
-{
- struct psb_intel_output *intel_output =
- to_psb_intel_output(connector);
- return psb_intel_ddc_get_modes(intel_output);
-}
-
-static int cdv_intel_crt_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t value)
-{
- return 0;
-}
-
-/*
- * Routines for controlling stuff on the analog port
- */
-
-static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = {
- .dpms = cdv_intel_crt_dpms,
- .mode_fixup = cdv_intel_crt_mode_fixup,
- .prepare = psb_intel_encoder_prepare,
- .commit = psb_intel_encoder_commit,
- .mode_set = cdv_intel_crt_mode_set,
-};
-
-static const struct drm_connector_funcs cdv_intel_crt_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
- .detect = cdv_intel_crt_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = cdv_intel_crt_destroy,
- .set_property = cdv_intel_crt_set_property,
-};
-
-static const struct drm_connector_helper_funcs
- cdv_intel_crt_connector_helper_funcs = {
- .mode_valid = cdv_intel_crt_mode_valid,
- .get_modes = cdv_intel_crt_get_modes,
- .best_encoder = psb_intel_best_encoder,
-};
-
-static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder)
-{
- drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs cdv_intel_crt_enc_funcs = {
- .destroy = cdv_intel_crt_enc_destroy,
-};
-
-void cdv_intel_crt_init(struct drm_device *dev,
- struct psb_intel_mode_device *mode_dev)
-{
-
- struct psb_intel_output *psb_intel_output;
- struct drm_connector *connector;
- struct drm_encoder *encoder;
-
- u32 i2c_reg;
-
- psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
- if (!psb_intel_output)
- return;
-
- psb_intel_output->mode_dev = mode_dev;
- connector = &psb_intel_output->base;
- drm_connector_init(dev, connector,
- &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
-
- encoder = &psb_intel_output->enc;
- drm_encoder_init(dev, encoder,
- &cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
-
- drm_mode_connector_attach_encoder(&psb_intel_output->base,
- &psb_intel_output->enc);
-
- /* Set up the DDC bus. */
- i2c_reg = GPIOA;
- /* Remove the following code for CDV */
- /*
- if (dev_priv->crt_ddc_bus != 0)
- i2c_reg = dev_priv->crt_ddc_bus;
- }*/
- psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
- i2c_reg, "CRTDDC_A");
- if (!psb_intel_output->ddc_bus) {
- dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
- "failed.\n");
- goto failed_ddc;
- }
-
- psb_intel_output->type = INTEL_OUTPUT_ANALOG;
- /*
- psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT);
- psb_intel_output->crtc_mask = (1 << 0) | (1 << 1);
- */
- connector->interlace_allowed = 0;
- connector->doublescan_allowed = 0;
-
- drm_encoder_helper_add(encoder, &cdv_intel_crt_helper_funcs);
- drm_connector_helper_add(connector,
- &cdv_intel_crt_connector_helper_funcs);
-
- drm_sysfs_connector_add(connector);
-
- return;
-failed_ddc:
- drm_encoder_cleanup(&psb_intel_output->enc);
- drm_connector_cleanup(&psb_intel_output->base);
- kfree(psb_intel_output);
- return;
-}
diff --git a/drivers/staging/gma500/cdv_intel_display.c b/drivers/staging/gma500/cdv_intel_display.c
deleted file mode 100644
index c63a32776a9e..000000000000
--- a/drivers/staging/gma500/cdv_intel_display.c
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt
- */
-
-#include
-#include
-
-#include
-#include "framebuffer.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_display.h"
-#include "power.h"
-#include "cdv_device.h"
-
-
-struct cdv_intel_range_t {
- int min, max;
-};
-
-struct cdv_intel_p2_t {
- int dot_limit;
- int p2_slow, p2_fast;
-};
-
-struct cdv_intel_clock_t {
- /* given values */
- int n;
- int m1, m2;
- int p1, p2;
- /* derived values */
- int dot;
- int vco;
- int m;
- int p;
-};
-
-#define INTEL_P2_NUM 2
-
-struct cdv_intel_limit_t {
- struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1;
- struct cdv_intel_p2_t p2;
-};
-
-#define CDV_LIMIT_SINGLE_LVDS_96 0
-#define CDV_LIMIT_SINGLE_LVDS_100 1
-#define CDV_LIMIT_DAC_HDMI_27 2
-#define CDV_LIMIT_DAC_HDMI_96 3
-
-static const struct cdv_intel_limit_t cdv_intel_limits[] = {
- { /* CDV_SIGNLE_LVDS_96MHz */
- .dot = {.min = 20000, .max = 115500},
- .vco = {.min = 1800000, .max = 3600000},
- .n = {.min = 2, .max = 6},
- .m = {.min = 60, .max = 160},
- .m1 = {.min = 0, .max = 0},
- .m2 = {.min = 58, .max = 158},
- .p = {.min = 28, .max = 140},
- .p1 = {.min = 2, .max = 10},
- .p2 = {.dot_limit = 200000,
- .p2_slow = 14, .p2_fast = 14},
- },
- { /* CDV_SINGLE_LVDS_100MHz */
- .dot = {.min = 20000, .max = 115500},
- .vco = {.min = 1800000, .max = 3600000},
- .n = {.min = 2, .max = 6},
- .m = {.min = 60, .max = 160},
- .m1 = {.min = 0, .max = 0},
- .m2 = {.min = 58, .max = 158},
- .p = {.min = 28, .max = 140},
- .p1 = {.min = 2, .max = 10},
- /* The single-channel range is 25-112Mhz, and dual-channel
- * is 80-224Mhz. Prefer single channel as much as possible.
- */
- .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14},
- },
- { /* CDV_DAC_HDMI_27MHz */
- .dot = {.min = 20000, .max = 400000},
- .vco = {.min = 1809000, .max = 3564000},
- .n = {.min = 1, .max = 1},
- .m = {.min = 67, .max = 132},
- .m1 = {.min = 0, .max = 0},
- .m2 = {.min = 65, .max = 130},
- .p = {.min = 5, .max = 90},
- .p1 = {.min = 1, .max = 9},
- .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
- },
- { /* CDV_DAC_HDMI_96MHz */
- .dot = {.min = 20000, .max = 400000},
- .vco = {.min = 1800000, .max = 3600000},
- .n = {.min = 2, .max = 6},
- .m = {.min = 60, .max = 160},
- .m1 = {.min = 0, .max = 0},
- .m2 = {.min = 58, .max = 158},
- .p = {.min = 5, .max = 100},
- .p1 = {.min = 1, .max = 10},
- .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
- },
-};
-
-#define _wait_for(COND, MS, W) ({ \
- unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
- int ret__ = 0; \
- while (!(COND)) { \
- if (time_after(jiffies, timeout__)) { \
- ret__ = -ETIMEDOUT; \
- break; \
- } \
- if (W && !in_dbg_master()) \
- msleep(W); \
- } \
- ret__; \
-})
-
-#define wait_for(COND, MS) _wait_for(COND, MS, 1)
-
-
-static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
-{
- int ret;
-
- ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
- if (ret) {
- DRM_ERROR("timeout waiting for SB to idle before read\n");
- return ret;
- }
-
- REG_WRITE(SB_ADDR, reg);
- REG_WRITE(SB_PCKT,
- SET_FIELD(SB_OPCODE_READ, SB_OPCODE) |
- SET_FIELD(SB_DEST_DPLL, SB_DEST) |
- SET_FIELD(0xf, SB_BYTE_ENABLE));
-
- ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
- if (ret) {
- DRM_ERROR("timeout waiting for SB to idle after read\n");
- return ret;
- }
-
- *val = REG_READ(SB_DATA);
-
- return 0;
-}
-
-static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
-{
- int ret;
- static bool dpio_debug = true;
- u32 temp;
-
- if (dpio_debug) {
- if (cdv_sb_read(dev, reg, &temp) == 0)
- DRM_DEBUG_KMS("0x%08x: 0x%08x (before)\n", reg, temp);
- DRM_DEBUG_KMS("0x%08x: 0x%08x\n", reg, val);
- }
-
- ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
- if (ret) {
- DRM_ERROR("timeout waiting for SB to idle before write\n");
- return ret;
- }
-
- REG_WRITE(SB_ADDR, reg);
- REG_WRITE(SB_DATA, val);
- REG_WRITE(SB_PCKT,
- SET_FIELD(SB_OPCODE_WRITE, SB_OPCODE) |
- SET_FIELD(SB_DEST_DPLL, SB_DEST) |
- SET_FIELD(0xf, SB_BYTE_ENABLE));
-
- ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
- if (ret) {
- DRM_ERROR("timeout waiting for SB to idle after write\n");
- return ret;
- }
-
- if (dpio_debug) {
- if (cdv_sb_read(dev, reg, &temp) == 0)
- DRM_DEBUG_KMS("0x%08x: 0x%08x (after)\n", reg, temp);
- }
-
- return 0;
-}
-
-/* Reset the DPIO configuration register. The BIOS does this at every
- * mode set.
- */
-static void cdv_sb_reset(struct drm_device *dev)
-{
-
- REG_WRITE(DPIO_CFG, 0);
- REG_READ(DPIO_CFG);
- REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N);
-}
-
-/* Unlike most Intel display engines, on Cedarview the DPLL registers
- * are behind this sideband bus. They must be programmed while the
- * DPLL reference clock is on in the DPLL control register, but before
- * the DPLL is enabled in the DPLL control register.
- */
-static int
-cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
- struct cdv_intel_clock_t *clock)
-{
- struct psb_intel_crtc *psb_crtc =
- to_psb_intel_crtc(crtc);
- int pipe = psb_crtc->pipe;
- u32 m, n_vco, p;
- int ret = 0;
- int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
- u32 ref_value;
-
- cdv_sb_reset(dev);
-
- if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) {
- DRM_ERROR("Attempting to set DPLL with refclk disabled\n");
- return -EBUSY;
- }
-
- /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */
- ref_value = 0x68A701;
-
- cdv_sb_write(dev, SB_REF_SFR(pipe), ref_value);
-
- /* We don't know what the other fields of these regs are, so
- * leave them in place.
- */
- ret = cdv_sb_read(dev, SB_M(pipe), &m);
- if (ret)
- return ret;
- m &= ~SB_M_DIVIDER_MASK;
- m |= ((clock->m2) << SB_M_DIVIDER_SHIFT);
- ret = cdv_sb_write(dev, SB_M(pipe), m);
- if (ret)
- return ret;
-
- ret = cdv_sb_read(dev, SB_N_VCO(pipe), &n_vco);
- if (ret)
- return ret;
-
- /* Follow the BIOS to program the N_DIVIDER REG */
- n_vco &= 0xFFFF;
- n_vco |= 0x107;
- n_vco &= ~(SB_N_VCO_SEL_MASK |
- SB_N_DIVIDER_MASK |
- SB_N_CB_TUNE_MASK);
-
- n_vco |= ((clock->n) << SB_N_DIVIDER_SHIFT);
-
- if (clock->vco < 2250000) {
- n_vco |= (2 << SB_N_CB_TUNE_SHIFT);
- n_vco |= (0 << SB_N_VCO_SEL_SHIFT);
- } else if (clock->vco < 2750000) {
- n_vco |= (1 << SB_N_CB_TUNE_SHIFT);
- n_vco |= (1 << SB_N_VCO_SEL_SHIFT);
- } else if (clock->vco < 3300000) {
- n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
- n_vco |= (2 << SB_N_VCO_SEL_SHIFT);
- } else {
- n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
- n_vco |= (3 << SB_N_VCO_SEL_SHIFT);
- }
-
- ret = cdv_sb_write(dev, SB_N_VCO(pipe), n_vco);
- if (ret)
- return ret;
-
- ret = cdv_sb_read(dev, SB_P(pipe), &p);
- if (ret)
- return ret;
- p &= ~(SB_P2_DIVIDER_MASK | SB_P1_DIVIDER_MASK);
- p |= SET_FIELD(clock->p1, SB_P1_DIVIDER);
- switch (clock->p2) {
- case 5:
- p |= SET_FIELD(SB_P2_5, SB_P2_DIVIDER);
- break;
- case 10:
- p |= SET_FIELD(SB_P2_10, SB_P2_DIVIDER);
- break;
- case 14:
- p |= SET_FIELD(SB_P2_14, SB_P2_DIVIDER);
- break;
- case 7:
- p |= SET_FIELD(SB_P2_7, SB_P2_DIVIDER);
- break;
- default:
- DRM_ERROR("Bad P2 clock: %d\n", clock->p2);
- return -EINVAL;
- }
- ret = cdv_sb_write(dev, SB_P(pipe), p);
- if (ret)
- return ret;
-
- /* always Program the Lane Register for the Pipe A*/
- if (pipe == 0) {
- /* Program the Lane0/1 for HDMI B */
- u32 lane_reg, lane_value;
-
- lane_reg = PSB_LANE0;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE;
- cdv_sb_write(dev, lane_reg, lane_value);
-
- lane_reg = PSB_LANE1;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE;
- cdv_sb_write(dev, lane_reg, lane_value);
-
- /* Program the Lane2/3 for HDMI C */
- lane_reg = PSB_LANE2;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE;
- cdv_sb_write(dev, lane_reg, lane_value);
-
- lane_reg = PSB_LANE3;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE;
- cdv_sb_write(dev, lane_reg, lane_value);
- }
-
- return 0;
-}
-
-/*
- * Returns whether any output on the specified pipe is of the specified type
- */
-bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_mode_config *mode_config = &dev->mode_config;
- struct drm_connector *l_entry;
-
- list_for_each_entry(l_entry, &mode_config->connector_list, head) {
- if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(l_entry);
- if (psb_intel_output->type == type)
- return true;
- }
- }
- return false;
-}
-
-static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
- int refclk)
-{
- const struct cdv_intel_limit_t *limit;
- if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
- /*
- * Now only single-channel LVDS is supported on CDV. If it is
- * incorrect, please add the dual-channel LVDS.
- */
- if (refclk == 96000)
- limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
- else
- limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
- } else {
- if (refclk == 27000)
- limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
- else
- limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_96];
- }
- return limit;
-}
-
-/* m1 is reserved as 0 in CDV, n is a ring counter */
-static void cdv_intel_clock(struct drm_device *dev,
- int refclk, struct cdv_intel_clock_t *clock)
-{
- clock->m = clock->m2 + 2;
- clock->p = clock->p1 * clock->p2;
- clock->vco = (refclk * clock->m) / clock->n;
- clock->dot = clock->vco / clock->p;
-}
-
-
-#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
-static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc,
- const struct cdv_intel_limit_t *limit,
- struct cdv_intel_clock_t *clock)
-{
- if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
- INTELPllInvalid("p1 out of range\n");
- if (clock->p < limit->p.min || limit->p.max < clock->p)
- INTELPllInvalid("p out of range\n");
- /* unnecessary to check the range of m(m1/M2)/n again */
- if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
- INTELPllInvalid("vco out of range\n");
- /* XXX: We may need to be checking "Dot clock"
- * depending on the multiplier, connector, etc.,
- * rather than just a single range.
- */
- if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
- INTELPllInvalid("dot out of range\n");
-
- return true;
-}
-
-static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
- int refclk,
- struct cdv_intel_clock_t *best_clock)
-{
- struct drm_device *dev = crtc->dev;
- struct cdv_intel_clock_t clock;
- const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk);
- int err = target;
-
-
- if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
- (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
- /*
- * For LVDS, if the panel is on, just rely on its current
- * settings for dual-channel. We haven't figured out how to
- * reliably set up different single/dual channel state, if we
- * even can.
- */
- if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
- LVDS_CLKB_POWER_UP)
- clock.p2 = limit->p2.p2_fast;
- else
- clock.p2 = limit->p2.p2_slow;
- } else {
- if (target < limit->p2.dot_limit)
- clock.p2 = limit->p2.p2_slow;
- else
- clock.p2 = limit->p2.p2_fast;
- }
-
- memset(best_clock, 0, sizeof(*best_clock));
- clock.m1 = 0;
- /* m1 is reserved as 0 in CDV, n is a ring counter.
- So skip the m1 loop */
- for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
- for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max;
- clock.m2++) {
- for (clock.p1 = limit->p1.min;
- clock.p1 <= limit->p1.max;
- clock.p1++) {
- int this_err;
-
- cdv_intel_clock(dev, refclk, &clock);
-
- if (!cdv_intel_PLL_is_valid(crtc,
- limit, &clock))
- continue;
-
- this_err = abs(clock.dot - target);
- if (this_err < err) {
- *best_clock = clock;
- err = this_err;
- }
- }
- }
- }
-
- return err != target;
-}
-
-int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
- int x, int y, struct drm_framebuffer *old_fb)
-{
- struct drm_device *dev = crtc->dev;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
- int pipe = psb_intel_crtc->pipe;
- unsigned long start, offset;
- int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
- int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
- int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
- u32 dspcntr;
- int ret = 0;
-
- if (!gma_power_begin(dev, true))
- return 0;
-
- /* no fb bound */
- if (!crtc->fb) {
- dev_err(dev->dev, "No FB bound\n");
- goto psb_intel_pipe_cleaner;
- }
-
-
- /* We are displaying this buffer, make sure it is actually loaded
- into the GTT */
- ret = psb_gtt_pin(psbfb->gtt);
- if (ret < 0)
- goto psb_intel_pipe_set_base_exit;
- start = psbfb->gtt->offset;
- offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
- REG_WRITE(dspstride, crtc->fb->pitches[0]);
-
- dspcntr = REG_READ(dspcntr_reg);
- dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
- switch (crtc->fb->bits_per_pixel) {
- case 8:
- dspcntr |= DISPPLANE_8BPP;
- break;
- case 16:
- if (crtc->fb->depth == 15)
- dspcntr |= DISPPLANE_15_16BPP;
- else
- dspcntr |= DISPPLANE_16BPP;
- break;
- case 24:
- case 32:
- dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
- break;
- default:
- dev_err(dev->dev, "Unknown color depth\n");
- ret = -EINVAL;
- goto psb_intel_pipe_set_base_exit;
- }
- REG_WRITE(dspcntr_reg, dspcntr);
-
- dev_dbg(dev->dev,
- "Writing base %08lX %08lX %d %d\n", start, offset, x, y);
-
- REG_WRITE(dspbase, offset);
- REG_READ(dspbase);
- REG_WRITE(dspsurf, start);
- REG_READ(dspsurf);
-
-psb_intel_pipe_cleaner:
- /* If there was a previous display we can now unpin it */
- if (old_fb)
- psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
- gma_power_end(dev);
- return ret;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct drm_device *dev = crtc->dev;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
- int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
- int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
- u32 temp;
- bool enabled;
-
- /* XXX: When our outputs are all unaware of DPMS modes other than off
- * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
- */
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- /* Enable the DPLL */
- temp = REG_READ(dpll_reg);
- if ((temp & DPLL_VCO_ENABLE) == 0) {
- REG_WRITE(dpll_reg, temp);
- REG_READ(dpll_reg);
- /* Wait for the clocks to stabilize. */
- udelay(150);
- REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
- REG_READ(dpll_reg);
- /* Wait for the clocks to stabilize. */
- udelay(150);
- REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
- REG_READ(dpll_reg);
- /* Wait for the clocks to stabilize. */
- udelay(150);
- }
-
- /* Jim Bish - switch plan and pipe per scott */
- /* Enable the plane */
- temp = REG_READ(dspcntr_reg);
- if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
- REG_WRITE(dspcntr_reg,
- temp | DISPLAY_PLANE_ENABLE);
- /* Flush the plane changes */
- REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
- }
-
- udelay(150);
-
- /* Enable the pipe */
- temp = REG_READ(pipeconf_reg);
- if ((temp & PIPEACONF_ENABLE) == 0)
- REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-
- psb_intel_crtc_load_lut(crtc);
-
- /* Give the overlay scaler a chance to enable
- * if it's on this pipe */
- /* psb_intel_crtc_dpms_video(crtc, true); TODO */
- break;
- case DRM_MODE_DPMS_OFF:
- /* Give the overlay scaler a chance to disable
- * if it's on this pipe */
- /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-
- /* Disable the VGA plane that we never use */
- REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
- /* Jim Bish - changed pipe/plane here as well. */
-
- /* Wait for vblank for the disable to take effect */
- cdv_intel_wait_for_vblank(dev);
-
- /* Next, disable display pipes */
- temp = REG_READ(pipeconf_reg);
- if ((temp & PIPEACONF_ENABLE) != 0) {
- REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
- REG_READ(pipeconf_reg);
- }
-
- /* Wait for vblank for the disable to take effect. */
- cdv_intel_wait_for_vblank(dev);
-
- udelay(150);
-
- /* Disable display plane */
- temp = REG_READ(dspcntr_reg);
- if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
- REG_WRITE(dspcntr_reg,
- temp & ~DISPLAY_PLANE_ENABLE);
- /* Flush the plane changes */
- REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
- REG_READ(dspbase_reg);
- }
-
- temp = REG_READ(dpll_reg);
- if ((temp & DPLL_VCO_ENABLE) != 0) {
- REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
- REG_READ(dpll_reg);
- }
-
- /* Wait for the clocks to turn off. */
- udelay(150);
- break;
- }
- enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
- /*Set FIFO Watermarks*/
- REG_WRITE(DSPARB, 0x3F3E);
-}
-
-static void cdv_intel_crtc_prepare(struct drm_crtc *crtc)
-{
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void cdv_intel_crtc_commit(struct drm_crtc *crtc)
-{
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-void cdv_intel_encoder_prepare(struct drm_encoder *encoder)
-{
- struct drm_encoder_helper_funcs *encoder_funcs =
- encoder->helper_private;
- /* lvds has its own version of prepare see cdv_intel_lvds_prepare */
- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-void cdv_intel_encoder_commit(struct drm_encoder *encoder)
-{
- struct drm_encoder_helper_funcs *encoder_funcs =
- encoder->helper_private;
- /* lvds has its own version of commit see cdv_intel_lvds_commit */
- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return true;
-}
-
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int cdv_intel_panel_fitter_pipe(struct drm_device *dev)
-{
- u32 pfit_control;
-
- pfit_control = REG_READ(PFIT_CONTROL);
-
- /* See if the panel fitter is in use */
- if ((pfit_control & PFIT_ENABLE) == 0)
- return -1;
- return (pfit_control >> 29) & 0x3;
-}
-
-static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y,
- struct drm_framebuffer *old_fb)
-{
- struct drm_device *dev = crtc->dev;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
- int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
- int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
- int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
- int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
- int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
- int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
- int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
- int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
- int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
- int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
- int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
- int refclk;
- struct cdv_intel_clock_t clock;
- u32 dpll = 0, dspcntr, pipeconf;
- bool ok, is_sdvo = false, is_dvo = false;
- bool is_crt = false, is_lvds = false, is_tv = false;
- bool is_hdmi = false;
- struct drm_mode_config *mode_config = &dev->mode_config;
- struct drm_connector *connector;
-
- list_for_each_entry(connector, &mode_config->connector_list, head) {
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
-
- if (!connector->encoder
- || connector->encoder->crtc != crtc)
- continue;
-
- switch (psb_intel_output->type) {
- case INTEL_OUTPUT_LVDS:
- is_lvds = true;
- break;
- case INTEL_OUTPUT_SDVO:
- is_sdvo = true;
- break;
- case INTEL_OUTPUT_DVO:
- is_dvo = true;
- break;
- case INTEL_OUTPUT_TVOUT:
- is_tv = true;
- break;
- case INTEL_OUTPUT_ANALOG:
- is_crt = true;
- break;
- case INTEL_OUTPUT_HDMI:
- is_hdmi = true;
- break;
- }
- }
-
- refclk = 96000;
-
- /* Hack selection about ref clk for CRT */
- /* Select 27MHz as the reference clk for HDMI */
- if (is_crt || is_hdmi)
- refclk = 27000;
-
- drm_mode_debug_printmodeline(adjusted_mode);
-
- ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
- &clock);
- if (!ok) {
- dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
- return 0;
- }
-
- dpll = DPLL_VGA_MODE_DIS;
- if (is_tv) {
- /* XXX: just matching BIOS for now */
-/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
- dpll |= 3;
- }
- dpll |= PLL_REF_INPUT_DREFCLK;
-
- dpll |= DPLL_SYNCLOCK_ENABLE;
- dpll |= DPLL_VGA_MODE_DIS;
- if (is_lvds)
- dpll |= DPLLB_MODE_LVDS;
- else
- dpll |= DPLLB_MODE_DAC_SERIAL;
- /* dpll |= (2 << 11); */
-
- /* setup pipeconf */
- pipeconf = REG_READ(pipeconf_reg);
-
- /* Set up the display plane register */
- dspcntr = DISPPLANE_GAMMA_ENABLE;
-
- if (pipe == 0)
- dspcntr |= DISPPLANE_SEL_PIPE_A;
- else
- dspcntr |= DISPPLANE_SEL_PIPE_B;
-
- dspcntr |= DISPLAY_PLANE_ENABLE;
- pipeconf |= PIPEACONF_ENABLE;
-
- REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE);
- REG_READ(dpll_reg);
-
- cdv_dpll_set_clock_cdv(dev, crtc, &clock);
-
- udelay(150);
-
-
- /* The LVDS pin pair needs to be on before the DPLLs are enabled.
- * This is an exception to the general rule that mode_set doesn't turn
- * things on.
- */
- if (is_lvds) {
- u32 lvds = REG_READ(LVDS);
-
- lvds |=
- LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
- LVDS_PIPEB_SELECT;
- /* Set the B0-B3 data pairs corresponding to
- * whether we're going to
- * set the DPLLs for dual-channel mode or not.
- */
- if (clock.p2 == 7)
- lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
- else
- lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
-
- /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
- * appropriately here, but we need to look more
- * thoroughly into how panels behave in the two modes.
- */
-
- REG_WRITE(LVDS, lvds);
- REG_READ(LVDS);
- }
-
- dpll |= DPLL_VCO_ENABLE;
-
- /* Disable the panel fitter if it was on our pipe */
- if (cdv_intel_panel_fitter_pipe(dev) == pipe)
- REG_WRITE(PFIT_CONTROL, 0);
-
- DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
- drm_mode_debug_printmodeline(mode);
-
- REG_WRITE(dpll_reg,
- (REG_READ(dpll_reg) & ~DPLL_LOCK) | DPLL_VCO_ENABLE);
- REG_READ(dpll_reg);
- /* Wait for the clocks to stabilize. */
- udelay(150); /* 42 usec w/o calibration, 110 with. rounded up. */
-
- if (!(REG_READ(dpll_reg) & DPLL_LOCK)) {
- dev_err(dev->dev, "Failed to get DPLL lock\n");
- return -EBUSY;
- }
-
- {
- int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
- REG_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
- }
-
- REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
- ((adjusted_mode->crtc_htotal - 1) << 16));
- REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
- ((adjusted_mode->crtc_hblank_end - 1) << 16));
- REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
- ((adjusted_mode->crtc_hsync_end - 1) << 16));
- REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
- ((adjusted_mode->crtc_vtotal - 1) << 16));
- REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
- ((adjusted_mode->crtc_vblank_end - 1) << 16));
- REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
- ((adjusted_mode->crtc_vsync_end - 1) << 16));
- /* pipesrc and dspsize control the size that is scaled from,
- * which should always be the user's requested size.
- */
- REG_WRITE(dspsize_reg,
- ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
- REG_WRITE(dsppos_reg, 0);
- REG_WRITE(pipesrc_reg,
- ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
- REG_WRITE(pipeconf_reg, pipeconf);
- REG_READ(pipeconf_reg);
-
- cdv_intel_wait_for_vblank(dev);
-
- REG_WRITE(dspcntr_reg, dspcntr);
-
- /* Flush the plane changes */
- {
- struct drm_crtc_helper_funcs *crtc_funcs =
- crtc->helper_private;
- crtc_funcs->mode_set_base(crtc, x, y, old_fb);
- }
-
- cdv_intel_wait_for_vblank(dev);
-
- return 0;
-}
-
-/** Loads the palette/gamma unit for the CRTC with the prepared values */
-void cdv_intel_crtc_load_lut(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *)dev->dev_private;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int palreg = PALETTE_A;
- int i;
-
- /* The clocks have to be on to load the palette. */
- if (!crtc->enabled)
- return;
-
- switch (psb_intel_crtc->pipe) {
- case 0:
- break;
- case 1:
- palreg = PALETTE_B;
- break;
- case 2:
- palreg = PALETTE_C;
- break;
- default:
- dev_err(dev->dev, "Illegal Pipe Number.\n");
- return;
- }
-
- if (gma_power_begin(dev, false)) {
- for (i = 0; i < 256; i++) {
- REG_WRITE(palreg + 4 * i,
- ((psb_intel_crtc->lut_r[i] +
- psb_intel_crtc->lut_adj[i]) << 16) |
- ((psb_intel_crtc->lut_g[i] +
- psb_intel_crtc->lut_adj[i]) << 8) |
- (psb_intel_crtc->lut_b[i] +
- psb_intel_crtc->lut_adj[i]));
- }
- gma_power_end(dev);
- } else {
- for (i = 0; i < 256; i++) {
- dev_priv->save_palette_a[i] =
- ((psb_intel_crtc->lut_r[i] +
- psb_intel_crtc->lut_adj[i]) << 16) |
- ((psb_intel_crtc->lut_g[i] +
- psb_intel_crtc->lut_adj[i]) << 8) |
- (psb_intel_crtc->lut_b[i] +
- psb_intel_crtc->lut_adj[i]);
- }
-
- }
-}
-
-/**
- * Save HW states of giving crtc
- */
-static void cdv_intel_crtc_save(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- /* struct drm_psb_private *dev_priv =
- (struct drm_psb_private *)dev->dev_private; */
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
- int pipeA = (psb_intel_crtc->pipe == 0);
- uint32_t paletteReg;
- int i;
-
- if (!crtc_state) {
- dev_dbg(dev->dev, "No CRTC state found\n");
- return;
- }
-
- crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
- crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
- crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
- crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
- crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
- crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
- crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
- crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
- crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
- crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
- crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
- crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
- crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
-
- /*NOTE: DSPSIZE DSPPOS only for psb*/
- crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
- crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
-
- crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
-
- DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
- crtc_state->saveDSPCNTR,
- crtc_state->savePIPECONF,
- crtc_state->savePIPESRC,
- crtc_state->saveFP0,
- crtc_state->saveFP1,
- crtc_state->saveDPLL,
- crtc_state->saveHTOTAL,
- crtc_state->saveHBLANK,
- crtc_state->saveHSYNC,
- crtc_state->saveVTOTAL,
- crtc_state->saveVBLANK,
- crtc_state->saveVSYNC,
- crtc_state->saveDSPSTRIDE,
- crtc_state->saveDSPSIZE,
- crtc_state->saveDSPPOS,
- crtc_state->saveDSPBASE
- );
-
- paletteReg = pipeA ? PALETTE_A : PALETTE_B;
- for (i = 0; i < 256; ++i)
- crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
-}
-
-/**
- * Restore HW states of giving crtc
- */
-static void cdv_intel_crtc_restore(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- /* struct drm_psb_private * dev_priv =
- (struct drm_psb_private *)dev->dev_private; */
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
- /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
- int pipeA = (psb_intel_crtc->pipe == 0);
- uint32_t paletteReg;
- int i;
-
- if (!crtc_state) {
- dev_dbg(dev->dev, "No crtc state\n");
- return;
- }
-
- DRM_DEBUG(
- "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
- REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
- REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
- REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
- REG_READ(pipeA ? FPA0 : FPB0),
- REG_READ(pipeA ? FPA1 : FPB1),
- REG_READ(pipeA ? DPLL_A : DPLL_B),
- REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
- REG_READ(pipeA ? HBLANK_A : HBLANK_B),
- REG_READ(pipeA ? HSYNC_A : HSYNC_B),
- REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
- REG_READ(pipeA ? VBLANK_A : VBLANK_B),
- REG_READ(pipeA ? VSYNC_A : VSYNC_B),
- REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
- REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
- REG_READ(pipeA ? DSPAPOS : DSPBPOS),
- REG_READ(pipeA ? DSPABASE : DSPBBASE)
- );
-
- DRM_DEBUG(
- "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
- crtc_state->saveDSPCNTR,
- crtc_state->savePIPECONF,
- crtc_state->savePIPESRC,
- crtc_state->saveFP0,
- crtc_state->saveFP1,
- crtc_state->saveDPLL,
- crtc_state->saveHTOTAL,
- crtc_state->saveHBLANK,
- crtc_state->saveHSYNC,
- crtc_state->saveVTOTAL,
- crtc_state->saveVBLANK,
- crtc_state->saveVSYNC,
- crtc_state->saveDSPSTRIDE,
- crtc_state->saveDSPSIZE,
- crtc_state->saveDSPPOS,
- crtc_state->saveDSPBASE
- );
-
-
- if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
- REG_WRITE(pipeA ? DPLL_A : DPLL_B,
- crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
- REG_READ(pipeA ? DPLL_A : DPLL_B);
- DRM_DEBUG("write dpll: %x\n",
- REG_READ(pipeA ? DPLL_A : DPLL_B));
- udelay(150);
- }
-
- REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
- REG_READ(pipeA ? FPA0 : FPB0);
-
- REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
- REG_READ(pipeA ? FPA1 : FPB1);
-
- REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
- REG_READ(pipeA ? DPLL_A : DPLL_B);
- udelay(150);
-
- REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
- REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
- REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
- REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
- REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
- REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
- REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
-
- REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
- REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
-
- REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
- REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
- REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
-
- cdv_intel_wait_for_vblank(dev);
-
- REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
- REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-
- cdv_intel_wait_for_vblank(dev);
-
- paletteReg = pipeA ? PALETTE_A : PALETTE_B;
- for (i = 0; i < 256; ++i)
- REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
-}
-
-static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
- struct drm_file *file_priv,
- uint32_t handle,
- uint32_t width, uint32_t height)
-{
- struct drm_device *dev = crtc->dev;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
- uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
- uint32_t temp;
- size_t addr = 0;
- struct gtt_range *gt;
- struct drm_gem_object *obj;
- int ret;
-
- /* if we want to turn of the cursor ignore width and height */
- if (!handle) {
- /* turn off the cursor */
- temp = CURSOR_MODE_DISABLE;
-
- if (gma_power_begin(dev, false)) {
- REG_WRITE(control, temp);
- REG_WRITE(base, 0);
- gma_power_end(dev);
- }
-
- /* unpin the old GEM object */
- if (psb_intel_crtc->cursor_obj) {
- gt = container_of(psb_intel_crtc->cursor_obj,
- struct gtt_range, gem);
- psb_gtt_unpin(gt);
- drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
- psb_intel_crtc->cursor_obj = NULL;
- }
-
- return 0;
- }
-
- /* Currently we only support 64x64 cursors */
- if (width != 64 || height != 64) {
- dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
- return -EINVAL;
- }
-
- obj = drm_gem_object_lookup(dev, file_priv, handle);
- if (!obj)
- return -ENOENT;
-
- if (obj->size < width * height * 4) {
- dev_dbg(dev->dev, "buffer is to small\n");
- return -ENOMEM;
- }
-
- gt = container_of(obj, struct gtt_range, gem);
-
- /* Pin the memory into the GTT */
- ret = psb_gtt_pin(gt);
- if (ret) {
- dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
- return ret;
- }
-
- addr = gt->offset; /* Or resource.start ??? */
-
- psb_intel_crtc->cursor_addr = addr;
-
- temp = 0;
- /* set the pipe for the cursor */
- temp |= (pipe << 28);
- temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
- if (gma_power_begin(dev, false)) {
- REG_WRITE(control, temp);
- REG_WRITE(base, addr);
- gma_power_end(dev);
- }
-
- /* unpin the old GEM object */
- if (psb_intel_crtc->cursor_obj) {
- gt = container_of(psb_intel_crtc->cursor_obj,
- struct gtt_range, gem);
- psb_gtt_unpin(gt);
- drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
- psb_intel_crtc->cursor_obj = obj;
- }
- return 0;
-}
-
-static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
- struct drm_device *dev = crtc->dev;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- uint32_t temp = 0;
- uint32_t adder;
-
-
- if (x < 0) {
- temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
- x = -x;
- }
- if (y < 0) {
- temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
- y = -y;
- }
-
- temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
- temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
- adder = psb_intel_crtc->cursor_addr;
-
- if (gma_power_begin(dev, false)) {
- REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
- REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
- gma_power_end(dev);
- }
- return 0;
-}
-
-static void cdv_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
- u16 *green, u16 *blue, uint32_t start, uint32_t size)
-{
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int i;
- int end = (start + size > 256) ? 256 : start + size;
-
- for (i = start; i < end; i++) {
- psb_intel_crtc->lut_r[i] = red[i] >> 8;
- psb_intel_crtc->lut_g[i] = green[i] >> 8;
- psb_intel_crtc->lut_b[i] = blue[i] >> 8;
- }
-
- cdv_intel_crtc_load_lut(crtc);
-}
-
-static int cdv_crtc_set_config(struct drm_mode_set *set)
-{
- int ret = 0;
- struct drm_device *dev = set->crtc->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (!dev_priv->rpm_enabled)
- return drm_crtc_helper_set_config(set);
-
- pm_runtime_forbid(&dev->pdev->dev);
-
- ret = drm_crtc_helper_set_config(set);
-
- pm_runtime_allow(&dev->pdev->dev);
-
- return ret;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-
-/* FIXME: why are we using this, should it be cdv_ in this tree ? */
-
-static void i8xx_clock(int refclk, struct cdv_intel_clock_t *clock)
-{
- clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
- clock->p = clock->p1 * clock->p2;
- clock->vco = refclk * clock->m / (clock->n + 2);
- clock->dot = clock->vco / clock->p;
-}
-
-/* Returns the clock of the currently programmed mode of the given pipe. */
-static int cdv_intel_crtc_clock_get(struct drm_device *dev,
- struct drm_crtc *crtc)
-{
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- u32 dpll;
- u32 fp;
- struct cdv_intel_clock_t clock;
- bool is_lvds;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (gma_power_begin(dev, false)) {
- dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
- if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
- fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
- else
- fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
- is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
- gma_power_end(dev);
- } else {
- dpll = (pipe == 0) ?
- dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
-
- if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
- fp = (pipe == 0) ?
- dev_priv->saveFPA0 :
- dev_priv->saveFPB0;
- else
- fp = (pipe == 0) ?
- dev_priv->saveFPA1 :
- dev_priv->saveFPB1;
-
- is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
- }
-
- clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
- clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
- clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
-
- if (is_lvds) {
- clock.p1 =
- ffs((dpll &
- DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
- DPLL_FPA01_P1_POST_DIV_SHIFT);
- if (clock.p1 == 0) {
- clock.p1 = 4;
- dev_err(dev->dev, "PLL %d\n", dpll);
- }
- clock.p2 = 14;
-
- if ((dpll & PLL_REF_INPUT_MASK) ==
- PLLB_REF_INPUT_SPREADSPECTRUMIN) {
- /* XXX: might not be 66MHz */
- i8xx_clock(66000, &clock);
- } else
- i8xx_clock(48000, &clock);
- } else {
- if (dpll & PLL_P1_DIVIDE_BY_TWO)
- clock.p1 = 2;
- else {
- clock.p1 =
- ((dpll &
- DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
- DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
- }
- if (dpll & PLL_P2_DIVIDE_BY_4)
- clock.p2 = 4;
- else
- clock.p2 = 2;
-
- i8xx_clock(48000, &clock);
- }
-
- /* XXX: It would be nice to validate the clocks, but we can't reuse
- * i830PllIsValid() because it relies on the xf86_config connector
- * configuration being accurate, which it isn't necessarily.
- */
-
- return clock.dot;
-}
-
-/** Returns the currently programmed mode of the given pipe. */
-struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
- struct drm_crtc *crtc)
-{
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- struct drm_display_mode *mode;
- int htot;
- int hsync;
- int vtot;
- int vsync;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (gma_power_begin(dev, false)) {
- htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
- hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
- vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
- vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
- gma_power_end(dev);
- } else {
- htot = (pipe == 0) ?
- dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
- hsync = (pipe == 0) ?
- dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
- vtot = (pipe == 0) ?
- dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
- vsync = (pipe == 0) ?
- dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
- }
-
- mode = kzalloc(sizeof(*mode), GFP_KERNEL);
- if (!mode)
- return NULL;
-
- mode->clock = cdv_intel_crtc_clock_get(dev, crtc);
- mode->hdisplay = (htot & 0xffff) + 1;
- mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
- mode->hsync_start = (hsync & 0xffff) + 1;
- mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
- mode->vdisplay = (vtot & 0xffff) + 1;
- mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
- mode->vsync_start = (vsync & 0xffff) + 1;
- mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
-
- drm_mode_set_name(mode);
- drm_mode_set_crtcinfo(mode, 0);
-
- return mode;
-}
-
-static void cdv_intel_crtc_destroy(struct drm_crtc *crtc)
-{
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-
- kfree(psb_intel_crtc->crtc_state);
- drm_crtc_cleanup(crtc);
- kfree(psb_intel_crtc);
-}
-
-const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
- .dpms = cdv_intel_crtc_dpms,
- .mode_fixup = cdv_intel_crtc_mode_fixup,
- .mode_set = cdv_intel_crtc_mode_set,
- .mode_set_base = cdv_intel_pipe_set_base,
- .prepare = cdv_intel_crtc_prepare,
- .commit = cdv_intel_crtc_commit,
-};
-
-const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
- .save = cdv_intel_crtc_save,
- .restore = cdv_intel_crtc_restore,
- .cursor_set = cdv_intel_crtc_cursor_set,
- .cursor_move = cdv_intel_crtc_cursor_move,
- .gamma_set = cdv_intel_crtc_gamma_set,
- .set_config = cdv_crtc_set_config,
- .destroy = cdv_intel_crtc_destroy,
-};
-
-/*
- * Set the default value of cursor control and base register
- * to zero. This is a workaround for h/w defect on oaktrail
- */
-void cdv_intel_cursor_init(struct drm_device *dev, int pipe)
-{
- uint32_t control;
- uint32_t base;
-
- switch (pipe) {
- case 0:
- control = CURACNTR;
- base = CURABASE;
- break;
- case 1:
- control = CURBCNTR;
- base = CURBBASE;
- break;
- case 2:
- control = CURCCNTR;
- base = CURCBASE;
- break;
- default:
- return;
- }
-
- REG_WRITE(control, 0);
- REG_WRITE(base, 0);
-}
-
diff --git a/drivers/staging/gma500/cdv_intel_hdmi.c b/drivers/staging/gma500/cdv_intel_hdmi.c
deleted file mode 100644
index cbca2b0c7d58..000000000000
--- a/drivers/staging/gma500/cdv_intel_hdmi.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- *
- * FIXME:
- * We should probably make this generic and share it with Medfield
- */
-
-#include
-#include
-#include
-#include
-#include "psb_intel_drv.h"
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include
-
-/* hdmi control bits */
-#define HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9)
-#define HDMI_BORDER_ENABLE (1 << 7)
-#define HDMI_AUDIO_ENABLE (1 << 6)
-#define HDMI_VSYNC_ACTIVE_HIGH (1 << 4)
-#define HDMI_HSYNC_ACTIVE_HIGH (1 << 3)
-/* hdmi-b control bits */
-#define HDMIB_PIPE_B_SELECT (1 << 30)
-
-
-struct mid_intel_hdmi_priv {
- u32 hdmi_reg;
- u32 save_HDMIB;
- bool has_hdmi_sink;
- bool has_hdmi_audio;
- /* Should set this when detect hotplug */
- bool hdmi_device_connected;
- struct mdfld_hdmi_i2c *i2c_bus;
- struct i2c_adapter *hdmi_i2c_adapter; /* for control functions */
- struct drm_device *dev;
-};
-
-static void cdv_hdmi_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct drm_device *dev = encoder->dev;
- struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
- u32 hdmib;
- struct drm_crtc *crtc = encoder->crtc;
- struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
-
- hdmib = (2 << 10);
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
- hdmib |= HDMI_VSYNC_ACTIVE_HIGH;
- if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
- hdmib |= HDMI_HSYNC_ACTIVE_HIGH;
-
- if (intel_crtc->pipe == 1)
- hdmib |= HDMIB_PIPE_B_SELECT;
-
- if (hdmi_priv->has_hdmi_audio) {
- hdmib |= HDMI_AUDIO_ENABLE;
- hdmib |= HDMI_NULL_PACKETS_DURING_VSYNC;
- }
-
- REG_WRITE(hdmi_priv->hdmi_reg, hdmib);
- REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return true;
-}
-
-static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
-{
- struct drm_device *dev = encoder->dev;
- struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
- u32 hdmib;
-
- hdmib = REG_READ(hdmi_priv->hdmi_reg);
-
- if (mode != DRM_MODE_DPMS_ON)
- REG_WRITE(hdmi_priv->hdmi_reg, hdmib & ~HDMIB_PORT_EN);
- else
- REG_WRITE(hdmi_priv->hdmi_reg, hdmib | HDMIB_PORT_EN);
- REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static void cdv_hdmi_save(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- struct psb_intel_output *output = to_psb_intel_output(connector);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-
- hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static void cdv_hdmi_restore(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- struct psb_intel_output *output = to_psb_intel_output(connector);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-
- REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB);
- REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static enum drm_connector_status cdv_hdmi_detect(
- struct drm_connector *connector, bool force)
-{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
- struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv;
- struct edid *edid = NULL;
- enum drm_connector_status status = connector_status_disconnected;
-
- edid = drm_get_edid(&psb_intel_output->base,
- psb_intel_output->hdmi_i2c_adapter);
-
- hdmi_priv->has_hdmi_sink = false;
- hdmi_priv->has_hdmi_audio = false;
- if (edid) {
- if (edid->input & DRM_EDID_INPUT_DIGITAL) {
- status = connector_status_connected;
- hdmi_priv->has_hdmi_sink =
- drm_detect_hdmi_monitor(edid);
- hdmi_priv->has_hdmi_audio =
- drm_detect_monitor_audio(edid);
- }
-
- psb_intel_output->base.display_info.raw_edid = NULL;
- kfree(edid);
- }
- return status;
-}
-
-static int cdv_hdmi_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t value)
-{
- struct drm_encoder *encoder = connector->encoder;
-
- if (!strcmp(property->name, "scaling mode") && encoder) {
- struct psb_intel_crtc *crtc = to_psb_intel_crtc(encoder->crtc);
- bool centre;
- uint64_t curValue;
-
- if (!crtc)
- return -1;
-
- switch (value) {
- case DRM_MODE_SCALE_FULLSCREEN:
- break;
- case DRM_MODE_SCALE_NO_SCALE:
- break;
- case DRM_MODE_SCALE_ASPECT:
- break;
- default:
- return -1;
- }
-
- if (drm_connector_property_get_value(connector,
- property, &curValue))
- return -1;
-
- if (curValue == value)
- return 0;
-
- if (drm_connector_property_set_value(connector,
- property, value))
- return -1;
-
- centre = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
- (value == DRM_MODE_SCALE_NO_SCALE);
-
- if (crtc->saved_mode.hdisplay != 0 &&
- crtc->saved_mode.vdisplay != 0) {
- if (centre) {
- if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode,
- encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
- return -1;
- } else {
- struct drm_encoder_helper_funcs *helpers
- = encoder->helper_private;
- helpers->mode_set(encoder, &crtc->saved_mode,
- &crtc->saved_adjusted_mode);
- }
- }
- }
- return 0;
-}
-
-/*
- * Return the list of HDMI DDC modes if available.
- */
-static int cdv_hdmi_get_modes(struct drm_connector *connector)
-{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
- struct edid *edid = NULL;
- int ret = 0;
-
- edid = drm_get_edid(&psb_intel_output->base,
- psb_intel_output->hdmi_i2c_adapter);
- if (edid) {
- drm_mode_connector_update_edid_property(&psb_intel_output->
- base, edid);
- ret = drm_add_edid_modes(&psb_intel_output->base, edid);
- kfree(edid);
- }
- return ret;
-}
-
-static int cdv_hdmi_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
-
- if (mode->clock > 165000)
- return MODE_CLOCK_HIGH;
- if (mode->clock < 20000)
- return MODE_CLOCK_HIGH;
-
- /* just in case */
- if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
- return MODE_NO_DBLESCAN;
-
- /* just in case */
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- return MODE_NO_INTERLACE;
-
- /*
- * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it
- * will go beyond the stolen memory size allocated to the framebuffer
- */
- if (mode->hdisplay > 1680)
- return MODE_PANEL;
- if (mode->vdisplay > 1050)
- return MODE_PANEL;
- return MODE_OK;
-}
-
-static void cdv_hdmi_destroy(struct drm_connector *connector)
-{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
-
- if (psb_intel_output->ddc_bus)
- psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
- drm_sysfs_connector_remove(connector);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
-
-static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = {
- .dpms = cdv_hdmi_dpms,
- .mode_fixup = cdv_hdmi_mode_fixup,
- .prepare = psb_intel_encoder_prepare,
- .mode_set = cdv_hdmi_mode_set,
- .commit = psb_intel_encoder_commit,
-};
-
-static const struct drm_connector_helper_funcs
- cdv_hdmi_connector_helper_funcs = {
- .get_modes = cdv_hdmi_get_modes,
- .mode_valid = cdv_hdmi_mode_valid,
- .best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs cdv_hdmi_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
- .save = cdv_hdmi_save,
- .restore = cdv_hdmi_restore,
- .detect = cdv_hdmi_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = cdv_hdmi_set_property,
- .destroy = cdv_hdmi_destroy,
-};
-
-void cdv_hdmi_init(struct drm_device *dev,
- struct psb_intel_mode_device *mode_dev, int reg)
-{
- struct psb_intel_output *psb_intel_output;
- struct drm_connector *connector;
- struct drm_encoder *encoder;
- struct mid_intel_hdmi_priv *hdmi_priv;
- int ddc_bus;
-
- psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
- sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL);
- if (!psb_intel_output)
- return;
-
- hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1);
- psb_intel_output->mode_dev = mode_dev;
- connector = &psb_intel_output->base;
- encoder = &psb_intel_output->enc;
- drm_connector_init(dev, &psb_intel_output->base,
- &cdv_hdmi_connector_funcs,
- DRM_MODE_CONNECTOR_DVID);
-
- drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
- DRM_MODE_ENCODER_TMDS);
-
- drm_mode_connector_attach_encoder(&psb_intel_output->base,
- &psb_intel_output->enc);
- psb_intel_output->type = INTEL_OUTPUT_HDMI;
- hdmi_priv->hdmi_reg = reg;
- hdmi_priv->has_hdmi_sink = false;
- psb_intel_output->dev_priv = hdmi_priv;
-
- drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs);
- drm_connector_helper_add(connector,
- &cdv_hdmi_connector_helper_funcs);
- connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- connector->interlace_allowed = false;
- connector->doublescan_allowed = false;
-
- drm_connector_attach_property(connector,
- dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
-
- switch (reg) {
- case SDVOB:
- ddc_bus = GPIOE;
- break;
- case SDVOC:
- ddc_bus = GPIOD;
- break;
- default:
- DRM_ERROR("unknown reg 0x%x for HDMI\n", reg);
- goto failed_ddc;
- break;
- }
-
- psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
- ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC");
-
- if (!psb_intel_output->ddc_bus) {
- dev_err(dev->dev, "No ddc adapter available!\n");
- goto failed_ddc;
- }
- psb_intel_output->hdmi_i2c_adapter =
- &(psb_intel_output->ddc_bus->adapter);
- hdmi_priv->dev = dev;
- drm_sysfs_connector_add(connector);
- return;
-
-failed_ddc:
- drm_encoder_cleanup(&psb_intel_output->enc);
- drm_connector_cleanup(&psb_intel_output->base);
- kfree(psb_intel_output);
-}
diff --git a/drivers/staging/gma500/cdv_intel_lvds.c b/drivers/staging/gma500/cdv_intel_lvds.c
deleted file mode 100644
index 988b2d0acf43..000000000000
--- a/drivers/staging/gma500/cdv_intel_lvds.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt
- * Dave Airlie
- * Jesse Barnes
- */
-
-#include
-#include
-#include
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include
-#include "cdv_device.h"
-
-/**
- * LVDS I2C backlight control macros
- */
-#define BRIGHTNESS_MAX_LEVEL 100
-#define BRIGHTNESS_MASK 0xFF
-#define BLC_I2C_TYPE 0x01
-#define BLC_PWM_TYPT 0x02
-
-#define BLC_POLARITY_NORMAL 0
-#define BLC_POLARITY_INVERSE 1
-
-#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE)
-#define PSB_BLC_MIN_PWM_REG_FREQ (0x2)
-#define PSB_BLC_PWM_PRECISION_FACTOR (10)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-
-struct cdv_intel_lvds_priv {
- /**
- * Saved LVDO output states
- */
- uint32_t savePP_ON;
- uint32_t savePP_OFF;
- uint32_t saveLVDS;
- uint32_t savePP_CONTROL;
- uint32_t savePP_CYCLE;
- uint32_t savePFIT_CONTROL;
- uint32_t savePFIT_PGM_RATIOS;
- uint32_t saveBLC_PWM_CTL;
-};
-
-/*
- * Returns the maximum level of the backlight duty cycle field.
- */
-static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 retval;
-
- if (gma_power_begin(dev, false)) {
- retval = ((REG_READ(BLC_PWM_CTL) &
- BACKLIGHT_MODULATION_FREQ_MASK) >>
- BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
- gma_power_end(dev);
- } else
- retval = ((dev_priv->saveBLC_PWM_CTL &
- BACKLIGHT_MODULATION_FREQ_MASK) >>
- BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
- return retval;
-}
-
-/*
- * Set LVDS backlight level by I2C command
- */
-static int cdv_lvds_i2c_set_brightness(struct drm_device *dev,
- unsigned int level)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
- u8 out_buf[2];
- unsigned int blc_i2c_brightness;
-
- struct i2c_msg msgs[] = {
- {
- .addr = lvds_i2c_bus->slave_addr,
- .flags = 0,
- .len = 2,
- .buf = out_buf,
- }
- };
-
- blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
- BRIGHTNESS_MASK /
- BRIGHTNESS_MAX_LEVEL);
-
- if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
- blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
-
- out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
- out_buf[1] = (u8)blc_i2c_brightness;
-
- if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1)
- return 0;
-
- DRM_ERROR("I2C transfer error\n");
- return -1;
-}
-
-
-static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- u32 max_pwm_blc;
- u32 blc_pwm_duty_cycle;
-
- max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev);
-
- /*BLC_PWM_CTL Should be initiated while backlight device init*/
- BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0);
-
- blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
-
- if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
- blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
-
- blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
- REG_WRITE(BLC_PWM_CTL,
- (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
- (blc_pwm_duty_cycle));
-
- return 0;
-}
-
-/*
- * Set LVDS backlight level either by I2C or PWM
- */
-void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (!dev_priv->lvds_bl) {
- DRM_ERROR("NO LVDS Backlight Info\n");
- return;
- }
-
- if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
- cdv_lvds_i2c_set_brightness(dev, level);
- else
- cdv_lvds_pwm_set_brightness(dev, level);
-}
-
-/**
- * Sets the backlight level.
- *
- * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().
- */
-static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 blc_pwm_ctl;
-
- if (gma_power_begin(dev, false)) {
- blc_pwm_ctl =
- REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
- REG_WRITE(BLC_PWM_CTL,
- (blc_pwm_ctl |
- (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
- gma_power_end(dev);
- } else {
- blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
- ~BACKLIGHT_DUTY_CYCLE_MASK;
- dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
- (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
- }
-}
-
-/**
- * Sets the power state for the panel.
- */
-static void cdv_intel_lvds_set_power(struct drm_device *dev,
- struct psb_intel_output *output, bool on)
-{
- u32 pp_status;
-
- if (!gma_power_begin(dev, true))
- return;
-
- if (on) {
- REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
- POWER_TARGET_ON);
- do {
- pp_status = REG_READ(PP_STATUS);
- } while ((pp_status & PP_ON) == 0);
-
- cdv_intel_lvds_set_backlight(dev,
- output->
- mode_dev->backlight_duty_cycle);
- } else {
- cdv_intel_lvds_set_backlight(dev, 0);
-
- REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
- ~POWER_TARGET_ON);
- do {
- pp_status = REG_READ(PP_STATUS);
- } while (pp_status & PP_ON);
- }
- gma_power_end(dev);
-}
-
-static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct drm_device *dev = encoder->dev;
- struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
- if (mode == DRM_MODE_DPMS_ON)
- cdv_intel_lvds_set_power(dev, output, true);
- else
- cdv_intel_lvds_set_power(dev, output, false);
- /* XXX: We never power down the LVDS pairs. */
-}
-
-static void cdv_intel_lvds_save(struct drm_connector *connector)
-{
-}
-
-static void cdv_intel_lvds_restore(struct drm_connector *connector)
-{
-}
-
-int cdv_intel_lvds_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
- struct drm_display_mode *fixed_mode =
- psb_intel_output->mode_dev->panel_fixed_mode;
-
- /* just in case */
- if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
- return MODE_NO_DBLESCAN;
-
- /* just in case */
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- return MODE_NO_INTERLACE;
-
- if (fixed_mode) {
- if (mode->hdisplay > fixed_mode->hdisplay)
- return MODE_PANEL;
- if (mode->vdisplay > fixed_mode->vdisplay)
- return MODE_PANEL;
- }
- return MODE_OK;
-}
-
-bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct psb_intel_mode_device *mode_dev =
- enc_to_psb_intel_output(encoder)->mode_dev;
- struct drm_device *dev = encoder->dev;
- struct drm_encoder *tmp_encoder;
- struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
-
- /* Should never happen!! */
- list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
- head) {
- if (tmp_encoder != encoder
- && tmp_encoder->crtc == encoder->crtc) {
- printk(KERN_ERR "Can't enable LVDS and another "
- "encoder on the same pipe\n");
- return false;
- }
- }
-
- /*
- * If we have timings from the BIOS for the panel, put them in
- * to the adjusted mode. The CRTC will be set up for this mode,
- * with the panel scaling set up to source from the H/VDisplay
- * of the original mode.
- */
- if (panel_fixed_mode != NULL) {
- adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
- adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
- adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
- adjusted_mode->htotal = panel_fixed_mode->htotal;
- adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
- adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
- adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
- adjusted_mode->vtotal = panel_fixed_mode->vtotal;
- adjusted_mode->clock = panel_fixed_mode->clock;
- drm_mode_set_crtcinfo(adjusted_mode,
- CRTC_INTERLACE_HALVE_V);
- }
-
- /*
- * XXX: It would be nice to support lower refresh rates on the
- * panels to reduce power consumption, and perhaps match the
- * user's requested refresh rate.
- */
-
- return true;
-}
-
-static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
- struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
- if (!gma_power_begin(dev, true))
- return;
-
- mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
- mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
- BACKLIGHT_DUTY_CYCLE_MASK);
-
- cdv_intel_lvds_set_power(dev, output, false);
-
- gma_power_end(dev);
-}
-
-static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
- struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
- if (mode_dev->backlight_duty_cycle == 0)
- mode_dev->backlight_duty_cycle =
- cdv_intel_lvds_get_max_backlight(dev);
-
- cdv_intel_lvds_set_power(dev, output, true);
-}
-
-static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct drm_device *dev = encoder->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 pfit_control;
-
- /*
- * The LVDS pin pair will already have been turned on in the
- * cdv_intel_crtc_mode_set since it has a large impact on the DPLL
- * settings.
- */
-
- /*
- * Enable automatic panel scaling so that non-native modes fill the
- * screen. Should be enabled before the pipe is enabled, according to
- * register description and PRM.
- */
- if (mode->hdisplay != adjusted_mode->hdisplay ||
- mode->vdisplay != adjusted_mode->vdisplay)
- pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
- HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
- HORIZ_INTERP_BILINEAR);
- else
- pfit_control = 0;
-
- if (dev_priv->lvds_dither)
- pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-
- REG_WRITE(PFIT_CONTROL, pfit_control);
-}
-
-/**
- * Detect the LVDS connection.
- *
- * This always returns CONNECTOR_STATUS_CONNECTED.
- * This connector should only have
- * been set up if the LVDS was actually connected anyway.
- */
-static enum drm_connector_status cdv_intel_lvds_detect(
- struct drm_connector *connector, bool force)
-{
- return connector_status_connected;
-}
-
-/**
- * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
- */
-static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
- struct psb_intel_mode_device *mode_dev =
- psb_intel_output->mode_dev;
- int ret;
-
- ret = psb_intel_ddc_get_modes(psb_intel_output);
-
- if (ret)
- return ret;
-
- /* Didn't get an EDID, so
- * Set wide sync ranges so we get all modes
- * handed to valid_mode for checking
- */
- connector->display_info.min_vfreq = 0;
- connector->display_info.max_vfreq = 200;
- connector->display_info.min_hfreq = 0;
- connector->display_info.max_hfreq = 200;
- if (mode_dev->panel_fixed_mode != NULL) {
- struct drm_display_mode *mode =
- drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
- drm_mode_probed_add(connector, mode);
- return 1;
- }
-
- return 0;
-}
-
-/**
- * cdv_intel_lvds_destroy - unregister and free LVDS structures
- * @connector: connector to free
- *
- * Unregister the DDC bus for this connector then free the driver private
- * structure.
- */
-void cdv_intel_lvds_destroy(struct drm_connector *connector)
-{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
-
- if (psb_intel_output->ddc_bus)
- psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
- drm_sysfs_connector_remove(connector);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
-
-int cdv_intel_lvds_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t value)
-{
- struct drm_encoder *encoder = connector->encoder;
-
- if (!strcmp(property->name, "scaling mode") && encoder) {
- struct psb_intel_crtc *crtc =
- to_psb_intel_crtc(encoder->crtc);
- uint64_t curValue;
-
- if (!crtc)
- return -1;
-
- switch (value) {
- case DRM_MODE_SCALE_FULLSCREEN:
- break;
- case DRM_MODE_SCALE_NO_SCALE:
- break;
- case DRM_MODE_SCALE_ASPECT:
- break;
- default:
- return -1;
- }
-
- if (drm_connector_property_get_value(connector,
- property,
- &curValue))
- return -1;
-
- if (curValue == value)
- return 0;
-
- if (drm_connector_property_set_value(connector,
- property,
- value))
- return -1;
-
- if (crtc->saved_mode.hdisplay != 0 &&
- crtc->saved_mode.vdisplay != 0) {
- if (!drm_crtc_helper_set_mode(encoder->crtc,
- &crtc->saved_mode,
- encoder->crtc->x,
- encoder->crtc->y,
- encoder->crtc->fb))
- return -1;
- }
- } else if (!strcmp(property->name, "backlight") && encoder) {
- if (drm_connector_property_set_value(connector,
- property,
- value))
- return -1;
- else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct drm_psb_private *dev_priv =
- encoder->dev->dev_private;
- struct backlight_device *bd =
- dev_priv->backlight_device;
- bd->props.brightness = value;
- backlight_update_status(bd);
-#endif
- }
- } else if (!strcmp(property->name, "DPMS") && encoder) {
- struct drm_encoder_helper_funcs *helpers =
- encoder->helper_private;
- helpers->dpms(encoder, value);
- }
- return 0;
-}
-
-static const struct drm_encoder_helper_funcs
- cdv_intel_lvds_helper_funcs = {
- .dpms = cdv_intel_lvds_encoder_dpms,
- .mode_fixup = cdv_intel_lvds_mode_fixup,
- .prepare = cdv_intel_lvds_prepare,
- .mode_set = cdv_intel_lvds_mode_set,
- .commit = cdv_intel_lvds_commit,
-};
-
-static const struct drm_connector_helper_funcs
- cdv_intel_lvds_connector_helper_funcs = {
- .get_modes = cdv_intel_lvds_get_modes,
- .mode_valid = cdv_intel_lvds_mode_valid,
- .best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
- .save = cdv_intel_lvds_save,
- .restore = cdv_intel_lvds_restore,
- .detect = cdv_intel_lvds_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = cdv_intel_lvds_set_property,
- .destroy = cdv_intel_lvds_destroy,
-};
-
-
-static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder)
-{
- drm_encoder_cleanup(encoder);
-}
-
-const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
- .destroy = cdv_intel_lvds_enc_destroy,
-};
-
-/**
- * cdv_intel_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
- *
- * Create the connector, register the LVDS DDC bus, and try to figure out what
- * modes we can display on the LVDS panel (if present).
- */
-void cdv_intel_lvds_init(struct drm_device *dev,
- struct psb_intel_mode_device *mode_dev)
-{
- struct psb_intel_output *psb_intel_output;
- struct cdv_intel_lvds_priv *lvds_priv;
- struct drm_connector *connector;
- struct drm_encoder *encoder;
- struct drm_display_mode *scan;
- struct drm_crtc *crtc;
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 lvds;
- int pipe;
-
- psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
- sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
- if (!psb_intel_output)
- return;
-
- lvds_priv = (struct cdv_intel_lvds_priv *)(psb_intel_output + 1);
-
- psb_intel_output->dev_priv = lvds_priv;
-
- psb_intel_output->mode_dev = mode_dev;
- connector = &psb_intel_output->base;
- encoder = &psb_intel_output->enc;
-
-
- drm_connector_init(dev, &psb_intel_output->base,
- &cdv_intel_lvds_connector_funcs,
- DRM_MODE_CONNECTOR_LVDS);
-
- drm_encoder_init(dev, &psb_intel_output->enc,
- &cdv_intel_lvds_enc_funcs,
- DRM_MODE_ENCODER_LVDS);
-
-
- drm_mode_connector_attach_encoder(&psb_intel_output->base,
- &psb_intel_output->enc);
- psb_intel_output->type = INTEL_OUTPUT_LVDS;
-
- drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
- drm_connector_helper_add(connector,
- &cdv_intel_lvds_connector_helper_funcs);
- connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- connector->interlace_allowed = false;
- connector->doublescan_allowed = false;
-
- /*Attach connector properties*/
- drm_connector_attach_property(connector,
- dev->mode_config.scaling_mode_property,
- DRM_MODE_SCALE_FULLSCREEN);
- drm_connector_attach_property(connector,
- dev_priv->backlight_property,
- BRIGHTNESS_MAX_LEVEL);
-
- /**
- * Set up I2C bus
- * FIXME: distroy i2c_bus when exit
- */
- psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
- GPIOB,
- "LVDSBLC_B");
- if (!psb_intel_output->i2c_bus) {
- dev_printk(KERN_ERR,
- &dev->pdev->dev, "I2C bus registration failed.\n");
- goto failed_blc_i2c;
- }
- psb_intel_output->i2c_bus->slave_addr = 0x2C;
- dev_priv->lvds_i2c_bus = psb_intel_output->i2c_bus;
-
- /*
- * LVDS discovery:
- * 1) check for EDID on DDC
- * 2) check for VBT data
- * 3) check to see if LVDS is already on
- * if none of the above, no panel
- * 4) make sure lid is open
- * if closed, act like it's not there for now
- */
-
- /* Set up the DDC bus. */
- psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
- GPIOC,
- "LVDSDDC_C");
- if (!psb_intel_output->ddc_bus) {
- dev_printk(KERN_ERR, &dev->pdev->dev,
- "DDC bus registration " "failed.\n");
- goto failed_ddc;
- }
-
- /*
- * Attempt to get the fixed panel mode from DDC. Assume that the
- * preferred mode is the right one.
- */
- psb_intel_ddc_get_modes(psb_intel_output);
- list_for_each_entry(scan, &connector->probed_modes, head) {
- if (scan->type & DRM_MODE_TYPE_PREFERRED) {
- mode_dev->panel_fixed_mode =
- drm_mode_duplicate(dev, scan);
- goto out; /* FIXME: check for quirks */
- }
- }
-
- /* Failed to get EDID, what about VBT? do we need this?*/
- if (dev_priv->lfp_lvds_vbt_mode) {
- mode_dev->panel_fixed_mode =
- drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
- if (mode_dev->panel_fixed_mode) {
- mode_dev->panel_fixed_mode->type |=
- DRM_MODE_TYPE_PREFERRED;
- goto out; /* FIXME: check for quirks */
- }
- }
- /*
- * If we didn't get EDID, try checking if the panel is already turned
- * on. If so, assume that whatever is currently programmed is the
- * correct mode.
- */
- lvds = REG_READ(LVDS);
- pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
- crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
-
- if (crtc && (lvds & LVDS_PORT_EN)) {
- mode_dev->panel_fixed_mode =
- cdv_intel_crtc_mode_get(dev, crtc);
- if (mode_dev->panel_fixed_mode) {
- mode_dev->panel_fixed_mode->type |=
- DRM_MODE_TYPE_PREFERRED;
- goto out; /* FIXME: check for quirks */
- }
- }
-
- /* If we still don't have a mode after all that, give up. */
- if (!mode_dev->panel_fixed_mode) {
- DRM_DEBUG
- ("Found no modes on the lvds, ignoring the LVDS\n");
- goto failed_find;
- }
-
-out:
- drm_sysfs_connector_add(connector);
- return;
-
-failed_find:
- printk(KERN_ERR "Failed find\n");
- if (psb_intel_output->ddc_bus)
- psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-failed_ddc:
- printk(KERN_ERR "Failed DDC\n");
- if (psb_intel_output->i2c_bus)
- psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-failed_blc_i2c:
- printk(KERN_ERR "Failed BLC\n");
- drm_encoder_cleanup(encoder);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
diff --git a/drivers/staging/gma500/displays/hdmi.h b/drivers/staging/gma500/displays/hdmi.h
deleted file mode 100644
index d58ba9bd010f..000000000000
--- a/drivers/staging/gma500/displays/hdmi.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
- */
-
-#ifndef HDMI_H
-#define HDMI_H
-
-extern void hdmi_init(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/pyr_cmd.h b/drivers/staging/gma500/displays/pyr_cmd.h
deleted file mode 100644
index 84bae5c8c552..000000000000
--- a/drivers/staging/gma500/displays/pyr_cmd.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
- */
-
-#ifndef PYR_CMD_H
-#define PYR_CMD_H
-
-extern void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-
-#endif
-
diff --git a/drivers/staging/gma500/displays/pyr_vid.h b/drivers/staging/gma500/displays/pyr_vid.h
deleted file mode 100644
index ce98860fa68a..000000000000
--- a/drivers/staging/gma500/displays/pyr_vid.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
-*/
-
-#ifndef PYR_VID_H
-#define PYR_VID_H
-
-extern void pyr_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *pyr_vid_get_config_mode(struct drm_device* dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tmd_cmd.h b/drivers/staging/gma500/displays/tmd_cmd.h
deleted file mode 100644
index 641e85eedece..000000000000
--- a/drivers/staging/gma500/displays/tmd_cmd.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
- */
-
-#ifndef TMD_CMD_H
-#define TMD_CMD_H
-
-extern void tmd_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *tmd_cmd_get_config_mode(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tmd_vid.h b/drivers/staging/gma500/displays/tmd_vid.h
deleted file mode 100644
index 7a5fa3b935e3..000000000000
--- a/drivers/staging/gma500/displays/tmd_vid.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
-*/
-
-#ifndef TMD_VID_H
-#define TMD_VID_H
-
-extern void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tpo_cmd.h b/drivers/staging/gma500/displays/tpo_cmd.h
deleted file mode 100644
index 610552730d71..000000000000
--- a/drivers/staging/gma500/displays/tpo_cmd.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
-*/
-
-#ifndef TPO_CMD_H
-#define TPO_CMD_H
-
-extern void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-/* extern struct drm_display_mode * */
-/* tpo_cmd_get_config_mode(struct drm_device *dev); */
-
-#endif
diff --git a/drivers/staging/gma500/displays/tpo_vid.h b/drivers/staging/gma500/displays/tpo_vid.h
deleted file mode 100644
index c24f05722de1..000000000000
--- a/drivers/staging/gma500/displays/tpo_vid.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
- */
-
-#ifndef TPO_VID_H
-#define TPO_VID_H
-
-extern void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-
-#endif
diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c
deleted file mode 100644
index b00761cba144..000000000000
--- a/drivers/staging/gma500/framebuffer.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_drv.h"
-#include "framebuffer.h"
-#include "gtt.h"
-
-#include "mdfld_output.h"
-
-static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
-static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
- struct drm_file *file_priv,
- unsigned int *handle);
-
-static const struct drm_framebuffer_funcs psb_fb_funcs = {
- .destroy = psb_user_framebuffer_destroy,
- .create_handle = psb_user_framebuffer_create_handle,
-};
-
-#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
-
-static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- struct psb_fbdev *fbdev = info->par;
- struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
- uint32_t v;
-
- if (!fb)
- return -ENOMEM;
-
- if (regno > 255)
- return 1;
-
- red = CMAP_TOHW(red, info->var.red.length);
- blue = CMAP_TOHW(blue, info->var.blue.length);
- green = CMAP_TOHW(green, info->var.green.length);
- transp = CMAP_TOHW(transp, info->var.transp.length);
-
- v = (red << info->var.red.offset) |
- (green << info->var.green.offset) |
- (blue << info->var.blue.offset) |
- (transp << info->var.transp.offset);
-
- if (regno < 16) {
- switch (fb->bits_per_pixel) {
- case 16:
- ((uint32_t *) info->pseudo_palette)[regno] = v;
- break;
- case 24:
- case 32:
- ((uint32_t *) info->pseudo_palette)[regno] = v;
- break;
- }
- }
-
- return 0;
-}
-
-static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = &fbdev->pfb;
- struct drm_device *dev = psbfb->base.dev;
-
- /*
- * We have to poke our nose in here. The core fb code assumes
- * panning is part of the hardware that can be invoked before
- * the actual fb is mapped. In our case that isn't quite true.
- */
- if (psbfb->gtt->npage)
- psb_gtt_roll(dev, psbfb->gtt, var->yoffset);
- return 0;
-}
-
-void psbfb_suspend(struct drm_device *dev)
-{
- struct drm_framebuffer *fb = 0;
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
- console_lock();
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
- struct fb_info *info = psbfb->fbdev;
- fb_set_suspend(info, 1);
- drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
- }
- mutex_unlock(&dev->mode_config.mutex);
- console_unlock();
-}
-
-void psbfb_resume(struct drm_device *dev)
-{
- struct drm_framebuffer *fb = 0;
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
- console_lock();
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
- struct fb_info *info = psbfb->fbdev;
- fb_set_suspend(info, 0);
- drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
- }
- mutex_unlock(&dev->mode_config.mutex);
- console_unlock();
- drm_helper_disable_unused_functions(dev);
-}
-
-static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- struct psb_framebuffer *psbfb = vma->vm_private_data;
- struct drm_device *dev = psbfb->base.dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- int page_num;
- int i;
- unsigned long address;
- int ret;
- unsigned long pfn;
- /* FIXME: assumes fb at stolen base which may not be true */
- unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
-
- page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
- address = (unsigned long)vmf->virtual_address;
-
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- for (i = 0; i < page_num; i++) {
- pfn = (phys_addr >> PAGE_SHIFT);
-
- ret = vm_insert_mixed(vma, address, pfn);
- if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
- break;
- else if (unlikely(ret != 0)) {
- ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
- return ret;
- }
- address += PAGE_SIZE;
- phys_addr += PAGE_SIZE;
- }
- return VM_FAULT_NOPAGE;
-}
-
-static void psbfb_vm_open(struct vm_area_struct *vma)
-{
-}
-
-static void psbfb_vm_close(struct vm_area_struct *vma)
-{
-}
-
-static struct vm_operations_struct psbfb_vm_ops = {
- .fault = psbfb_vm_fault,
- .open = psbfb_vm_open,
- .close = psbfb_vm_close
-};
-
-static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
- struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = &fbdev->pfb;
-
- if (vma->vm_pgoff != 0)
- return -EINVAL;
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
- return -EINVAL;
-
- if (!psbfb->addr_space)
- psbfb->addr_space = vma->vm_file->f_mapping;
- /*
- * If this is a GEM object then info->screen_base is the virtual
- * kernel remapping of the object. FIXME: Review if this is
- * suitable for our mmap work
- */
- vma->vm_ops = &psbfb_vm_ops;
- vma->vm_private_data = (void *)psbfb;
- vma->vm_flags |= VM_RESERVED | VM_IO |
- VM_MIXEDMAP | VM_DONTEXPAND;
- return 0;
-}
-
-static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
-{
- return -ENOTTY;
-}
-
-static struct fb_ops psbfb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = drm_fb_helper_check_var,
- .fb_set_par = drm_fb_helper_set_par,
- .fb_blank = drm_fb_helper_blank,
- .fb_setcolreg = psbfb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = psbfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = psbfb_mmap,
- .fb_sync = psbfb_sync,
- .fb_ioctl = psbfb_ioctl,
-};
-
-static struct fb_ops psbfb_roll_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = drm_fb_helper_check_var,
- .fb_set_par = drm_fb_helper_set_par,
- .fb_blank = drm_fb_helper_blank,
- .fb_setcolreg = psbfb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_pan_display = psbfb_pan,
- .fb_mmap = psbfb_mmap,
- .fb_sync = psbfb_sync,
- .fb_ioctl = psbfb_ioctl,
-};
-
-static struct fb_ops psbfb_unaccel_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = drm_fb_helper_check_var,
- .fb_set_par = drm_fb_helper_set_par,
- .fb_blank = drm_fb_helper_blank,
- .fb_setcolreg = psbfb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_mmap = psbfb_mmap,
- .fb_ioctl = psbfb_ioctl,
-};
-
-/**
- * psb_framebuffer_init - initialize a framebuffer
- * @dev: our DRM device
- * @fb: framebuffer to set up
- * @mode_cmd: mode description
- * @gt: backing object
- *
- * Configure and fill in the boilerplate for our frame buffer. Return
- * 0 on success or an error code if we fail.
- */
-static int psb_framebuffer_init(struct drm_device *dev,
- struct psb_framebuffer *fb,
- struct drm_mode_fb_cmd2 *mode_cmd,
- struct gtt_range *gt)
-{
- u32 bpp, depth;
- int ret;
-
- drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
-
- if (mode_cmd->pitches[0] & 63)
- return -EINVAL;
- switch (bpp) {
- case 8:
- case 16:
- case 24:
- case 32:
- break;
- default:
- return -EINVAL;
- }
- ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
- if (ret) {
- dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
- return ret;
- }
- drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
- fb->gtt = gt;
- return 0;
-}
-
-/**
- * psb_framebuffer_create - create a framebuffer backed by gt
- * @dev: our DRM device
- * @mode_cmd: the description of the requested mode
- * @gt: the backing object
- *
- * Create a framebuffer object backed by the gt, and fill in the
- * boilerplate required
- *
- * TODO: review object references
- */
-
-static struct drm_framebuffer *psb_framebuffer_create
- (struct drm_device *dev,
- struct drm_mode_fb_cmd2 *mode_cmd,
- struct gtt_range *gt)
-{
- struct psb_framebuffer *fb;
- int ret;
-
- fb = kzalloc(sizeof(*fb), GFP_KERNEL);
- if (!fb)
- return ERR_PTR(-ENOMEM);
-
- ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
- if (ret) {
- kfree(fb);
- return ERR_PTR(ret);
- }
- return &fb->base;
-}
-
-/**
- * psbfb_alloc - allocate frame buffer memory
- * @dev: the DRM device
- * @aligned_size: space needed
- * @force: fall back to GEM buffers if need be
- *
- * Allocate the frame buffer. In the usual case we get a GTT range that
- * is stolen memory backed and life is simple. If there isn't sufficient
- * stolen memory or the system has no stolen memory we allocate a range
- * and back it with a GEM object.
- *
- * In this case the GEM object has no handle.
- */
-static struct gtt_range *psbfb_alloc(struct drm_device *dev,
- int aligned_size, int force)
-{
- struct gtt_range *backing;
- /* Begin by trying to use stolen memory backing */
- backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
- if (backing) {
- if (drm_gem_private_object_init(dev,
- &backing->gem, aligned_size) == 0)
- return backing;
- psb_gtt_free_range(dev, backing);
- }
- if (!force)
- return NULL;
-
- /* Next try using GEM host memory */
- backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0);
- if (backing == NULL)
- return NULL;
-
- /* Now back it with an object */
- if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) {
- psb_gtt_free_range(dev, backing);
- return NULL;
- }
- return backing;
-}
-
-/**
- * psbfb_create - create a framebuffer
- * @fbdev: the framebuffer device
- * @sizes: specification of the layout
- *
- * Create a framebuffer to the specifications provided
- */
-static int psbfb_create(struct psb_fbdev *fbdev,
- struct drm_fb_helper_surface_size *sizes)
-{
- struct drm_device *dev = fbdev->psb_fb_helper.dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct fb_info *info;
- struct drm_framebuffer *fb;
- struct psb_framebuffer *psbfb = &fbdev->pfb;
- struct drm_mode_fb_cmd2 mode_cmd;
- struct device *device = &dev->pdev->dev;
- int size;
- int ret;
- struct gtt_range *backing;
- int gtt_roll = 1;
- u32 bpp, depth;
-
- mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
- bpp = sizes->surface_bpp;
-
- /* No 24bit packed */
- if (bpp == 24)
- bpp = 32;
-
- /* Acceleration via the GTT requires pitch to be 4096 byte aligned
- (ie 1024 or 2048 pixels in normal use) */
- mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096);
- depth = sizes->surface_depth;
-
- size = mode_cmd.pitches[0] * mode_cmd.height;
- size = ALIGN(size, PAGE_SIZE);
-
- /* Allocate the framebuffer in the GTT with stolen page backing */
- backing = psbfb_alloc(dev, size, 0);
- if (backing == NULL) {
- /*
- * We couldn't get the space we wanted, fall back to the
- * display engine requirement instead. The HW requires
- * the pitch to be 64 byte aligned
- */
-
- gtt_roll = 0; /* Don't use GTT accelerated scrolling */
-
- mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64);
- depth = sizes->surface_depth;
-
- size = mode_cmd.pitches[0] * mode_cmd.height;
- size = ALIGN(size, PAGE_SIZE);
-
- /* Allocate the framebuffer in the GTT with stolen page
- backing when there is room */
- backing = psbfb_alloc(dev, size, 1);
- if (backing == NULL)
- return -ENOMEM;
- }
-
- mutex_lock(&dev->struct_mutex);
-
- info = framebuffer_alloc(0, device);
- if (!info) {
- ret = -ENOMEM;
- goto out_err1;
- }
- info->par = fbdev;
-
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
-
- ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
- if (ret)
- goto out_unref;
-
- fb = &psbfb->base;
- psbfb->fbdev = info;
-
- fbdev->psb_fb_helper.fb = fb;
- fbdev->psb_fb_helper.fbdev = info;
-
- strcpy(info->fix.id, "psbfb");
-
- info->flags = FBINFO_DEFAULT;
- if (gtt_roll) { /* GTT rolling seems best */
- info->fbops = &psbfb_roll_ops;
- info->flags |= FBINFO_HWACCEL_YPAN;
- }
- else if (dev_priv->ops->accel_2d) /* 2D engine */
- info->fbops = &psbfb_ops;
- else /* Software */
- info->fbops = &psbfb_unaccel_ops;
-
- ret = fb_alloc_cmap(&info->cmap, 256, 0);
- if (ret) {
- ret = -ENOMEM;
- goto out_unref;
- }
-
- info->fix.smem_start = dev->mode_config.fb_base;
- info->fix.smem_len = size;
- info->fix.ywrapstep = gtt_roll;
- info->fix.ypanstep = gtt_roll;
-
- if (backing->stolen) {
- /* Accessed stolen memory directly */
- info->screen_base = (char *)dev_priv->vram_addr +
- backing->offset;
- } else {
- /* Pin the pages into the GTT and create a mapping to them */
- psb_gtt_pin(backing);
- info->screen_base = vm_map_ram(backing->pages, backing->npage,
- -1, PAGE_KERNEL);
- if (info->screen_base == NULL) {
- psb_gtt_unpin(backing);
- ret = -ENOMEM;
- goto out_unref;
- }
- psbfb->vm_map = 1;
- }
- info->screen_size = size;
-
- if (dev_priv->gtt.stolen_size) {
- info->apertures = alloc_apertures(1);
- if (!info->apertures) {
- ret = -ENOMEM;
- goto out_unref;
- }
- info->apertures->ranges[0].base = dev->mode_config.fb_base;
- info->apertures->ranges[0].size = dev_priv->gtt.stolen_size;
- }
-
- drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
- drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
- sizes->fb_width, sizes->fb_height);
-
- info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
- info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
-
- info->pixmap.size = 64 * 1024;
- info->pixmap.buf_align = 8;
- info->pixmap.access_align = 32;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
- info->pixmap.scan_align = 1;
-
- dev_info(dev->dev, "allocated %dx%d fb\n",
- psbfb->base.width, psbfb->base.height);
-
- mutex_unlock(&dev->struct_mutex);
- return 0;
-out_unref:
- if (backing->stolen)
- psb_gtt_free_range(dev, backing);
- else {
- if (psbfb->vm_map)
- vm_unmap_ram(info->screen_base, backing->npage);
- drm_gem_object_unreference(&backing->gem);
- }
-out_err1:
- mutex_unlock(&dev->struct_mutex);
- psb_gtt_free_range(dev, backing);
- return ret;
-}
-
-/**
- * psb_user_framebuffer_create - create framebuffer
- * @dev: our DRM device
- * @filp: client file
- * @cmd: mode request
- *
- * Create a new framebuffer backed by a userspace GEM object
- */
-static struct drm_framebuffer *psb_user_framebuffer_create
- (struct drm_device *dev, struct drm_file *filp,
- struct drm_mode_fb_cmd2 *cmd)
-{
- struct gtt_range *r;
- struct drm_gem_object *obj;
-
- /*
- * Find the GEM object and thus the gtt range object that is
- * to back this space
- */
- obj = drm_gem_object_lookup(dev, filp, cmd->handles[0]);
- if (obj == NULL)
- return ERR_PTR(-ENOENT);
-
- /* Let the core code do all the work */
- r = container_of(obj, struct gtt_range, gem);
- return psb_framebuffer_create(dev, cmd, r);
-}
-
-static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
-}
-
-static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
- u16 *green, u16 *blue, int regno)
-{
-}
-
-static int psbfb_probe(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes)
-{
- struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper;
- int new_fb = 0;
- int ret;
-
- if (!helper->fb) {
- ret = psbfb_create(psb_fbdev, sizes);
- if (ret)
- return ret;
- new_fb = 1;
- }
- return new_fb;
-}
-
-struct drm_fb_helper_funcs psb_fb_helper_funcs = {
- .gamma_set = psbfb_gamma_set,
- .gamma_get = psbfb_gamma_get,
- .fb_probe = psbfb_probe,
-};
-
-int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
-{
- struct fb_info *info;
- struct psb_framebuffer *psbfb = &fbdev->pfb;
-
- if (fbdev->psb_fb_helper.fbdev) {
- info = fbdev->psb_fb_helper.fbdev;
-
- /* If this is our base framebuffer then kill any virtual map
- for the framebuffer layer and unpin it */
- if (psbfb->vm_map) {
- vm_unmap_ram(info->screen_base, psbfb->gtt->npage);
- psb_gtt_unpin(psbfb->gtt);
- }
- unregister_framebuffer(info);
- if (info->cmap.len)
- fb_dealloc_cmap(&info->cmap);
- framebuffer_release(info);
- }
- drm_fb_helper_fini(&fbdev->psb_fb_helper);
- drm_framebuffer_cleanup(&psbfb->base);
-
- if (psbfb->gtt)
- drm_gem_object_unreference(&psbfb->gtt->gem);
- return 0;
-}
-
-int psb_fbdev_init(struct drm_device *dev)
-{
- struct psb_fbdev *fbdev;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
- if (!fbdev) {
- dev_err(dev->dev, "no memory\n");
- return -ENOMEM;
- }
-
- dev_priv->fbdev = fbdev;
- fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;
-
- drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
- INTELFB_CONN_LIMIT);
-
- drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
- drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
- return 0;
-}
-
-void psb_fbdev_fini(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (!dev_priv->fbdev)
- return;
-
- psb_fbdev_destroy(dev, dev_priv->fbdev);
- kfree(dev_priv->fbdev);
- dev_priv->fbdev = NULL;
-}
-
-static void psbfb_output_poll_changed(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev;
- drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
-}
-
-/**
- * psb_user_framebuffer_create_handle - add hamdle to a framebuffer
- * @fb: framebuffer
- * @file_priv: our DRM file
- * @handle: returned handle
- *
- * Our framebuffer object is a GTT range which also contains a GEM
- * object. We need to turn it into a handle for userspace. GEM will do
- * the work for us
- */
-static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
- struct drm_file *file_priv,
- unsigned int *handle)
-{
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
- struct gtt_range *r = psbfb->gtt;
- return drm_gem_handle_create(file_priv, &r->gem, handle);
-}
-
-/**
- * psb_user_framebuffer_destroy - destruct user created fb
- * @fb: framebuffer
- *
- * User framebuffers are backed by GEM objects so all we have to do is
- * clean up a bit and drop the reference, GEM will handle the fallout
- */
-static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
-{
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
- struct gtt_range *r = psbfb->gtt;
- struct drm_device *dev = fb->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_fbdev *fbdev = dev_priv->fbdev;
- struct drm_crtc *crtc;
- int reset = 0;
-
- /* Should never get stolen memory for a user fb */
- WARN_ON(r->stolen);
-
- /* Check if we are erroneously live */
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- if (crtc->fb == fb)
- reset = 1;
-
- if (reset)
- /*
- * Now force a sane response before we permit the DRM CRTC
- * layer to do stupid things like blank the display. Instead
- * we reset this framebuffer as if the user had forced a reset.
- * We must do this before the cleanup so that the DRM layer
- * doesn't get a chance to stick its oar in where it isn't
- * wanted.
- */
- drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
-
- /* Let DRM do its clean up */
- drm_framebuffer_cleanup(fb);
- /* We are no longer using the resource in GEM */
- drm_gem_object_unreference_unlocked(&r->gem);
- kfree(fb);
-}
-
-static const struct drm_mode_config_funcs psb_mode_funcs = {
- .fb_create = psb_user_framebuffer_create,
- .output_poll_changed = psbfb_output_poll_changed,
-};
-
-static int psb_create_backlight_property(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_property *backlight;
-
- if (dev_priv->backlight_property)
- return 0;
-
- backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "backlight", 2);
- backlight->values[0] = 0;
- backlight->values[1] = 100;
-
- dev_priv->backlight_property = backlight;
-
- return 0;
-}
-
-static void psb_setup_outputs(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_connector *connector;
-
- drm_mode_create_scaling_mode_property(dev);
- psb_create_backlight_property(dev);
-
- dev_priv->ops->output_init(dev);
-
- list_for_each_entry(connector, &dev->mode_config.connector_list,
- head) {
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
- struct drm_encoder *encoder = &psb_intel_output->enc;
- int crtc_mask = 0, clone_mask = 0;
-
- /* valid crtcs */
- switch (psb_intel_output->type) {
- case INTEL_OUTPUT_ANALOG:
- crtc_mask = (1 << 0);
- clone_mask = (1 << INTEL_OUTPUT_ANALOG);
- break;
- case INTEL_OUTPUT_SDVO:
- crtc_mask = ((1 << 0) | (1 << 1));
- clone_mask = (1 << INTEL_OUTPUT_SDVO);
- break;
- case INTEL_OUTPUT_LVDS:
- if (IS_MRST(dev))
- crtc_mask = (1 << 0);
- else
- crtc_mask = (1 << 1);
- clone_mask = (1 << INTEL_OUTPUT_LVDS);
- break;
- case INTEL_OUTPUT_MIPI:
- crtc_mask = (1 << 0);
- clone_mask = (1 << INTEL_OUTPUT_MIPI);
- break;
- case INTEL_OUTPUT_MIPI2:
- crtc_mask = (1 << 2);
- clone_mask = (1 << INTEL_OUTPUT_MIPI2);
- break;
- case INTEL_OUTPUT_HDMI:
- /* HDMI on crtc 1 for SoC devices and crtc 0 for
- Cedarview. HDMI on Poulsbo is only via external
- logic */
- if (IS_MFLD(dev) || IS_MRST(dev))
- crtc_mask = (1 << 1);
- else
- crtc_mask = (1 << 0); /* Cedarview */
- clone_mask = (1 << INTEL_OUTPUT_HDMI);
- break;
- }
- encoder->possible_crtcs = crtc_mask;
- encoder->possible_clones =
- psb_intel_connector_clones(dev, clone_mask);
- }
-}
-
-void psb_modeset_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *) dev->dev_private;
- struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
- int i;
-
- drm_mode_config_init(dev);
-
- dev->mode_config.min_width = 0;
- dev->mode_config.min_height = 0;
-
- dev->mode_config.funcs = (void *) &psb_mode_funcs;
-
- /* set memory base */
- /* MRST and PSB should use BAR 2*/
- pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *)
- &(dev->mode_config.fb_base));
-
- /* num pipes is 2 for PSB but 1 for Mrst */
- for (i = 0; i < dev_priv->num_pipe; i++)
- psb_intel_crtc_init(dev, i, mode_dev);
-
- dev->mode_config.max_width = 2048;
- dev->mode_config.max_height = 2048;
-
- psb_setup_outputs(dev);
-}
-
-void psb_modeset_cleanup(struct drm_device *dev)
-{
- mutex_lock(&dev->struct_mutex);
-
- drm_kms_helper_poll_fini(dev);
- psb_fbdev_fini(dev);
- drm_mode_config_cleanup(dev);
-
- mutex_unlock(&dev->struct_mutex);
-}
diff --git a/drivers/staging/gma500/framebuffer.h b/drivers/staging/gma500/framebuffer.h
deleted file mode 100644
index d1b2289447f0..000000000000
--- a/drivers/staging/gma500/framebuffer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2008-2011, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt
- *
- */
-
-#ifndef _FRAMEBUFFER_H_
-#define _FRAMEBUFFER_H_
-
-#include
-#include
-
-#include "psb_drv.h"
-
-struct psb_framebuffer {
- struct drm_framebuffer base;
- struct address_space *addr_space;
- struct fb_info *fbdev;
- struct gtt_range *gtt;
- bool vm_map; /* True if we must undo a vm_map_ram */
-};
-
-struct psb_fbdev {
- struct drm_fb_helper psb_fb_helper;
- struct psb_framebuffer pfb;
-};
-
-#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
-
-extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
-
-#endif
-
diff --git a/drivers/staging/gma500/gem.c b/drivers/staging/gma500/gem.c
deleted file mode 100644
index f6433c037d24..000000000000
--- a/drivers/staging/gma500/gem.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * psb GEM interface
- *
- * Copyright (c) 2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Alan Cox
- *
- * TODO:
- * - we need to work out if the MMU is relevant (eg for
- * accelerated operations on a GEM object)
- */
-
-#include
-#include
-#include "psb_drm.h"
-#include "psb_drv.h"
-
-int psb_gem_init_object(struct drm_gem_object *obj)
-{
- return -EINVAL;
-}
-
-void psb_gem_free_object(struct drm_gem_object *obj)
-{
- struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
- drm_gem_object_release_wrap(obj);
- /* This must occur last as it frees up the memory of the GEM object */
- psb_gtt_free_range(obj->dev, gtt);
-}
-
-int psb_gem_get_aperture(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- return -EINVAL;
-}
-
-/**
- * psb_gem_dumb_map_gtt - buffer mapping for dumb interface
- * @file: our drm client file
- * @dev: drm device
- * @handle: GEM handle to the object (from dumb_create)
- *
- * Do the necessary setup to allow the mapping of the frame buffer
- * into user memory. We don't have to do much here at the moment.
- */
-int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
- uint32_t handle, uint64_t *offset)
-{
- int ret = 0;
- struct drm_gem_object *obj;
-
- if (!(dev->driver->driver_features & DRIVER_GEM))
- return -ENODEV;
-
- mutex_lock(&dev->struct_mutex);
-
- /* GEM does all our handle to object mapping */
- obj = drm_gem_object_lookup(dev, file, handle);
- if (obj == NULL) {
- ret = -ENOENT;
- goto unlock;
- }
- /* What validation is needed here ? */
-
- /* Make it mmapable */
- if (!obj->map_list.map) {
- ret = gem_create_mmap_offset(obj);
- if (ret)
- goto out;
- }
- /* GEM should really work out the hash offsets for us */
- *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
-out:
- drm_gem_object_unreference(obj);
-unlock:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-/**
- * psb_gem_create - create a mappable object
- * @file: the DRM file of the client
- * @dev: our device
- * @size: the size requested
- * @handlep: returned handle (opaque number)
- *
- * Create a GEM object, fill in the boilerplate and attach a handle to
- * it so that userspace can speak about it. This does the core work
- * for the various methods that do/will create GEM objects for things
- */
-static int psb_gem_create(struct drm_file *file,
- struct drm_device *dev, uint64_t size, uint32_t *handlep)
-{
- struct gtt_range *r;
- int ret;
- u32 handle;
-
- size = roundup(size, PAGE_SIZE);
-
- /* Allocate our object - for now a direct gtt range which is not
- stolen memory backed */
- r = psb_gtt_alloc_range(dev, size, "gem", 0);
- if (r == NULL) {
- dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
- return -ENOSPC;
- }
- /* Initialize the extra goodies GEM needs to do all the hard work */
- if (drm_gem_object_init(dev, &r->gem, size) != 0) {
- psb_gtt_free_range(dev, r);
- /* GEM doesn't give an error code so use -ENOMEM */
- dev_err(dev->dev, "GEM init failed for %lld\n", size);
- return -ENOMEM;
- }
- /* Give the object a handle so we can carry it more easily */
- ret = drm_gem_handle_create(file, &r->gem, &handle);
- if (ret) {
- dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
- &r->gem, size);
- drm_gem_object_release(&r->gem);
- psb_gtt_free_range(dev, r);
- return ret;
- }
- /* We have the initial and handle reference but need only one now */
- drm_gem_object_unreference(&r->gem);
- *handlep = handle;
- return 0;
-}
-
-/**
- * psb_gem_dumb_create - create a dumb buffer
- * @drm_file: our client file
- * @dev: our device
- * @args: the requested arguments copied from userspace
- *
- * Allocate a buffer suitable for use for a frame buffer of the
- * form described by user space. Give userspace a handle by which
- * to reference it.
- */
-int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
- struct drm_mode_create_dumb *args)
-{
- args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
- args->size = args->pitch * args->height;
- return psb_gem_create(file, dev, args->size, &args->handle);
-}
-
-/**
- * psb_gem_dumb_destroy - destroy a dumb buffer
- * @file: client file
- * @dev: our DRM device
- * @handle: the object handle
- *
- * Destroy a handle that was created via psb_gem_dumb_create, at least
- * we hope it was created that way. i915 seems to assume the caller
- * does the checking but that might be worth review ! FIXME
- */
-int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
- uint32_t handle)
-{
- /* No special work needed, drop the reference and see what falls out */
- return drm_gem_handle_delete(file, handle);
-}
-
-/**
- * psb_gem_fault - pagefault handler for GEM objects
- * @vma: the VMA of the GEM object
- * @vmf: fault detail
- *
- * Invoked when a fault occurs on an mmap of a GEM managed area. GEM
- * does most of the work for us including the actual map/unmap calls
- * but we need to do the actual page work.
- *
- * This code eventually needs to handle faulting objects in and out
- * of the GTT and repacking it when we run out of space. We can put
- * that off for now and for our simple uses
- *
- * The VMA was set up by GEM. In doing so it also ensured that the
- * vma->vm_private_data points to the GEM object that is backing this
- * mapping.
- */
-int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- struct drm_gem_object *obj;
- struct gtt_range *r;
- int ret;
- unsigned long pfn;
- pgoff_t page_offset;
- struct drm_device *dev;
- struct drm_psb_private *dev_priv;
-
- obj = vma->vm_private_data; /* GEM object */
- dev = obj->dev;
- dev_priv = dev->dev_private;
-
- r = container_of(obj, struct gtt_range, gem); /* Get the gtt range */
-
- /* Make sure we don't parallel update on a fault, nor move or remove
- something from beneath our feet */
- mutex_lock(&dev->struct_mutex);
-
- /* For now the mmap pins the object and it stays pinned. As things
- stand that will do us no harm */
- if (r->mmapping == 0) {
- ret = psb_gtt_pin(r);
- if (ret < 0) {
- dev_err(dev->dev, "gma500: pin failed: %d\n", ret);
- goto fail;
- }
- r->mmapping = 1;
- }
-
- /* Page relative to the VMA start - we must calculate this ourselves
- because vmf->pgoff is the fake GEM offset */
- page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
- >> PAGE_SHIFT;
-
- /* CPU view of the page, don't go via the GART for CPU writes */
- if (r->stolen)
- pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT;
- else
- pfn = page_to_pfn(r->pages[page_offset]);
- ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
-
-fail:
- mutex_unlock(&dev->struct_mutex);
- switch (ret) {
- case 0:
- case -ERESTARTSYS:
- case -EINTR:
- return VM_FAULT_NOPAGE;
- case -ENOMEM:
- return VM_FAULT_OOM;
- default:
- return VM_FAULT_SIGBUS;
- }
-}
-
-static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev,
- int size, u32 *handle)
-{
- struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1);
- if (gtt == NULL)
- return -ENOMEM;
- if (drm_gem_private_object_init(dev, >t->gem, size) != 0)
- goto free_gtt;
- if (drm_gem_handle_create(file, >t->gem, handle) == 0)
- return 0;
-free_gtt:
- psb_gtt_free_range(dev, gtt);
- return -ENOMEM;
-}
-
-/*
- * GEM interfaces for our specific client
- */
-int psb_gem_create_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_psb_gem_create *args = data;
- int ret;
- if (args->flags & PSB_GEM_CREATE_STOLEN) {
- ret = psb_gem_create_stolen(file, dev, args->size,
- &args->handle);
- if (ret == 0)
- return 0;
- /* Fall throguh */
- args->flags &= ~PSB_GEM_CREATE_STOLEN;
- }
- return psb_gem_create(file, dev, args->size, &args->handle);
-}
-
-int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_psb_gem_mmap *args = data;
- return dev->driver->dumb_map_offset(file, dev,
- args->handle, &args->offset);
-}
-
diff --git a/drivers/staging/gma500/gem_glue.c b/drivers/staging/gma500/gem_glue.c
deleted file mode 100644
index daac12120653..000000000000
--- a/drivers/staging/gma500/gem_glue.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include
-#include
-
-void drm_gem_object_release_wrap(struct drm_gem_object *obj)
-{
- /* Remove the list map if one is present */
- if (obj->map_list.map) {
- struct drm_gem_mm *mm = obj->dev->mm_private;
- struct drm_map_list *list = &obj->map_list;
- drm_ht_remove_item(&mm->offset_hash, &list->hash);
- drm_mm_put_block(list->file_offset_node);
- kfree(list->map);
- list->map = NULL;
- }
- drm_gem_object_release(obj);
-}
-
-/**
- * gem_create_mmap_offset - invent an mmap offset
- * @obj: our object
- *
- * Standard implementation of offset generation for mmap as is
- * duplicated in several drivers. This belongs in GEM.
- */
-int gem_create_mmap_offset(struct drm_gem_object *obj)
-{
- struct drm_device *dev = obj->dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_local_map *map;
- int ret;
-
- list = &obj->map_list;
- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
- if (list->map == NULL)
- return -ENOMEM;
- map = list->map;
- map->type = _DRM_GEM;
- map->size = obj->size;
- map->handle = obj;
-
- list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
- obj->size / PAGE_SIZE, 0, 0);
- if (!list->file_offset_node) {
- dev_err(dev->dev, "failed to allocate offset for bo %d\n",
- obj->name);
- ret = -ENOSPC;
- goto free_it;
- }
- list->file_offset_node = drm_mm_get_block(list->file_offset_node,
- obj->size / PAGE_SIZE, 0);
- if (!list->file_offset_node) {
- ret = -ENOMEM;
- goto free_it;
- }
- list->hash.key = list->file_offset_node->start;
- ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
- if (ret) {
- dev_err(dev->dev, "failed to add to map hash\n");
- goto free_mm;
- }
- return 0;
-
-free_mm:
- drm_mm_put_block(list->file_offset_node);
-free_it:
- kfree(list->map);
- list->map = NULL;
- return ret;
-}
diff --git a/drivers/staging/gma500/gem_glue.h b/drivers/staging/gma500/gem_glue.h
deleted file mode 100644
index ce5ce30f74db..000000000000
--- a/drivers/staging/gma500/gem_glue.h
+++ /dev/null
@@ -1,2 +0,0 @@
-extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
-extern int gem_create_mmap_offset(struct drm_gem_object *obj);
diff --git a/drivers/staging/gma500/gtt.c b/drivers/staging/gma500/gtt.c
deleted file mode 100644
index e770bd190a5c..000000000000
--- a/drivers/staging/gma500/gtt.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Thomas Hellstrom
- * Alan Cox
- */
-
-#include
-#include "psb_drv.h"
-
-
-/*
- * GTT resource allocator - manage page mappings in GTT space
- */
-
-/**
- * psb_gtt_mask_pte - generate GTT pte entry
- * @pfn: page number to encode
- * @type: type of memory in the GTT
- *
- * Set the GTT entry for the appropriate memory type.
- */
-static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
-{
- uint32_t mask = PSB_PTE_VALID;
-
- if (type & PSB_MMU_CACHED_MEMORY)
- mask |= PSB_PTE_CACHED;
- if (type & PSB_MMU_RO_MEMORY)
- mask |= PSB_PTE_RO;
- if (type & PSB_MMU_WO_MEMORY)
- mask |= PSB_PTE_WO;
-
- return (pfn << PAGE_SHIFT) | mask;
-}
-
-/**
- * psb_gtt_entry - find the GTT entries for a gtt_range
- * @dev: our DRM device
- * @r: our GTT range
- *
- * Given a gtt_range object return the GTT offset of the page table
- * entries for this gtt_range
- */
-u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- unsigned long offset;
-
- offset = r->resource.start - dev_priv->gtt_mem->start;
-
- return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
-}
-
-/**
- * psb_gtt_insert - put an object into the GTT
- * @dev: our DRM device
- * @r: our GTT range
- *
- * Take our preallocated GTT range and insert the GEM object into
- * the GTT. This is protected via the gtt mutex which the caller
- * must hold.
- */
-static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
-{
- u32 *gtt_slot, pte;
- struct page **pages;
- int i;
-
- if (r->pages == NULL) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- WARN_ON(r->stolen); /* refcount these maybe ? */
-
- gtt_slot = psb_gtt_entry(dev, r);
- pages = r->pages;
-
- /* Make sure changes are visible to the GPU */
- set_pages_array_uc(pages, r->npage);
-
- /* Write our page entries into the GTT itself */
- for (i = r->roll; i < r->npage; i++) {
- pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
- iowrite32(pte, gtt_slot++);
- }
- for (i = 0; i < r->roll; i++) {
- pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
- iowrite32(pte, gtt_slot++);
- }
- /* Make sure all the entries are set before we return */
- ioread32(gtt_slot - 1);
-
- return 0;
-}
-
-/**
- * psb_gtt_remove - remove an object from the GTT
- * @dev: our DRM device
- * @r: our GTT range
- *
- * Remove a preallocated GTT range from the GTT. Overwrite all the
- * page table entries with the dummy page. This is protected via the gtt
- * mutex which the caller must hold.
- */
-static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 *gtt_slot, pte;
- int i;
-
- WARN_ON(r->stolen);
-
- gtt_slot = psb_gtt_entry(dev, r);
- pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);
-
- for (i = 0; i < r->npage; i++)
- iowrite32(pte, gtt_slot++);
- ioread32(gtt_slot - 1);
- set_pages_array_wb(r->pages, r->npage);
-}
-
-/**
- * psb_gtt_roll - set scrolling position
- * @dev: our DRM device
- * @r: the gtt mapping we are using
- * @roll: roll offset
- *
- * Roll an existing pinned mapping by moving the pages through the GTT.
- * This allows us to implement hardware scrolling on the consoles without
- * a 2D engine
- */
-void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
-{
- u32 *gtt_slot, pte;
- int i;
-
- if (roll >= r->npage) {
- WARN_ON(1);
- return;
- }
-
- r->roll = roll;
-
- /* Not currently in the GTT - no worry we will write the mapping at
- the right position when it gets pinned */
- if (!r->stolen && !r->in_gart)
- return;
-
- gtt_slot = psb_gtt_entry(dev, r);
-
- for (i = r->roll; i < r->npage; i++) {
- pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
- iowrite32(pte, gtt_slot++);
- }
- for (i = 0; i < r->roll; i++) {
- pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
- iowrite32(pte, gtt_slot++);
- }
- ioread32(gtt_slot - 1);
-}
-
-/**
- * psb_gtt_attach_pages - attach and pin GEM pages
- * @gt: the gtt range
- *
- * Pin and build an in kernel list of the pages that back our GEM object.
- * While we hold this the pages cannot be swapped out. This is protected
- * via the gtt mutex which the caller must hold.
- */
-static int psb_gtt_attach_pages(struct gtt_range *gt)
-{
- struct inode *inode;
- struct address_space *mapping;
- int i;
- struct page *p;
- int pages = gt->gem.size / PAGE_SIZE;
-
- WARN_ON(gt->pages);
-
- /* This is the shared memory object that backs the GEM resource */
- inode = gt->gem.filp->f_path.dentry->d_inode;
- mapping = inode->i_mapping;
-
- gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
- if (gt->pages == NULL)
- return -ENOMEM;
- gt->npage = pages;
-
- for (i = 0; i < pages; i++) {
- /* FIXME: needs updating as per mail from Hugh Dickins */
- p = read_cache_page_gfp(mapping, i,
- __GFP_COLD | GFP_KERNEL);
- if (IS_ERR(p))
- goto err;
- gt->pages[i] = p;
- }
- return 0;
-
-err:
- while (i--)
- page_cache_release(gt->pages[i]);
- kfree(gt->pages);
- gt->pages = NULL;
- return PTR_ERR(p);
-}
-
-/**
- * psb_gtt_detach_pages - attach and pin GEM pages
- * @gt: the gtt range
- *
- * Undo the effect of psb_gtt_attach_pages. At this point the pages
- * must have been removed from the GTT as they could now be paged out
- * and move bus address. This is protected via the gtt mutex which the
- * caller must hold.
- */
-static void psb_gtt_detach_pages(struct gtt_range *gt)
-{
- int i;
- for (i = 0; i < gt->npage; i++) {
- /* FIXME: do we need to force dirty */
- set_page_dirty(gt->pages[i]);
- page_cache_release(gt->pages[i]);
- }
- kfree(gt->pages);
- gt->pages = NULL;
-}
-
-/**
- * psb_gtt_pin - pin pages into the GTT
- * @gt: range to pin
- *
- * Pin a set of pages into the GTT. The pins are refcounted so that
- * multiple pins need multiple unpins to undo.
- *
- * Non GEM backed objects treat this as a no-op as they are always GTT
- * backed objects.
- */
-int psb_gtt_pin(struct gtt_range *gt)
-{
- int ret = 0;
- struct drm_device *dev = gt->gem.dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- mutex_lock(&dev_priv->gtt_mutex);
-
- if (gt->in_gart == 0 && gt->stolen == 0) {
- ret = psb_gtt_attach_pages(gt);
- if (ret < 0)
- goto out;
- ret = psb_gtt_insert(dev, gt);
- if (ret < 0) {
- psb_gtt_detach_pages(gt);
- goto out;
- }
- }
- gt->in_gart++;
-out:
- mutex_unlock(&dev_priv->gtt_mutex);
- return ret;
-}
-
-/**
- * psb_gtt_unpin - Drop a GTT pin requirement
- * @gt: range to pin
- *
- * Undoes the effect of psb_gtt_pin. On the last drop the GEM object
- * will be removed from the GTT which will also drop the page references
- * and allow the VM to clean up or page stuff.
- *
- * Non GEM backed objects treat this as a no-op as they are always GTT
- * backed objects.
- */
-void psb_gtt_unpin(struct gtt_range *gt)
-{
- struct drm_device *dev = gt->gem.dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- mutex_lock(&dev_priv->gtt_mutex);
-
- WARN_ON(!gt->in_gart);
-
- gt->in_gart--;
- if (gt->in_gart == 0 && gt->stolen == 0) {
- psb_gtt_remove(dev, gt);
- psb_gtt_detach_pages(gt);
- }
- mutex_unlock(&dev_priv->gtt_mutex);
-}
-
-/*
- * GTT resource allocator - allocate and manage GTT address space
- */
-
-/**
- * psb_gtt_alloc_range - allocate GTT address space
- * @dev: Our DRM device
- * @len: length (bytes) of address space required
- * @name: resource name
- * @backed: resource should be backed by stolen pages
- *
- * Ask the kernel core to find us a suitable range of addresses
- * to use for a GTT mapping.
- *
- * Returns a gtt_range structure describing the object, or NULL on
- * error. On successful return the resource is both allocated and marked
- * as in use.
- */
-struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
- const char *name, int backed)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct gtt_range *gt;
- struct resource *r = dev_priv->gtt_mem;
- int ret;
- unsigned long start, end;
-
- if (backed) {
- /* The start of the GTT is the stolen pages */
- start = r->start;
- end = r->start + dev_priv->gtt.stolen_size - 1;
- } else {
- /* The rest we will use for GEM backed objects */
- start = r->start + dev_priv->gtt.stolen_size;
- end = r->end;
- }
-
- gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
- if (gt == NULL)
- return NULL;
- gt->resource.name = name;
- gt->stolen = backed;
- gt->in_gart = backed;
- gt->roll = 0;
- /* Ensure this is set for non GEM objects */
- gt->gem.dev = dev;
- ret = allocate_resource(dev_priv->gtt_mem, >->resource,
- len, start, end, PAGE_SIZE, NULL, NULL);
- if (ret == 0) {
- gt->offset = gt->resource.start - r->start;
- return gt;
- }
- kfree(gt);
- return NULL;
-}
-
-/**
- * psb_gtt_free_range - release GTT address space
- * @dev: our DRM device
- * @gt: a mapping created with psb_gtt_alloc_range
- *
- * Release a resource that was allocated with psb_gtt_alloc_range. If the
- * object has been pinned by mmap users we clean this up here currently.
- */
-void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
-{
- /* Undo the mmap pin if we are destroying the object */
- if (gt->mmapping) {
- psb_gtt_unpin(gt);
- gt->mmapping = 0;
- }
- WARN_ON(gt->in_gart && !gt->stolen);
- release_resource(>->resource);
- kfree(gt);
-}
-
-void psb_gtt_alloc(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- init_rwsem(&dev_priv->gtt.sem);
-}
-
-void psb_gtt_takedown(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (dev_priv->gtt_map) {
- iounmap(dev_priv->gtt_map);
- dev_priv->gtt_map = NULL;
- }
- if (dev_priv->gtt_initialized) {
- pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
- dev_priv->gmch_ctrl);
- PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
- (void) PSB_RVDC32(PSB_PGETBL_CTL);
- }
- if (dev_priv->vram_addr)
- iounmap(dev_priv->gtt_map);
-}
-
-int psb_gtt_init(struct drm_device *dev, int resume)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- unsigned gtt_pages;
- unsigned long stolen_size, vram_stolen_size;
- unsigned i, num_pages;
- unsigned pfn_base;
- uint32_t vram_pages;
- uint32_t dvmt_mode = 0;
- struct psb_gtt *pg;
-
- int ret = 0;
- uint32_t pte;
-
- mutex_init(&dev_priv->gtt_mutex);
-
- psb_gtt_alloc(dev);
- pg = &dev_priv->gtt;
-
- /* Enable the GTT */
- pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
- pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
- dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
-
- dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
- PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
- (void) PSB_RVDC32(PSB_PGETBL_CTL);
-
- /* The root resource we allocate address space from */
- dev_priv->gtt_initialized = 1;
-
- pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
-
- /*
- * The video mmu has a hw bug when accessing 0x0D0000000.
- * Make gatt start at 0x0e000,0000. This doesn't actually
- * matter for us but may do if the video acceleration ever
- * gets opened up.
- */
- pg->mmu_gatt_start = 0xE0000000;
-
- pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
- gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
- >> PAGE_SHIFT;
- /* Some CDV firmware doesn't report this currently. In which case the
- system has 64 gtt pages */
- if (pg->gtt_start == 0 || gtt_pages == 0) {
- dev_err(dev->dev, "GTT PCI BAR not initialized.\n");
- gtt_pages = 64;
- pg->gtt_start = dev_priv->pge_ctl;
- }
-
- pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
- pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
- >> PAGE_SHIFT;
- dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
-
- if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
- static struct resource fudge; /* Preferably peppermint */
- /* This can occur on CDV SDV systems. Fudge it in this case.
- We really don't care what imaginary space is being allocated
- at this point */
- dev_err(dev->dev, "GATT PCI BAR not initialized.\n");
- pg->gatt_start = 0x40000000;
- pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
- /* This is a little confusing but in fact the GTT is providing
- a view from the GPU into memory and not vice versa. As such
- this is really allocating space that is not the same as the
- CPU address space on CDV */
- fudge.start = 0x40000000;
- fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
- fudge.name = "fudge";
- fudge.flags = IORESOURCE_MEM;
- dev_priv->gtt_mem = &fudge;
- }
-
- pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
- vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base
- - PAGE_SIZE;
-
- stolen_size = vram_stolen_size;
-
- printk(KERN_INFO "Stolen memory information\n");
- printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base);
- printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
- vram_stolen_size/1024);
- dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7;
- printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n",
- (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
-
- if (resume && (gtt_pages != pg->gtt_pages) &&
- (stolen_size != pg->stolen_size)) {
- dev_err(dev->dev, "GTT resume error.\n");
- ret = -EINVAL;
- goto out_err;
- }
-
- pg->gtt_pages = gtt_pages;
- pg->stolen_size = stolen_size;
- dev_priv->vram_stolen_size = vram_stolen_size;
-
- /*
- * Map the GTT and the stolen memory area
- */
- dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
- gtt_pages << PAGE_SHIFT);
- if (!dev_priv->gtt_map) {
- dev_err(dev->dev, "Failure to map gtt.\n");
- ret = -ENOMEM;
- goto out_err;
- }
-
- dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
- if (!dev_priv->vram_addr) {
- dev_err(dev->dev, "Failure to map stolen base.\n");
- ret = -ENOMEM;
- goto out_err;
- }
-
- /*
- * Insert vram stolen pages into the GTT
- */
-
- pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
- vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
- printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
- num_pages, pfn_base << PAGE_SHIFT, 0);
- for (i = 0; i < num_pages; ++i) {
- pte = psb_gtt_mask_pte(pfn_base + i, 0);
- iowrite32(pte, dev_priv->gtt_map + i);
- }
-
- /*
- * Init rest of GTT to the scratch page to avoid accidents or scribbles
- */
-
- pfn_base = page_to_pfn(dev_priv->scratch_page);
- pte = psb_gtt_mask_pte(pfn_base, 0);
- for (; i < gtt_pages; ++i)
- iowrite32(pte, dev_priv->gtt_map + i);
-
- (void) ioread32(dev_priv->gtt_map + i - 1);
- return 0;
-
-out_err:
- psb_gtt_takedown(dev);
- return ret;
-}
diff --git a/drivers/staging/gma500/gtt.h b/drivers/staging/gma500/gtt.h
deleted file mode 100644
index aa1742387f5a..000000000000
--- a/drivers/staging/gma500/gtt.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2008, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_GTT_H_
-#define _PSB_GTT_H_
-
-#include
-
-/* This wants cleaning up with respect to the psb_dev and un-needed stuff */
-struct psb_gtt {
- uint32_t gatt_start;
- uint32_t mmu_gatt_start;
- uint32_t gtt_start;
- uint32_t gtt_phys_start;
- unsigned gtt_pages;
- unsigned gatt_pages;
- unsigned long stolen_size;
- unsigned long vram_stolen_size;
- struct rw_semaphore sem;
-};
-
-/* Exported functions */
-extern int psb_gtt_init(struct drm_device *dev, int resume);
-extern void psb_gtt_takedown(struct drm_device *dev);
-
-/* Each gtt_range describes an allocation in the GTT area */
-struct gtt_range {
- struct resource resource; /* Resource for our allocation */
- u32 offset; /* GTT offset of our object */
- struct drm_gem_object gem; /* GEM high level stuff */
- int in_gart; /* Currently in the GART (ref ct) */
- bool stolen; /* Backed from stolen RAM */
- bool mmapping; /* Is mmappable */
- struct page **pages; /* Backing pages if present */
- int npage; /* Number of backing pages */
- int roll; /* Roll applied to the GTT entries */
-};
-
-extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
- const char *name, int backed);
-extern void psb_gtt_kref_put(struct gtt_range *gt);
-extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
-extern int psb_gtt_pin(struct gtt_range *gt);
-extern void psb_gtt_unpin(struct gtt_range *gt);
-extern void psb_gtt_roll(struct drm_device *dev,
- struct gtt_range *gt, int roll);
-
-#endif
diff --git a/drivers/staging/gma500/intel_bios.c b/drivers/staging/gma500/intel_bios.c
deleted file mode 100644
index 096757f9bc89..000000000000
--- a/drivers/staging/gma500/intel_bios.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (c) 2006 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt
- *
- */
-#include
-#include
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-
-
-static void *find_section(struct bdb_header *bdb, int section_id)
-{
- u8 *base = (u8 *)bdb;
- int index = 0;
- u16 total, current_size;
- u8 current_id;
-
- /* skip to first section */
- index += bdb->header_size;
- total = bdb->bdb_size;
-
- /* walk the sections looking for section_id */
- while (index < total) {
- current_id = *(base + index);
- index++;
- current_size = *((u16 *)(base + index));
- index += 2;
- if (current_id == section_id)
- return base + index;
- index += current_size;
- }
-
- return NULL;
-}
-
-static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
- struct lvds_dvo_timing *dvo_timing)
-{
- panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
- dvo_timing->hactive_lo;
- panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
- ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
- panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
- dvo_timing->hsync_pulse_width;
- panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
- ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
-
- panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
- dvo_timing->vactive_lo;
- panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
- dvo_timing->vsync_off;
- panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
- dvo_timing->vsync_pulse_width;
- panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
- ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
- panel_fixed_mode->clock = dvo_timing->clock * 10;
- panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
-
- /* Some VBTs have bogus h/vtotal values */
- if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
- panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
- if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
- panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
-
- drm_mode_set_name(panel_fixed_mode);
-}
-
-static void parse_backlight_data(struct drm_psb_private *dev_priv,
- struct bdb_header *bdb)
-{
- struct bdb_lvds_backlight *vbt_lvds_bl = NULL;
- struct bdb_lvds_backlight *lvds_bl;
- u8 p_type = 0;
- void *bl_start = NULL;
- struct bdb_lvds_options *lvds_opts
- = find_section(bdb, BDB_LVDS_OPTIONS);
-
- dev_priv->lvds_bl = NULL;
-
- if (lvds_opts)
- p_type = lvds_opts->panel_type;
- else
- return;
-
- bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
- vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
-
- lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL);
- if (!lvds_bl) {
- dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
- return;
- }
- memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
- dev_priv->lvds_bl = lvds_bl;
-}
-
-/* Try to find integrated panel data */
-static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
- struct bdb_header *bdb)
-{
- struct bdb_lvds_options *lvds_options;
- struct bdb_lvds_lfp_data *lvds_lfp_data;
- struct bdb_lvds_lfp_data_entry *entry;
- struct lvds_dvo_timing *dvo_timing;
- struct drm_display_mode *panel_fixed_mode;
-
- /* Defaults if we can't find VBT info */
- dev_priv->lvds_dither = 0;
- dev_priv->lvds_vbt = 0;
-
- lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
- if (!lvds_options)
- return;
-
- dev_priv->lvds_dither = lvds_options->pixel_dither;
- if (lvds_options->panel_type == 0xff)
- return;
-
- lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
- if (!lvds_lfp_data)
- return;
-
-
- entry = &lvds_lfp_data->data[lvds_options->panel_type];
- dvo_timing = &entry->dvo_timing;
-
- panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),
- GFP_KERNEL);
- if (panel_fixed_mode == NULL) {
- dev_err(dev_priv->dev->dev, "out of memory for fixed panel mode\n");
- return;
- }
-
- dev_priv->lvds_vbt = 1;
- fill_detail_timing_data(panel_fixed_mode, dvo_timing);
-
- if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
- dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
- drm_mode_debug_printmodeline(panel_fixed_mode);
- } else {
- dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n");
- dev_priv->lvds_vbt = 0;
- kfree(panel_fixed_mode);
- }
- return;
-}
-
-/* Try to find sdvo panel data */
-static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv,
- struct bdb_header *bdb)
-{
- struct bdb_sdvo_lvds_options *sdvo_lvds_options;
- struct lvds_dvo_timing *dvo_timing;
- struct drm_display_mode *panel_fixed_mode;
-
- dev_priv->sdvo_lvds_vbt_mode = NULL;
-
- sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
- if (!sdvo_lvds_options)
- return;
-
- dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
- if (!dvo_timing)
- return;
-
- panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
-
- if (!panel_fixed_mode)
- return;
-
- fill_detail_timing_data(panel_fixed_mode,
- dvo_timing + sdvo_lvds_options->panel_type);
-
- dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
-
- return;
-}
-
-static void parse_general_features(struct drm_psb_private *dev_priv,
- struct bdb_header *bdb)
-{
- struct bdb_general_features *general;
-
- /* Set sensible defaults in case we can't find the general block */
- dev_priv->int_tv_support = 1;
- dev_priv->int_crt_support = 1;
-
- general = find_section(bdb, BDB_GENERAL_FEATURES);
- if (general) {
- dev_priv->int_tv_support = general->int_tv_support;
- dev_priv->int_crt_support = general->int_crt_support;
- dev_priv->lvds_use_ssc = general->enable_ssc;
-
- if (dev_priv->lvds_use_ssc) {
- dev_priv->lvds_ssc_freq
- = general->ssc_freq ? 100 : 96;
- }
- }
-}
-
-/**
- * psb_intel_init_bios - initialize VBIOS settings & find VBT
- * @dev: DRM device
- *
- * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers
- * to appropriate values.
- *
- * VBT existence is a sanity check that is relied on by other i830_bios.c code.
- * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
- * feed an updated VBT back through that, compared to what we'll fetch using
- * this method of groping around in the BIOS data.
- *
- * Returns 0 on success, nonzero on failure.
- */
-bool psb_intel_init_bios(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct pci_dev *pdev = dev->pdev;
- struct vbt_header *vbt = NULL;
- struct bdb_header *bdb;
- u8 __iomem *bios;
- size_t size;
- int i;
-
- bios = pci_map_rom(pdev, &size);
- if (!bios)
- return -1;
-
- /* Scour memory looking for the VBT signature */
- for (i = 0; i + 4 < size; i++) {
- if (!memcmp(bios + i, "$VBT", 4)) {
- vbt = (struct vbt_header *)(bios + i);
- break;
- }
- }
-
- if (!vbt) {
- dev_err(dev->dev, "VBT signature missing\n");
- pci_unmap_rom(pdev, bios);
- return -1;
- }
-
- bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
-
- /* Grab useful general definitions */
- parse_general_features(dev_priv, bdb);
- parse_lfp_panel_data(dev_priv, bdb);
- parse_sdvo_panel_data(dev_priv, bdb);
- parse_backlight_data(dev_priv, bdb);
-
- pci_unmap_rom(pdev, bios);
-
- return 0;
-}
-
-/**
- * Destroy and free VBT data
- */
-void psb_intel_destroy_bios(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_display_mode *sdvo_lvds_vbt_mode =
- dev_priv->sdvo_lvds_vbt_mode;
- struct drm_display_mode *lfp_lvds_vbt_mode =
- dev_priv->lfp_lvds_vbt_mode;
- struct bdb_lvds_backlight *lvds_bl =
- dev_priv->lvds_bl;
-
- /*free sdvo panel mode*/
- if (sdvo_lvds_vbt_mode) {
- dev_priv->sdvo_lvds_vbt_mode = NULL;
- kfree(sdvo_lvds_vbt_mode);
- }
-
- if (lfp_lvds_vbt_mode) {
- dev_priv->lfp_lvds_vbt_mode = NULL;
- kfree(lfp_lvds_vbt_mode);
- }
-
- if (lvds_bl) {
- dev_priv->lvds_bl = NULL;
- kfree(lvds_bl);
- }
-}
diff --git a/drivers/staging/gma500/intel_bios.h b/drivers/staging/gma500/intel_bios.h
deleted file mode 100644
index 70f1bf018183..000000000000
--- a/drivers/staging/gma500/intel_bios.h
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (c) 2006 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt
- *
- */
-
-#ifndef _I830_BIOS_H_
-#define _I830_BIOS_H_
-
-#include
-
-struct vbt_header {
- u8 signature[20]; /**< Always starts with 'VBT$' */
- u16 version; /**< decimal */
- u16 header_size; /**< in bytes */
- u16 vbt_size; /**< in bytes */
- u8 vbt_checksum;
- u8 reserved0;
- u32 bdb_offset; /**< from beginning of VBT */
- u32 aim_offset[4]; /**< from beginning of VBT */
-} __attribute__((packed));
-
-
-struct bdb_header {
- u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */
- u16 version; /**< decimal */
- u16 header_size; /**< in bytes */
- u16 bdb_size; /**< in bytes */
-};
-
-/* strictly speaking, this is a "skip" block, but it has interesting info */
-struct vbios_data {
- u8 type; /* 0 == desktop, 1 == mobile */
- u8 relstage;
- u8 chipset;
- u8 lvds_present:1;
- u8 tv_present:1;
- u8 rsvd2:6; /* finish byte */
- u8 rsvd3[4];
- u8 signon[155];
- u8 copyright[61];
- u16 code_segment;
- u8 dos_boot_mode;
- u8 bandwidth_percent;
- u8 rsvd4; /* popup memory size */
- u8 resize_pci_bios;
- u8 rsvd5; /* is crt already on ddc2 */
-} __attribute__((packed));
-
-/*
- * There are several types of BIOS data blocks (BDBs), each block has
- * an ID and size in the first 3 bytes (ID in first, size in next 2).
- * Known types are listed below.
- */
-#define BDB_GENERAL_FEATURES 1
-#define BDB_GENERAL_DEFINITIONS 2
-#define BDB_OLD_TOGGLE_LIST 3
-#define BDB_MODE_SUPPORT_LIST 4
-#define BDB_GENERIC_MODE_TABLE 5
-#define BDB_EXT_MMIO_REGS 6
-#define BDB_SWF_IO 7
-#define BDB_SWF_MMIO 8
-#define BDB_DOT_CLOCK_TABLE 9
-#define BDB_MODE_REMOVAL_TABLE 10
-#define BDB_CHILD_DEVICE_TABLE 11
-#define BDB_DRIVER_FEATURES 12
-#define BDB_DRIVER_PERSISTENCE 13
-#define BDB_EXT_TABLE_PTRS 14
-#define BDB_DOT_CLOCK_OVERRIDE 15
-#define BDB_DISPLAY_SELECT 16
-/* 17 rsvd */
-#define BDB_DRIVER_ROTATION 18
-#define BDB_DISPLAY_REMOVE 19
-#define BDB_OEM_CUSTOM 20
-#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */
-#define BDB_SDVO_LVDS_OPTIONS 22
-#define BDB_SDVO_PANEL_DTDS 23
-#define BDB_SDVO_LVDS_PNP_IDS 24
-#define BDB_SDVO_LVDS_POWER_SEQ 25
-#define BDB_TV_OPTIONS 26
-#define BDB_LVDS_OPTIONS 40
-#define BDB_LVDS_LFP_DATA_PTRS 41
-#define BDB_LVDS_LFP_DATA 42
-#define BDB_LVDS_BACKLIGHT 43
-#define BDB_LVDS_POWER 44
-#define BDB_SKIP 254 /* VBIOS private block, ignore */
-
-struct bdb_general_features {
- /* bits 1 */
- u8 panel_fitting:2;
- u8 flexaim:1;
- u8 msg_enable:1;
- u8 clear_screen:3;
- u8 color_flip:1;
-
- /* bits 2 */
- u8 download_ext_vbt:1;
- u8 enable_ssc:1;
- u8 ssc_freq:1;
- u8 enable_lfp_on_override:1;
- u8 disable_ssc_ddt:1;
- u8 rsvd8:3; /* finish byte */
-
- /* bits 3 */
- u8 disable_smooth_vision:1;
- u8 single_dvi:1;
- u8 rsvd9:6; /* finish byte */
-
- /* bits 4 */
- u8 legacy_monitor_detect;
-
- /* bits 5 */
- u8 int_crt_support:1;
- u8 int_tv_support:1;
- u8 rsvd11:6; /* finish byte */
-} __attribute__((packed));
-
-struct bdb_general_definitions {
- /* DDC GPIO */
- u8 crt_ddc_gmbus_pin;
-
- /* DPMS bits */
- u8 dpms_acpi:1;
- u8 skip_boot_crt_detect:1;
- u8 dpms_aim:1;
- u8 rsvd1:5; /* finish byte */
-
- /* boot device bits */
- u8 boot_display[2];
- u8 child_dev_size;
-
- /* device info */
- u8 tv_or_lvds_info[33];
- u8 dev1[33];
- u8 dev2[33];
- u8 dev3[33];
- u8 dev4[33];
- /* may be another device block here on some platforms */
-};
-
-struct bdb_lvds_options {
- u8 panel_type;
- u8 rsvd1;
- /* LVDS capabilities, stored in a dword */
- u8 pfit_mode:2;
- u8 pfit_text_mode_enhanced:1;
- u8 pfit_gfx_mode_enhanced:1;
- u8 pfit_ratio_auto:1;
- u8 pixel_dither:1;
- u8 lvds_edid:1;
- u8 rsvd2:1;
- u8 rsvd4;
-} __attribute__((packed));
-
-struct bdb_lvds_backlight {
- u8 type:2;
- u8 pol:1;
- u8 gpio:3;
- u8 gmbus:2;
- u16 freq;
- u8 minbrightness;
- u8 i2caddr;
- u8 brightnesscmd;
- /*FIXME: more...*/
-} __attribute__((packed));
-
-/* LFP pointer table contains entries to the struct below */
-struct bdb_lvds_lfp_data_ptr {
- u16 fp_timing_offset; /* offsets are from start of bdb */
- u8 fp_table_size;
- u16 dvo_timing_offset;
- u8 dvo_table_size;
- u16 panel_pnp_id_offset;
- u8 pnp_table_size;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data_ptrs {
- u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
- struct bdb_lvds_lfp_data_ptr ptr[16];
-} __attribute__((packed));
-
-/* LFP data has 3 blocks per entry */
-struct lvds_fp_timing {
- u16 x_res;
- u16 y_res;
- u32 lvds_reg;
- u32 lvds_reg_val;
- u32 pp_on_reg;
- u32 pp_on_reg_val;
- u32 pp_off_reg;
- u32 pp_off_reg_val;
- u32 pp_cycle_reg;
- u32 pp_cycle_reg_val;
- u32 pfit_reg;
- u32 pfit_reg_val;
- u16 terminator;
-} __attribute__((packed));
-
-struct lvds_dvo_timing {
- u16 clock; /**< In 10khz */
- u8 hactive_lo;
- u8 hblank_lo;
- u8 hblank_hi:4;
- u8 hactive_hi:4;
- u8 vactive_lo;
- u8 vblank_lo;
- u8 vblank_hi:4;
- u8 vactive_hi:4;
- u8 hsync_off_lo;
- u8 hsync_pulse_width;
- u8 vsync_pulse_width:4;
- u8 vsync_off:4;
- u8 rsvd0:6;
- u8 hsync_off_hi:2;
- u8 h_image;
- u8 v_image;
- u8 max_hv;
- u8 h_border;
- u8 v_border;
- u8 rsvd1:3;
- u8 digital:2;
- u8 vsync_positive:1;
- u8 hsync_positive:1;
- u8 rsvd2:1;
-} __attribute__((packed));
-
-struct lvds_pnp_id {
- u16 mfg_name;
- u16 product_code;
- u32 serial;
- u8 mfg_week;
- u8 mfg_year;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data_entry {
- struct lvds_fp_timing fp_timing;
- struct lvds_dvo_timing dvo_timing;
- struct lvds_pnp_id pnp_id;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data {
- struct bdb_lvds_lfp_data_entry data[16];
-} __attribute__((packed));
-
-struct aimdb_header {
- char signature[16];
- char oem_device[20];
- u16 aimdb_version;
- u16 aimdb_header_size;
- u16 aimdb_size;
-} __attribute__((packed));
-
-struct aimdb_block {
- u8 aimdb_id;
- u16 aimdb_size;
-} __attribute__((packed));
-
-struct vch_panel_data {
- u16 fp_timing_offset;
- u8 fp_timing_size;
- u16 dvo_timing_offset;
- u8 dvo_timing_size;
- u16 text_fitting_offset;
- u8 text_fitting_size;
- u16 graphics_fitting_offset;
- u8 graphics_fitting_size;
-} __attribute__((packed));
-
-struct vch_bdb_22 {
- struct aimdb_block aimdb_block;
- struct vch_panel_data panels[16];
-} __attribute__((packed));
-
-struct bdb_sdvo_lvds_options {
- u8 panel_backlight;
- u8 h40_set_panel_type;
- u8 panel_type;
- u8 ssc_clk_freq;
- u16 als_low_trip;
- u16 als_high_trip;
- u8 sclalarcoeff_tab_row_num;
- u8 sclalarcoeff_tab_row_size;
- u8 coefficient[8];
- u8 panel_misc_bits_1;
- u8 panel_misc_bits_2;
- u8 panel_misc_bits_3;
- u8 panel_misc_bits_4;
-} __attribute__((packed));
-
-
-extern bool psb_intel_init_bios(struct drm_device *dev);
-extern void psb_intel_destroy_bios(struct drm_device *dev);
-
-/*
- * Driver<->VBIOS interaction occurs through scratch bits in
- * GR18 & SWF*.
- */
-
-/* GR18 bits are set on display switch and hotkey events */
-#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */
-#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */
-#define GR18_HK_NONE (0x0<<3)
-#define GR18_HK_LFP_STRETCH (0x1<<3)
-#define GR18_HK_TOGGLE_DISP (0x2<<3)
-#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */
-#define GR18_HK_POPUP_DISABLED (0x6<<3)
-#define GR18_HK_POPUP_ENABLED (0x7<<3)
-#define GR18_HK_PFIT (0x8<<3)
-#define GR18_HK_APM_CHANGE (0xa<<3)
-#define GR18_HK_MULTIPLE (0xc<<3)
-#define GR18_USER_INT_EN (1<<2)
-#define GR18_A0000_FLUSH_EN (1<<1)
-#define GR18_SMM_EN (1<<0)
-
-/* Set by driver, cleared by VBIOS */
-#define SWF00_YRES_SHIFT 16
-#define SWF00_XRES_SHIFT 0
-#define SWF00_RES_MASK 0xffff
-
-/* Set by VBIOS at boot time and driver at runtime */
-#define SWF01_TV2_FORMAT_SHIFT 8
-#define SWF01_TV1_FORMAT_SHIFT 0
-#define SWF01_TV_FORMAT_MASK 0xffff
-
-#define SWF10_VBIOS_BLC_I2C_EN (1<<29)
-#define SWF10_GTT_OVERRIDE_EN (1<<28)
-#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */
-#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
-#define SWF10_OLD_TOGGLE 0x0
-#define SWF10_TOGGLE_LIST_1 0x1
-#define SWF10_TOGGLE_LIST_2 0x2
-#define SWF10_TOGGLE_LIST_3 0x3
-#define SWF10_TOGGLE_LIST_4 0x4
-#define SWF10_PANNING_EN (1<<23)
-#define SWF10_DRIVER_LOADED (1<<22)
-#define SWF10_EXTENDED_DESKTOP (1<<21)
-#define SWF10_EXCLUSIVE_MODE (1<<20)
-#define SWF10_OVERLAY_EN (1<<19)
-#define SWF10_PLANEB_HOLDOFF (1<<18)
-#define SWF10_PLANEA_HOLDOFF (1<<17)
-#define SWF10_VGA_HOLDOFF (1<<16)
-#define SWF10_ACTIVE_DISP_MASK 0xffff
-#define SWF10_PIPEB_LFP2 (1<<15)
-#define SWF10_PIPEB_EFP2 (1<<14)
-#define SWF10_PIPEB_TV2 (1<<13)
-#define SWF10_PIPEB_CRT2 (1<<12)
-#define SWF10_PIPEB_LFP (1<<11)
-#define SWF10_PIPEB_EFP (1<<10)
-#define SWF10_PIPEB_TV (1<<9)
-#define SWF10_PIPEB_CRT (1<<8)
-#define SWF10_PIPEA_LFP2 (1<<7)
-#define SWF10_PIPEA_EFP2 (1<<6)
-#define SWF10_PIPEA_TV2 (1<<5)
-#define SWF10_PIPEA_CRT2 (1<<4)
-#define SWF10_PIPEA_LFP (1<<3)
-#define SWF10_PIPEA_EFP (1<<2)
-#define SWF10_PIPEA_TV (1<<1)
-#define SWF10_PIPEA_CRT (1<<0)
-
-#define SWF11_MEMORY_SIZE_SHIFT 16
-#define SWF11_SV_TEST_EN (1<<15)
-#define SWF11_IS_AGP (1<<14)
-#define SWF11_DISPLAY_HOLDOFF (1<<13)
-#define SWF11_DPMS_REDUCED (1<<12)
-#define SWF11_IS_VBE_MODE (1<<11)
-#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */
-#define SWF11_DPMS_MASK 0x07
-#define SWF11_DPMS_OFF (1<<2)
-#define SWF11_DPMS_SUSPEND (1<<1)
-#define SWF11_DPMS_STANDBY (1<<0)
-#define SWF11_DPMS_ON 0
-
-#define SWF14_GFX_PFIT_EN (1<<31)
-#define SWF14_TEXT_PFIT_EN (1<<30)
-#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */
-#define SWF14_POPUP_EN (1<<28)
-#define SWF14_DISPLAY_HOLDOFF (1<<27)
-#define SWF14_DISP_DETECT_EN (1<<26)
-#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
-#define SWF14_DRIVER_STATUS (1<<24)
-#define SWF14_OS_TYPE_WIN9X (1<<23)
-#define SWF14_OS_TYPE_WINNT (1<<22)
-/* 21:19 rsvd */
-#define SWF14_PM_TYPE_MASK 0x00070000
-#define SWF14_PM_ACPI_VIDEO (0x4 << 16)
-#define SWF14_PM_ACPI (0x3 << 16)
-#define SWF14_PM_APM_12 (0x2 << 16)
-#define SWF14_PM_APM_11 (0x1 << 16)
-#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */
- /* if GR18 indicates a display switch */
-#define SWF14_DS_PIPEB_LFP2_EN (1<<15)
-#define SWF14_DS_PIPEB_EFP2_EN (1<<14)
-#define SWF14_DS_PIPEB_TV2_EN (1<<13)
-#define SWF14_DS_PIPEB_CRT2_EN (1<<12)
-#define SWF14_DS_PIPEB_LFP_EN (1<<11)
-#define SWF14_DS_PIPEB_EFP_EN (1<<10)
-#define SWF14_DS_PIPEB_TV_EN (1<<9)
-#define SWF14_DS_PIPEB_CRT_EN (1<<8)
-#define SWF14_DS_PIPEA_LFP2_EN (1<<7)
-#define SWF14_DS_PIPEA_EFP2_EN (1<<6)
-#define SWF14_DS_PIPEA_TV2_EN (1<<5)
-#define SWF14_DS_PIPEA_CRT2_EN (1<<4)
-#define SWF14_DS_PIPEA_LFP_EN (1<<3)
-#define SWF14_DS_PIPEA_EFP_EN (1<<2)
-#define SWF14_DS_PIPEA_TV_EN (1<<1)
-#define SWF14_DS_PIPEA_CRT_EN (1<<0)
- /* if GR18 indicates a panel fitting request */
-#define SWF14_PFIT_EN (1<<0) /* 0 means disable */
- /* if GR18 indicates an APM change request */
-#define SWF14_APM_HIBERNATE 0x4
-#define SWF14_APM_SUSPEND 0x3
-#define SWF14_APM_STANDBY 0x1
-#define SWF14_APM_RESTORE 0x0
-
-#endif /* _I830_BIOS_H_ */
diff --git a/drivers/staging/gma500/intel_i2c.c b/drivers/staging/gma500/intel_i2c.c
deleted file mode 100644
index 51cbf65268e6..000000000000
--- a/drivers/staging/gma500/intel_i2c.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright © 2006-2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt
- */
-
-#include
-#include
-#include
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-
-/*
- * Intel GPIO access functions
- */
-
-#define I2C_RISEFALL_TIME 20
-
-static int get_clock(void *data)
-{
- struct psb_intel_i2c_chan *chan = data;
- struct drm_device *dev = chan->drm_dev;
- u32 val;
-
- val = REG_READ(chan->reg);
- return (val & GPIO_CLOCK_VAL_IN) != 0;
-}
-
-static int get_data(void *data)
-{
- struct psb_intel_i2c_chan *chan = data;
- struct drm_device *dev = chan->drm_dev;
- u32 val;
-
- val = REG_READ(chan->reg);
- return (val & GPIO_DATA_VAL_IN) != 0;
-}
-
-static void set_clock(void *data, int state_high)
-{
- struct psb_intel_i2c_chan *chan = data;
- struct drm_device *dev = chan->drm_dev;
- u32 reserved = 0, clock_bits;
-
- /* On most chips, these bits must be preserved in software. */
- reserved =
- REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
- GPIO_CLOCK_PULLUP_DISABLE);
-
- if (state_high)
- clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
- else
- clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
- GPIO_CLOCK_VAL_MASK;
- REG_WRITE(chan->reg, reserved | clock_bits);
- udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
-}
-
-static void set_data(void *data, int state_high)
-{
- struct psb_intel_i2c_chan *chan = data;
- struct drm_device *dev = chan->drm_dev;
- u32 reserved = 0, data_bits;
-
- /* On most chips, these bits must be preserved in software. */
- reserved =
- REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
- GPIO_CLOCK_PULLUP_DISABLE);
-
- if (state_high)
- data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
- else
- data_bits =
- GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
- GPIO_DATA_VAL_MASK;
-
- REG_WRITE(chan->reg, reserved | data_bits);
- udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
-}
-
-/**
- * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
- * @dev: DRM device
- * @output: driver specific output device
- * @reg: GPIO reg to use
- * @name: name for this bus
- *
- * Creates and registers a new i2c bus with the Linux i2c layer, for use
- * in output probing and control (e.g. DDC or SDVO control functions).
- *
- * Possible values for @reg include:
- * %GPIOA
- * %GPIOB
- * %GPIOC
- * %GPIOD
- * %GPIOE
- * %GPIOF
- * %GPIOG
- * %GPIOH
- * see PRM for details on how these different busses are used.
- */
-struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
- const u32 reg, const char *name)
-{
- struct psb_intel_i2c_chan *chan;
-
- chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL);
- if (!chan)
- goto out_free;
-
- chan->drm_dev = dev;
- chan->reg = reg;
- snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
- chan->adapter.owner = THIS_MODULE;
- chan->adapter.algo_data = &chan->algo;
- chan->adapter.dev.parent = &dev->pdev->dev;
- chan->algo.setsda = set_data;
- chan->algo.setscl = set_clock;
- chan->algo.getsda = get_data;
- chan->algo.getscl = get_clock;
- chan->algo.udelay = 20;
- chan->algo.timeout = usecs_to_jiffies(2200);
- chan->algo.data = chan;
-
- i2c_set_adapdata(&chan->adapter, chan);
-
- if (i2c_bit_add_bus(&chan->adapter))
- goto out_free;
-
- /* JJJ: raise SCL and SDA? */
- set_data(chan, 1);
- set_clock(chan, 1);
- udelay(20);
-
- return chan;
-
-out_free:
- kfree(chan);
- return NULL;
-}
-
-/**
- * psb_intel_i2c_destroy - unregister and free i2c bus resources
- * @output: channel to free
- *
- * Unregister the adapter from the i2c layer, then free the structure.
- */
-void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan)
-{
- if (!chan)
- return;
-
- i2c_del_adapter(&chan->adapter);
- kfree(chan);
-}
diff --git a/drivers/staging/gma500/intel_opregion.c b/drivers/staging/gma500/intel_opregion.c
deleted file mode 100644
index d946bc1b17bf..000000000000
--- a/drivers/staging/gma500/intel_opregion.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * FIXME: resolve with the i915 version
- */
-
-#include "psb_drv.h"
-
-struct opregion_header {
- u8 signature[16];
- u32 size;
- u32 opregion_ver;
- u8 bios_ver[32];
- u8 vbios_ver[16];
- u8 driver_ver[16];
- u32 mboxes;
- u8 reserved[164];
-} __packed;
-
-struct opregion_apci {
- /*FIXME: add it later*/
-} __packed;
-
-struct opregion_swsci {
- /*FIXME: add it later*/
-} __packed;
-
-struct opregion_acpi {
- /*FIXME: add it later*/
-} __packed;
-
-int gma_intel_opregion_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 opregion_phy;
- void *base;
- u32 *lid_state;
-
- dev_priv->lid_state = NULL;
-
- pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy);
- if (opregion_phy == 0)
- return -ENOTSUPP;
-
- base = ioremap(opregion_phy, 8*1024);
- if (!base)
- return -ENOMEM;
-
- lid_state = base + 0x01ac;
-
- dev_priv->lid_state = lid_state;
- dev_priv->lid_last_state = readl(lid_state);
- return 0;
-}
-
-int gma_intel_opregion_exit(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- if (dev_priv->lid_state)
- iounmap(dev_priv->lid_state);
- return 0;
-}
diff --git a/drivers/staging/gma500/mdfld_device.c b/drivers/staging/gma500/mdfld_device.c
deleted file mode 100644
index f47aeb7a2039..000000000000
--- a/drivers/staging/gma500/mdfld_device.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include
-#include
-#include
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_output.h"
-#include "mid_bios.h"
-
-/*
- * Provide the Medfield specific backlight management
- */
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-static int mdfld_brightness;
-struct backlight_device *mdfld_backlight_device;
-
-static int mfld_set_brightness(struct backlight_device *bd)
-{
- struct drm_device *dev = bl_get_data(mdfld_backlight_device);
- struct drm_psb_private *dev_priv = dev->dev_private;
- int level = bd->props.brightness;
-
- /* Percentage 1-100% being valid */
- if (level < 1)
- level = 1;
-
- if (gma_power_begin(dev, 0)) {
- /* Calculate and set the brightness value */
- u32 adjusted_level;
-
- /* Adjust the backlight level with the percent in
- * dev_priv->blc_adj2;
- */
- adjusted_level = level * dev_priv->blc_adj2;
- adjusted_level = adjusted_level / 100;
-#if 0
-#ifndef CONFIG_MDFLD_DSI_DPU
- if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) &&
- (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){
- mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0);
- dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level);
- }
-#endif
- mdfld_dsi_brightness_control(dev, 0, adjusted_level);
-
- if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2))
- mdfld_dsi_brightness_control(dev, 2, adjusted_level);
-#endif
- gma_power_end(dev);
- }
- mdfld_brightness = level;
- return 0;
-}
-
-int psb_get_brightness(struct backlight_device *bd)
-{
- /* return locally cached var instead of HW read (due to DPST etc.) */
- /* FIXME: ideally return actual value in case firmware fiddled with
- it */
- return mdfld_brightness;
-}
-
-static const struct backlight_ops mfld_ops = {
- .get_brightness = psb_get_brightness,
- .update_status = mfld_set_brightness,
-};
-
-static int mdfld_backlight_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct backlight_properties props;
- memset(&props, 0, sizeof(struct backlight_properties));
- props.max_brightness = 100;
- props.type = BACKLIGHT_PLATFORM;
-
- mdfld_backlight_device = backlight_device_register("mfld-bl",
- NULL, (void *)dev, &mfld_ops, &props);
-
- if (IS_ERR(mdfld_backlight_device))
- return PTR_ERR(mdfld_backlight_device);
-
- dev_priv->blc_adj1 = 100;
- dev_priv->blc_adj2 = 100;
- mdfld_backlight_device->props.brightness = 100;
- mdfld_backlight_device->props.max_brightness = 100;
- backlight_update_status(mdfld_backlight_device);
- dev_priv->backlight_device = mdfld_backlight_device;
- return 0;
-}
-
-#endif
-
-/*
- * Provide the Medfield specific chip logic and low level methods for
- * power management.
- */
-
-static void mdfld_init_pm(struct drm_device *dev)
-{
- /* No work needed here yet */
-}
-
-/**
- * mdfld_save_display_registers - save registers for pipe
- * @dev: our device
- * @pipe: pipe to save
- *
- * Save the pipe state of the device before we power it off. Keep everything
- * we need to put it back again
- */
-static int mdfld_save_display_registers(struct drm_device *dev, int pipe)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- int i;
-
- /* register */
- u32 dpll_reg = MRST_DPLL_A;
- u32 fp_reg = MRST_FPA0;
- u32 pipeconf_reg = PIPEACONF;
- u32 htot_reg = HTOTAL_A;
- u32 hblank_reg = HBLANK_A;
- u32 hsync_reg = HSYNC_A;
- u32 vtot_reg = VTOTAL_A;
- u32 vblank_reg = VBLANK_A;
- u32 vsync_reg = VSYNC_A;
- u32 pipesrc_reg = PIPEASRC;
- u32 dspstride_reg = DSPASTRIDE;
- u32 dsplinoff_reg = DSPALINOFF;
- u32 dsptileoff_reg = DSPATILEOFF;
- u32 dspsize_reg = DSPASIZE;
- u32 dsppos_reg = DSPAPOS;
- u32 dspsurf_reg = DSPASURF;
- u32 mipi_reg = MIPI;
- u32 dspcntr_reg = DSPACNTR;
- u32 dspstatus_reg = PIPEASTAT;
- u32 palette_reg = PALETTE_A;
-
- /* pointer to values */
- u32 *dpll_val = &dev_priv->saveDPLL_A;
- u32 *fp_val = &dev_priv->saveFPA0;
- u32 *pipeconf_val = &dev_priv->savePIPEACONF;
- u32 *htot_val = &dev_priv->saveHTOTAL_A;
- u32 *hblank_val = &dev_priv->saveHBLANK_A;
- u32 *hsync_val = &dev_priv->saveHSYNC_A;
- u32 *vtot_val = &dev_priv->saveVTOTAL_A;
- u32 *vblank_val = &dev_priv->saveVBLANK_A;
- u32 *vsync_val = &dev_priv->saveVSYNC_A;
- u32 *pipesrc_val = &dev_priv->savePIPEASRC;
- u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
- u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
- u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
- u32 *dspsize_val = &dev_priv->saveDSPASIZE;
- u32 *dsppos_val = &dev_priv->saveDSPAPOS;
- u32 *dspsurf_val = &dev_priv->saveDSPASURF;
- u32 *mipi_val = &dev_priv->saveMIPI;
- u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
- u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
- u32 *palette_val = dev_priv->save_palette_a;
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- /* register */
- dpll_reg = MDFLD_DPLL_B;
- fp_reg = MDFLD_DPLL_DIV0;
- pipeconf_reg = PIPEBCONF;
- htot_reg = HTOTAL_B;
- hblank_reg = HBLANK_B;
- hsync_reg = HSYNC_B;
- vtot_reg = VTOTAL_B;
- vblank_reg = VBLANK_B;
- vsync_reg = VSYNC_B;
- pipesrc_reg = PIPEBSRC;
- dspstride_reg = DSPBSTRIDE;
- dsplinoff_reg = DSPBLINOFF;
- dsptileoff_reg = DSPBTILEOFF;
- dspsize_reg = DSPBSIZE;
- dsppos_reg = DSPBPOS;
- dspsurf_reg = DSPBSURF;
- dspcntr_reg = DSPBCNTR;
- dspstatus_reg = PIPEBSTAT;
- palette_reg = PALETTE_B;
-
- /* values */
- dpll_val = &dev_priv->saveDPLL_B;
- fp_val = &dev_priv->saveFPB0;
- pipeconf_val = &dev_priv->savePIPEBCONF;
- htot_val = &dev_priv->saveHTOTAL_B;
- hblank_val = &dev_priv->saveHBLANK_B;
- hsync_val = &dev_priv->saveHSYNC_B;
- vtot_val = &dev_priv->saveVTOTAL_B;
- vblank_val = &dev_priv->saveVBLANK_B;
- vsync_val = &dev_priv->saveVSYNC_B;
- pipesrc_val = &dev_priv->savePIPEBSRC;
- dspstride_val = &dev_priv->saveDSPBSTRIDE;
- dsplinoff_val = &dev_priv->saveDSPBLINOFF;
- dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
- dspsize_val = &dev_priv->saveDSPBSIZE;
- dsppos_val = &dev_priv->saveDSPBPOS;
- dspsurf_val = &dev_priv->saveDSPBSURF;
- dspcntr_val = &dev_priv->saveDSPBCNTR;
- dspstatus_val = &dev_priv->saveDSPBSTATUS;
- palette_val = dev_priv->save_palette_b;
- break;
- case 2:
- /* register */
- pipeconf_reg = PIPECCONF;
- htot_reg = HTOTAL_C;
- hblank_reg = HBLANK_C;
- hsync_reg = HSYNC_C;
- vtot_reg = VTOTAL_C;
- vblank_reg = VBLANK_C;
- vsync_reg = VSYNC_C;
- pipesrc_reg = PIPECSRC;
- dspstride_reg = DSPCSTRIDE;
- dsplinoff_reg = DSPCLINOFF;
- dsptileoff_reg = DSPCTILEOFF;
- dspsize_reg = DSPCSIZE;
- dsppos_reg = DSPCPOS;
- dspsurf_reg = DSPCSURF;
- mipi_reg = MIPI_C;
- dspcntr_reg = DSPCCNTR;
- dspstatus_reg = PIPECSTAT;
- palette_reg = PALETTE_C;
-
- /* pointer to values */
- pipeconf_val = &dev_priv->savePIPECCONF;
- htot_val = &dev_priv->saveHTOTAL_C;
- hblank_val = &dev_priv->saveHBLANK_C;
- hsync_val = &dev_priv->saveHSYNC_C;
- vtot_val = &dev_priv->saveVTOTAL_C;
- vblank_val = &dev_priv->saveVBLANK_C;
- vsync_val = &dev_priv->saveVSYNC_C;
- pipesrc_val = &dev_priv->savePIPECSRC;
- dspstride_val = &dev_priv->saveDSPCSTRIDE;
- dsplinoff_val = &dev_priv->saveDSPCLINOFF;
- dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
- dspsize_val = &dev_priv->saveDSPCSIZE;
- dsppos_val = &dev_priv->saveDSPCPOS;
- dspsurf_val = &dev_priv->saveDSPCSURF;
- mipi_val = &dev_priv->saveMIPI_C;
- dspcntr_val = &dev_priv->saveDSPCCNTR;
- dspstatus_val = &dev_priv->saveDSPCSTATUS;
- palette_val = dev_priv->save_palette_c;
- break;
- default:
- DRM_ERROR("%s, invalid pipe number.\n", __func__);
- return -EINVAL;
- }
-
- /* Pipe & plane A info */
- *dpll_val = PSB_RVDC32(dpll_reg);
- *fp_val = PSB_RVDC32(fp_reg);
- *pipeconf_val = PSB_RVDC32(pipeconf_reg);
- *htot_val = PSB_RVDC32(htot_reg);
- *hblank_val = PSB_RVDC32(hblank_reg);
- *hsync_val = PSB_RVDC32(hsync_reg);
- *vtot_val = PSB_RVDC32(vtot_reg);
- *vblank_val = PSB_RVDC32(vblank_reg);
- *vsync_val = PSB_RVDC32(vsync_reg);
- *pipesrc_val = PSB_RVDC32(pipesrc_reg);
- *dspstride_val = PSB_RVDC32(dspstride_reg);
- *dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
- *dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
- *dspsize_val = PSB_RVDC32(dspsize_reg);
- *dsppos_val = PSB_RVDC32(dsppos_reg);
- *dspsurf_val = PSB_RVDC32(dspsurf_reg);
- *dspcntr_val = PSB_RVDC32(dspcntr_reg);
- *dspstatus_val = PSB_RVDC32(dspstatus_reg);
-
- /*save palette (gamma) */
- for (i = 0; i < 256; i++)
- palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));
-
- if (pipe == 1) {
- dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
- dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
- dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
- dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
- return 0;
- }
- *mipi_val = PSB_RVDC32(mipi_reg);
- return 0;
-}
-
-/**
- * mdfld_save_cursor_overlay_registers - save cursor overlay info
- * @dev: our device
- *
- * Save the cursor and overlay register state
- */
-static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- /* Save cursor regs */
- dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
- dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
- dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
-
- dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
- dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
- dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
-
- dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
- dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
- dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
-
- /* HW overlay */
- dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
- dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
- dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
- dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
- dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
- dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
- dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-
- dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);
-
- return 0;
-}
-/*
- * mdfld_restore_display_registers - restore the state of a pipe
- * @dev: our device
- * @pipe: the pipe to restore
- *
- * Restore the state of a pipe to that which was saved by the register save
- * functions.
- */
-static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
-{
- /* To get panel out of ULPS mode */
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dsi_config *dsi_config = NULL;
- u32 i = 0;
- u32 dpll = 0;
- u32 timeout = 0;
- u32 reg_offset = 0;
-
- /* register */
- u32 dpll_reg = MRST_DPLL_A;
- u32 fp_reg = MRST_FPA0;
- u32 pipeconf_reg = PIPEACONF;
- u32 htot_reg = HTOTAL_A;
- u32 hblank_reg = HBLANK_A;
- u32 hsync_reg = HSYNC_A;
- u32 vtot_reg = VTOTAL_A;
- u32 vblank_reg = VBLANK_A;
- u32 vsync_reg = VSYNC_A;
- u32 pipesrc_reg = PIPEASRC;
- u32 dspstride_reg = DSPASTRIDE;
- u32 dsplinoff_reg = DSPALINOFF;
- u32 dsptileoff_reg = DSPATILEOFF;
- u32 dspsize_reg = DSPASIZE;
- u32 dsppos_reg = DSPAPOS;
- u32 dspsurf_reg = DSPASURF;
- u32 dspstatus_reg = PIPEASTAT;
- u32 mipi_reg = MIPI;
- u32 dspcntr_reg = DSPACNTR;
- u32 palette_reg = PALETTE_A;
-
- /* values */
- u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
- u32 fp_val = dev_priv->saveFPA0;
- u32 pipeconf_val = dev_priv->savePIPEACONF;
- u32 htot_val = dev_priv->saveHTOTAL_A;
- u32 hblank_val = dev_priv->saveHBLANK_A;
- u32 hsync_val = dev_priv->saveHSYNC_A;
- u32 vtot_val = dev_priv->saveVTOTAL_A;
- u32 vblank_val = dev_priv->saveVBLANK_A;
- u32 vsync_val = dev_priv->saveVSYNC_A;
- u32 pipesrc_val = dev_priv->savePIPEASRC;
- u32 dspstride_val = dev_priv->saveDSPASTRIDE;
- u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
- u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
- u32 dspsize_val = dev_priv->saveDSPASIZE;
- u32 dsppos_val = dev_priv->saveDSPAPOS;
- u32 dspsurf_val = dev_priv->saveDSPASURF;
- u32 dspstatus_val = dev_priv->saveDSPASTATUS;
- u32 mipi_val = dev_priv->saveMIPI;
- u32 dspcntr_val = dev_priv->saveDSPACNTR;
- u32 *palette_val = dev_priv->save_palette_a;
-
- switch (pipe) {
- case 0:
- dsi_config = dev_priv->dsi_configs[0];
- break;
- case 1:
- /* register */
- dpll_reg = MDFLD_DPLL_B;
- fp_reg = MDFLD_DPLL_DIV0;
- pipeconf_reg = PIPEBCONF;
- htot_reg = HTOTAL_B;
- hblank_reg = HBLANK_B;
- hsync_reg = HSYNC_B;
- vtot_reg = VTOTAL_B;
- vblank_reg = VBLANK_B;
- vsync_reg = VSYNC_B;
- pipesrc_reg = PIPEBSRC;
- dspstride_reg = DSPBSTRIDE;
- dsplinoff_reg = DSPBLINOFF;
- dsptileoff_reg = DSPBTILEOFF;
- dspsize_reg = DSPBSIZE;
- dsppos_reg = DSPBPOS;
- dspsurf_reg = DSPBSURF;
- dspcntr_reg = DSPBCNTR;
- palette_reg = PALETTE_B;
- dspstatus_reg = PIPEBSTAT;
-
- /* values */
- dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
- fp_val = dev_priv->saveFPB0;
- pipeconf_val = dev_priv->savePIPEBCONF;
- htot_val = dev_priv->saveHTOTAL_B;
- hblank_val = dev_priv->saveHBLANK_B;
- hsync_val = dev_priv->saveHSYNC_B;
- vtot_val = dev_priv->saveVTOTAL_B;
- vblank_val = dev_priv->saveVBLANK_B;
- vsync_val = dev_priv->saveVSYNC_B;
- pipesrc_val = dev_priv->savePIPEBSRC;
- dspstride_val = dev_priv->saveDSPBSTRIDE;
- dsplinoff_val = dev_priv->saveDSPBLINOFF;
- dsptileoff_val = dev_priv->saveDSPBTILEOFF;
- dspsize_val = dev_priv->saveDSPBSIZE;
- dsppos_val = dev_priv->saveDSPBPOS;
- dspsurf_val = dev_priv->saveDSPBSURF;
- dspcntr_val = dev_priv->saveDSPBCNTR;
- dspstatus_val = dev_priv->saveDSPBSTATUS;
- palette_val = dev_priv->save_palette_b;
- break;
- case 2:
- reg_offset = MIPIC_REG_OFFSET;
-
- /* register */
- pipeconf_reg = PIPECCONF;
- htot_reg = HTOTAL_C;
- hblank_reg = HBLANK_C;
- hsync_reg = HSYNC_C;
- vtot_reg = VTOTAL_C;
- vblank_reg = VBLANK_C;
- vsync_reg = VSYNC_C;
- pipesrc_reg = PIPECSRC;
- dspstride_reg = DSPCSTRIDE;
- dsplinoff_reg = DSPCLINOFF;
- dsptileoff_reg = DSPCTILEOFF;
- dspsize_reg = DSPCSIZE;
- dsppos_reg = DSPCPOS;
- dspsurf_reg = DSPCSURF;
- mipi_reg = MIPI_C;
- dspcntr_reg = DSPCCNTR;
- palette_reg = PALETTE_C;
- dspstatus_reg = PIPECSTAT;
-
- /* values */
- pipeconf_val = dev_priv->savePIPECCONF;
- htot_val = dev_priv->saveHTOTAL_C;
- hblank_val = dev_priv->saveHBLANK_C;
- hsync_val = dev_priv->saveHSYNC_C;
- vtot_val = dev_priv->saveVTOTAL_C;
- vblank_val = dev_priv->saveVBLANK_C;
- vsync_val = dev_priv->saveVSYNC_C;
- pipesrc_val = dev_priv->savePIPECSRC;
- dspstride_val = dev_priv->saveDSPCSTRIDE;
- dsplinoff_val = dev_priv->saveDSPCLINOFF;
- dsptileoff_val = dev_priv->saveDSPCTILEOFF;
- dspsize_val = dev_priv->saveDSPCSIZE;
- dsppos_val = dev_priv->saveDSPCPOS;
- dspsurf_val = dev_priv->saveDSPCSURF;
- dspstatus_val = dev_priv->saveDSPCSTATUS;
- mipi_val = dev_priv->saveMIPI_C;
- dspcntr_val = dev_priv->saveDSPCCNTR;
- palette_val = dev_priv->save_palette_c;
-
- dsi_config = dev_priv->dsi_configs[1];
- break;
- default:
- DRM_ERROR("%s, invalid pipe number.\n", __func__);
- return -EINVAL;
- }
-
- /* Make sure VGA plane is off. it initializes to on after reset!*/
- PSB_WVDC32(0x80000000, VGACNTRL);
- if (pipe == 1) {
- PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
- PSB_RVDC32(dpll_reg);
-
- PSB_WVDC32(fp_val, fp_reg);
- } else {
- dpll = PSB_RVDC32(dpll_reg);
-
- if (!(dpll & DPLL_VCO_ENABLE)) {
-
- /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
- if (dpll & MDFLD_PWR_GATE_EN) {
- dpll &= ~MDFLD_PWR_GATE_EN;
- PSB_WVDC32(dpll, dpll_reg);
- udelay(500); /* FIXME: 1 ? */
- }
-
- PSB_WVDC32(fp_val, fp_reg);
- PSB_WVDC32(dpll_val, dpll_reg);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
-
- dpll_val |= DPLL_VCO_ENABLE;
- PSB_WVDC32(dpll_val, dpll_reg);
- PSB_RVDC32(dpll_reg);
-
- /* wait for DSI PLL to lock */
- while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
- udelay(150);
- timeout++;
- }
-
- if (timeout == 20000) {
- DRM_ERROR("%s, can't lock DSIPLL.\n",
- __func__);
- return -EINVAL;
- }
- }
- }
- /* Restore mode */
- PSB_WVDC32(htot_val, htot_reg);
- PSB_WVDC32(hblank_val, hblank_reg);
- PSB_WVDC32(hsync_val, hsync_reg);
- PSB_WVDC32(vtot_val, vtot_reg);
- PSB_WVDC32(vblank_val, vblank_reg);
- PSB_WVDC32(vsync_val, vsync_reg);
- PSB_WVDC32(pipesrc_val, pipesrc_reg);
- PSB_WVDC32(dspstatus_val, dspstatus_reg);
-
- /* Set up the plane */
- PSB_WVDC32(dspstride_val, dspstride_reg);
- PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
- PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
- PSB_WVDC32(dspsize_val, dspsize_reg);
- PSB_WVDC32(dsppos_val, dsppos_reg);
- PSB_WVDC32(dspsurf_val, dspsurf_reg);
-
- if (pipe == 1) {
- PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
- PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
- PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
- PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);
-
- } else {
- /* Set up pipe related registers */
- PSB_WVDC32(mipi_val, mipi_reg);
- /* Setup MIPI adapter + MIPI IP registers */
- mdfld_dsi_controller_init(dsi_config, pipe);
- msleep(20);
- }
- /* Enable the plane */
- PSB_WVDC32(dspcntr_val, dspcntr_reg);
- msleep(20);
- /* Enable the pipe */
- PSB_WVDC32(pipeconf_val, pipeconf_reg);
-
- for (i = 0; i < 256; i++)
- PSB_WVDC32(palette_val[i], palette_reg + (i<<2));
- if (pipe == 1)
- return 0;
- if (!mdfld_panel_dpi(dev))
- mdfld_enable_te(dev, pipe);
- return 0;
-}
-
-/**
- * mdfld_restore_cursor_overlay_registers - restore cursor
- * @dev: our device
- *
- * Restore the cursor and overlay state that was saved earlier
- */
-static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- /* Enable Cursor A */
- PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
- PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
- PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
-
- PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
- PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
- PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
-
- PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
- PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
- PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
-
- /* Restore HW overlay */
- PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
- PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
- PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
- PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
- PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
- PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
- PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
-
- PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET);
-
- return 0;
-}
-
-/**
- * mdfld_save_display_registers - save registers lost on suspend
- * @dev: our DRM device
- *
- * Save the state we need in order to be able to restore the interface
- * upon resume from suspend
- */
-static int mdfld_save_registers(struct drm_device *dev)
-{
- /* FIXME: We need to shut down panels here if using them
- and once the right bits are merged */
- mdfld_save_cursor_overlay_registers(dev);
- mdfld_save_display_registers(dev, 0);
- mdfld_save_display_registers(dev, 0);
- mdfld_save_display_registers(dev, 2);
- mdfld_save_display_registers(dev, 1);
- mdfld_disable_crtc(dev, 0);
- mdfld_disable_crtc(dev, 2);
- mdfld_disable_crtc(dev, 1);
- return 0;
-}
-
-/**
- * mdfld_restore_display_registers - restore lost register state
- * @dev: our DRM device
- *
- * Restore register state that was lost during suspend and resume.
- */
-static int mdfld_restore_registers(struct drm_device *dev)
-{
- mdfld_restore_display_registers(dev, 1);
- mdfld_restore_display_registers(dev, 0);
- mdfld_restore_display_registers(dev, 2);
- mdfld_restore_cursor_overlay_registers(dev);
- return 0;
-}
-
-static int mdfld_power_down(struct drm_device *dev)
-{
- /* FIXME */
- return 0;
-}
-
-static int mdfld_power_up(struct drm_device *dev)
-{
- /* FIXME */
- return 0;
-}
-
-const struct psb_ops mdfld_chip_ops = {
- .name = "Medfield",
- .accel_2d = 0,
- .pipes = 3,
- .crtcs = 2,
- .sgx_offset = MRST_SGX_OFFSET,
-
- .chip_setup = mid_chip_setup,
-
- .crtc_helper = &mdfld_helper_funcs,
- .crtc_funcs = &mdfld_intel_crtc_funcs,
-
- .output_init = mdfld_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- .backlight_init = mdfld_backlight_init,
-#endif
-
- .init_pm = mdfld_init_pm,
- .save_regs = mdfld_save_registers,
- .restore_regs = mdfld_restore_registers,
- .power_down = mdfld_power_down,
- .power_up = mdfld_power_up,
-};
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.c b/drivers/staging/gma500/mdfld_dsi_dbi.c
deleted file mode 100644
index fd211f3467c4..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "power.h"
-#include
-
-int enable_gfx_rtpm;
-
-extern struct drm_device *gpDrmDevice;
-extern int gfxrtdelay;
-int enter_dsr;
-struct mdfld_dsi_dbi_output *gdbi_output;
-extern bool gbgfxsuspended;
-extern int enable_gfx_rtpm;
-extern int gfxrtdelay;
-
-#define MDFLD_DSR_MAX_IDLE_COUNT 2
-
-/*
- * set refreshing area
- */
-int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
- u16 x1, u16 y1, u16 x2, u16 y2)
-{
- struct mdfld_dsi_pkg_sender *sender =
- mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
- u8 param[4];
- u8 cmd;
- int err;
-
- if (!sender) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- /* Set column */
- cmd = DCS_SET_COLUMN_ADDRESS;
- param[0] = x1 >> 8;
- param[1] = x1;
- param[2] = x2 >> 8;
- param[3] = x2;
-
- err = mdfld_dsi_send_dcs(sender,
- cmd,
- param,
- 4,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
- goto err_out;
- }
-
- /* Set page */
- cmd = DCS_SET_PAGE_ADDRESS;
- param[0] = y1 >> 8;
- param[1] = y1;
- param[2] = y2 >> 8;
- param[3] = y2;
-
- err = mdfld_dsi_send_dcs(sender,
- cmd,
- param,
- 4,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
- goto err_out;
- }
-
- /*update screen*/
- err = mdfld_dsi_send_dcs(sender,
- write_mem_start,
- NULL,
- 0,
- CMD_DATA_SRC_PIPE,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
- goto err_out;
- }
- mdfld_dsi_cmds_kick_out(sender);
-err_out:
- return err;
-}
-
-/*
- * set panel's power state
- */
-int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
- int mode)
-{
- struct drm_device *dev = dbi_output->dev;
- struct mdfld_dsi_pkg_sender *sender =
- mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
- u8 param = 0;
- u32 err = 0;
-
- if (!sender) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- if (mode == DRM_MODE_DPMS_ON) {
- /* Exit sleep mode */
- err = mdfld_dsi_send_dcs(sender,
- DCS_EXIT_SLEEP_MODE,
- NULL,
- 0,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(dev->dev, "DCS 0x%x sent failed\n",
- DCS_EXIT_SLEEP_MODE);
- goto power_err;
- }
-
- /* Set display on */
- err = mdfld_dsi_send_dcs(sender,
- DCS_SET_DISPLAY_ON,
- NULL,
- 0,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(dev->dev, "DCS 0x%x sent failed\n",
- DCS_SET_DISPLAY_ON);
- goto power_err;
- }
-
- /* set tear effect on */
- err = mdfld_dsi_send_dcs(sender,
- DCS_SET_TEAR_ON,
- ¶m,
- 1,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(dev->dev, "DCS 0x%x sent failed\n",
- set_tear_on);
- goto power_err;
- }
-
- /**
- * FIXME: remove this later
- */
- err = mdfld_dsi_send_dcs(sender,
- DCS_WRITE_MEM_START,
- NULL,
- 0,
- CMD_DATA_SRC_PIPE,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(dev->dev, "DCS 0x%x sent failed\n",
- DCS_WRITE_MEM_START);
- goto power_err;
- }
- } else {
- /* Set tear effect off */
- err = mdfld_dsi_send_dcs(sender,
- DCS_SET_TEAR_OFF,
- NULL,
- 0,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(dev->dev, "DCS 0x%x sent failed\n",
- DCS_SET_TEAR_OFF);
- goto power_err;
- }
-
- /* Turn display off */
- err = mdfld_dsi_send_dcs(sender,
- DCS_SET_DISPLAY_OFF,
- NULL,
- 0,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(dev->dev, "DCS 0x%x sent failed\n",
- DCS_SET_DISPLAY_OFF);
- goto power_err;
- }
-
- /* Now enter sleep mode */
- err = mdfld_dsi_send_dcs(sender,
- DCS_ENTER_SLEEP_MODE,
- NULL,
- 0,
- CMD_DATA_SRC_SYSTEM_MEM,
- MDFLD_DSI_QUEUE_PACKAGE);
- if (err) {
- dev_err(dev->dev, "DCS 0x%x sent failed\n",
- DCS_ENTER_SLEEP_MODE);
- goto power_err;
- }
- }
- mdfld_dsi_cmds_kick_out(sender);
-power_err:
- return err;
-}
-
-/*
- * send a generic DCS command with a parameter list
- */
-int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
- u8 dcs, u8 *param, u32 num, u8 data_src)
-{
- struct mdfld_dsi_pkg_sender *sender =
- mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
- int ret;
-
- if (!sender) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- ret = mdfld_dsi_send_dcs(sender,
- dcs,
- param,
- num,
- data_src,
- MDFLD_DSI_SEND_PACKAGE);
-
- return ret;
-}
-
-/*
- * Enter DSR
- */
-void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
-{
- u32 reg_val;
- struct drm_device *dev = dbi_output->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = dbi_output->base.base.crtc;
- struct psb_intel_crtc *psb_crtc = (crtc) ?
- to_psb_intel_crtc(crtc) : NULL;
- u32 dpll_reg = MRST_DPLL_A;
- u32 pipeconf_reg = PIPEACONF;
- u32 dspcntr_reg = DSPACNTR;
-
- if (!dbi_output)
- return;
-
- /* FIXME check if can go */
- dev_priv->is_in_idle = true;
-
- gdbi_output = dbi_output;
- if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
- (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
- return;
-
- if (pipe == 2) {
- dpll_reg = MRST_DPLL_A;
- pipeconf_reg = PIPECCONF;
- dspcntr_reg = DSPCCNTR;
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
- /* Disable te interrupts */
- mdfld_disable_te(dev, pipe);
-
- /* Disable plane */
- reg_val = REG_READ(dspcntr_reg);
- if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
- REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
- REG_READ(dspcntr_reg);
- }
-
- /* Disable pipe */
- reg_val = REG_READ(pipeconf_reg);
- if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
- reg_val &= ~DISPLAY_PLANE_ENABLE;
- reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF);
- REG_WRITE(pipeconf_reg, reg_val);
- REG_READ(pipeconf_reg);
- mdfldWaitForPipeDisable(dev, pipe);
- }
-
- /* Disable DPLL */
- reg_val = REG_READ(dpll_reg);
- if (!(reg_val & DPLL_VCO_ENABLE)) {
- reg_val &= ~DPLL_VCO_ENABLE;
- REG_WRITE(dpll_reg, reg_val);
- REG_READ(dpll_reg);
- udelay(500);
- }
-
- gma_power_end(dev);
- dbi_output->mode_flags |= MODE_SETTING_IN_DSR;
- if (pipe == 2) {
- enter_dsr = 1;
- /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
- }
-}
-
-static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
- int pipe)
-{
- struct drm_device *dev = dbi_output->dev;
- struct drm_crtc *crtc = dbi_output->base.base.crtc;
- struct psb_intel_crtc *psb_crtc = (crtc) ?
- to_psb_intel_crtc(crtc) : NULL;
- u32 reg_val;
- u32 dpll_reg = MRST_DPLL_A;
- u32 pipeconf_reg = PIPEACONF;
- u32 dspcntr_reg = DSPACNTR;
- u32 reg_offset = 0;
-
- /*if mode setting on-going, back off*/
- if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
- (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
- return;
-
- if (pipe == 2) {
- dpll_reg = MRST_DPLL_A;
- pipeconf_reg = PIPECCONF;
- dspcntr_reg = DSPCCNTR;
- reg_offset = MIPIC_REG_OFFSET;
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- /* Enable DPLL */
- reg_val = REG_READ(dpll_reg);
- if (!(reg_val & DPLL_VCO_ENABLE)) {
- if (reg_val & MDFLD_PWR_GATE_EN) {
- reg_val &= ~MDFLD_PWR_GATE_EN;
- REG_WRITE(dpll_reg, reg_val);
- REG_READ(dpll_reg);
- udelay(500);
- }
-
- reg_val |= DPLL_VCO_ENABLE;
- REG_WRITE(dpll_reg, reg_val);
- REG_READ(dpll_reg);
- udelay(500);
-
- /* Add timeout */
- while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
- cpu_relax();
- }
-
- /* Enable pipe */
- reg_val = REG_READ(pipeconf_reg);
- if (!(reg_val & PIPEACONF_ENABLE)) {
- reg_val |= PIPEACONF_ENABLE;
- REG_WRITE(pipeconf_reg, reg_val);
- REG_READ(pipeconf_reg);
- udelay(500);
- mdfldWaitForPipeEnable(dev, pipe);
- }
-
- /* Enable plane */
- reg_val = REG_READ(dspcntr_reg);
- if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
- reg_val |= DISPLAY_PLANE_ENABLE;
- REG_WRITE(dspcntr_reg, reg_val);
- REG_READ(dspcntr_reg);
- udelay(500);
- }
-
- /* Enable TE interrupt on this pipe */
- mdfld_enable_te(dev, pipe);
- gma_power_end(dev);
-
- /*clean IN_DSR flag*/
- dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-}
-
-/*
- * Exit from DSR
- */
-void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
- struct mdfld_dsi_dbi_output **dbi_output;
- int i;
- int pipe;
-
- /* FIXME can go ? */
- dev_priv->is_in_idle = false;
- dbi_output = dsr_info->dbi_outputs;
-
-#ifdef CONFIG_PM_RUNTIME
- if (!enable_gfx_rtpm) {
-/* pm_runtime_allow(&gpDrmDevice->pdev->dev); */
-/* schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */
- }
-#endif
-
- /* For each output, exit dsr */
- for (i = 0; i < dsr_info->dbi_output_num; i++) {
- /* If panel has been turned off, skip */
- if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on)
- continue;
- pipe = dbi_output[i]->channel_num ? 2 : 0;
- enter_dsr = 0;
- mdfld_dbi_output_exit_dsr(dbi_output[i], pipe);
- }
- dev_priv->dsr_fb_update |= update_src;
-}
-
-static bool mdfld_dbi_is_in_dsr(struct drm_device *dev)
-{
- if (REG_READ(MRST_DPLL_A) & DPLL_VCO_ENABLE)
- return false;
- if ((REG_READ(PIPEACONF) & PIPEACONF_ENABLE) ||
- (REG_READ(PIPECCONF) & PIPEACONF_ENABLE))
- return false;
- if ((REG_READ(DSPACNTR) & DISPLAY_PLANE_ENABLE) ||
- (REG_READ(DSPCCNTR) & DISPLAY_PLANE_ENABLE))
- return false;
-
- return true;
-}
-
-/* Periodically update dbi panel */
-void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
- struct mdfld_dsi_dbi_output **dbi_outputs;
- struct mdfld_dsi_dbi_output *dbi_output;
- int i;
- int can_enter_dsr = 0;
- u32 damage_mask;
-
- dbi_outputs = dsr_info->dbi_outputs;
- dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
-
- if (!dbi_output)
- return;
-
- if (pipe == 0)
- damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0;
- else if (pipe == 2)
- damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2;
- else
- return;
-
- /* If FB is damaged and panel is on update on-panel FB */
- if (damage_mask && dbi_output->dbi_panel_on) {
- dbi_output->dsr_fb_update_done = false;
-
- if (dbi_output->p_funcs->update_fb)
- dbi_output->p_funcs->update_fb(dbi_output, pipe);
-
- if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done)
- dev_priv->dsr_fb_update &= ~damage_mask;
-
- /*clean IN_DSR flag*/
- dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-
- dbi_output->dsr_idle_count = 0;
- } else {
- dbi_output->dsr_idle_count++;
- }
-
- switch (dsr_info->dbi_output_num) {
- case 1:
- if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
- can_enter_dsr = 1;
- break;
- case 2:
- if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT
- && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
- can_enter_dsr = 1;
- break;
- default:
- DRM_ERROR("Wrong DBI output number\n");
- }
-
- /* Try to enter DSR */
- if (can_enter_dsr) {
- for (i = 0; i < dsr_info->dbi_output_num; i++) {
- if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] &&
- !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
- mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
- dbi_outputs[i]->channel_num ? 2 : 0);
-#if 0
- enter_dsr = 1;
- pr_err("%s: enter_dsr = 1\n", __func__);
-#endif
- }
- }
- /*schedule rpm suspend after gfxrtdelay*/
-#ifdef CONFIG_GFX_RTPM
- if (!dev_priv->rpm_enabled
- || !enter_dsr
- /* || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
- || pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay))
- dev_warn(dev->dev,
- "Runtime PM schedule suspend failed, rpm %d\n",
- dev_priv->rpm_enabled);
-#endif
- }
-}
-
-int mdfld_dbi_dsr_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-
- if (!dsr_info || IS_ERR(dsr_info)) {
- dsr_info = kzalloc(sizeof(struct mdfld_dbi_dsr_info),
- GFP_KERNEL);
- if (!dsr_info) {
- dev_err(dev->dev, "No memory\n");
- return -ENOMEM;
- }
- dev_priv->dbi_dsr_info = dsr_info;
- }
- return 0;
-}
-
-void mdfld_dbi_dsr_exit(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-
- if (dsr_info) {
- kfree(dsr_info);
- dev_priv->dbi_dsr_info = NULL;
- }
-}
-
-void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
- int pipe)
-{
- struct drm_device *dev = dsi_config->dev;
- u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- int lane_count = dsi_config->lane_count;
- u32 val = 0;
-
- dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
-
- /* Un-ready device */
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
- /* Init dsi adapter before kicking off */
- REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
- /* TODO: figure out how to setup these registers */
- REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
- REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
- 0x000a0014);
- REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
- REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
- REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
- /* Enable all interrupts */
- REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
- /* Max value: 20 clock cycles of txclkesc */
- REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
- /* Min 21 txclkesc, max: ffffh */
- REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
- /* Min: 7d0 max: 4e20 */
- REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
- /* Set up func_prg */
- val |= lane_count;
- val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
- val |= DSI_DBI_COLOR_FORMAT_OPTION2;
- REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
- REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
- REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
- /* De-assert dbi_stall when half of DBI FIFO is empty */
- /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
-
- REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
- REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
- REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-#if 0
-/*DBI encoder helper funcs*/
-static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
- .dpms = mdfld_dsi_dbi_dpms,
- .mode_fixup = mdfld_dsi_dbi_mode_fixup,
- .prepare = mdfld_dsi_dbi_prepare,
- .mode_set = mdfld_dsi_dbi_mode_set,
- .commit = mdfld_dsi_dbi_commit,
-};
-
-/*DBI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
- .destroy = drm_encoder_cleanup,
-};
-
-#endif
-
-/*
- * Init DSI DBI encoder.
- * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
- * return pointer of newly allocated DBI encoder, NULL on error
- */
-struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
- struct mdfld_dsi_connector *dsi_connector,
- struct panel_funcs *p_funcs)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dsi_dbi_output *dbi_output = NULL;
- struct mdfld_dsi_config *dsi_config;
- struct drm_connector *connector = NULL;
- struct drm_encoder *encoder = NULL;
- struct drm_display_mode *fixed_mode = NULL;
- struct psb_gtt *pg = dev_priv ? (&dev_priv->gtt) : NULL;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL;
- struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
- u32 data = 0;
- int pipe;
- int ret;
-
- if (!pg || !dsi_connector || !p_funcs) {
- WARN_ON(1);
- return NULL;
- }
-
- dsi_config = mdfld_dsi_get_config(dsi_connector);
- pipe = dsi_connector->pipe;
-
- /*panel hard-reset*/
- if (p_funcs->reset) {
- ret = p_funcs->reset(pipe);
- if (ret) {
- DRM_ERROR("Panel %d hard-reset failed\n", pipe);
- return NULL;
- }
- }
- /* Panel drvIC init */
- if (p_funcs->drv_ic_init)
- p_funcs->drv_ic_init(dsi_config, pipe);
-
- /* Panel power mode detect */
- ret = mdfld_dsi_get_power_mode(dsi_config,
- &data,
- MDFLD_DSI_HS_TRANSMISSION);
- if (ret) {
- DRM_ERROR("Panel %d get power mode failed\n", pipe);
- dsi_connector->status = connector_status_disconnected;
- } else {
- DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
- dsi_connector->status = connector_status_connected;
- }
-
- /*TODO: get panel info from DDB*/
-
- dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
- if (!dbi_output) {
- dev_err(dev->dev, "No memory\n");
- return NULL;
- }
-
- if (dsi_connector->pipe == 0) {
- dbi_output->channel_num = 0;
- dev_priv->dbi_output = dbi_output;
- } else if (dsi_connector->pipe == 2) {
- dbi_output->channel_num = 1;
- dev_priv->dbi_output2 = dbi_output;
- } else {
- dev_err(dev->dev, "only support 2 DSI outputs\n");
- goto out_err1;
- }
-
- dbi_output->dev = dev;
- dbi_output->p_funcs = p_funcs;
- fixed_mode = dsi_config->fixed_mode;
- dbi_output->panel_fixed_mode = fixed_mode;
-
- /* Create drm encoder object */
- connector = &dsi_connector->base.base;
- encoder = &dbi_output->base.base;
- /* Review this if we ever get MIPI-HDMI bridges or similar */
- drm_encoder_init(dev,
- encoder,
- p_funcs->encoder_funcs,
- DRM_MODE_ENCODER_LVDS);
- drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);
-
- /* Attach to given connector */
- drm_mode_connector_attach_encoder(connector, encoder);
-
- /* Set possible CRTCs and clones */
- if (dsi_connector->pipe) {
- encoder->possible_crtcs = (1 << 2);
- encoder->possible_clones = (1 << 1);
- } else {
- encoder->possible_crtcs = (1 << 0);
- encoder->possible_clones = (1 << 0);
- }
-
- dev_priv->dsr_fb_update = 0;
- dev_priv->dsr_enable = false;
- dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
-
- dbi_output->first_boot = true;
- dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
-
- /* Add this output to dpu_info if in DPU mode */
- if (dpu_info && dsi_connector->status == connector_status_connected) {
- if (dsi_connector->pipe == 0)
- dpu_info->dbi_outputs[0] = dbi_output;
- else
- dpu_info->dbi_outputs[1] = dbi_output;
-
- dpu_info->dbi_output_num++;
- } else if (dsi_connector->status == connector_status_connected) {
- /* Add this output to dsr_info if not */
- if (dsi_connector->pipe == 0)
- dsr_info->dbi_outputs[0] = dbi_output;
- else
- dsr_info->dbi_outputs[1] = dbi_output;
-
- dsr_info->dbi_output_num++;
- }
- return &dbi_output->base;
-out_err1:
- kfree(dbi_output);
- return NULL;
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.h b/drivers/staging/gma500/mdfld_dsi_dbi.h
deleted file mode 100644
index f0fa986fd934..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#ifndef __MDFLD_DSI_DBI_H__
-#define __MDFLD_DSI_DBI_H__
-
-#include
-#include
-#include
-#include
-#include
-
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-/*
- * DBI encoder which inherits from mdfld_dsi_encoder
- */
-struct mdfld_dsi_dbi_output {
- struct mdfld_dsi_encoder base;
- struct drm_display_mode *panel_fixed_mode;
- u8 last_cmd;
- u8 lane_count;
- u8 channel_num;
- struct drm_device *dev;
-
- /* Backlight operations */
-
- /* DSR timer */
- u32 dsr_idle_count;
- bool dsr_fb_update_done;
-
- /* Mode setting flags */
- u32 mode_flags;
-
- /* Panel status */
- bool dbi_panel_on;
- bool first_boot;
- struct panel_funcs *p_funcs;
-
- /* DPU */
- u32 *dbi_cb_addr;
- u32 dbi_cb_phy;
- spinlock_t cb_lock;
- u32 cb_write;
-};
-
-#define MDFLD_DSI_DBI_OUTPUT(dsi_encoder) \
- container_of(dsi_encoder, struct mdfld_dsi_dbi_output, base)
-
-struct mdfld_dbi_dsr_info {
- int dbi_output_num;
- struct mdfld_dsi_dbi_output *dbi_outputs[2];
-
- u32 dsr_idle_count;
-};
-
-#define DBI_CB_TIMEOUT_COUNT 0xffff
-
-/* Offsets */
-#define CMD_MEM_ADDR_OFFSET 0
-
-#define CMD_DATA_SRC_SYSTEM_MEM 0
-#define CMD_DATA_SRC_PIPE 1
-
-static inline int mdfld_dsi_dbi_fifo_ready(struct mdfld_dsi_dbi_output *dbi_output)
-{
- struct drm_device *dev = dbi_output->dev;
- u32 retry = DBI_CB_TIMEOUT_COUNT;
- int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;
- int ret = 0;
-
- /* Query the dbi fifo status*/
- while (retry--) {
- if (REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset) & (1 << 27))
- break;
- }
-
- if (!retry) {
- DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
- ret = -EAGAIN;
- }
- return ret;
-}
-
-static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output *dbi_output)
-{
- struct drm_device *dev = dbi_output->dev;
- u32 retry = DBI_CB_TIMEOUT_COUNT;
- int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;
- int ret = 0;
-
- /* Query the command execution status */
- while (retry--)
- if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 0)))
- break;
-
- if (!retry) {
- DRM_ERROR("Timeout waiting for DBI command status\n");
- ret = -EAGAIN;
- }
-
- return ret;
-}
-
-static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output *dbi_output)
-{
- int ret = 0;
-
- /* Query the command execution status*/
- ret = mdfld_dsi_dbi_cmd_sent(dbi_output);
- if (ret) {
- DRM_ERROR("Peripheral is busy\n");
- ret = -EAGAIN;
- }
- /* Query the dbi fifo status*/
- ret = mdfld_dsi_dbi_fifo_ready(dbi_output);
- if (ret) {
- DRM_ERROR("DBI FIFO is not empty\n");
- ret = -EAGAIN;
- }
- return ret;
-}
-
-extern void mdfld_dsi_dbi_output_init(struct drm_device *dev,
- struct psb_intel_mode_device *mode_dev, int pipe);
-extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src);
-extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output,
- int pipe);
-extern int mdfld_dbi_dsr_init(struct drm_device *dev);
-extern void mdfld_dbi_dsr_exit(struct drm_device *dev);
-extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
- struct mdfld_dsi_connector *dsi_connector,
- struct panel_funcs *p_funcs);
-extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
- u8 dcs, u8 *param, u32 num, u8 data_src);
-extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
- u16 x1, u16 y1, u16 x2, u16 y2);
-extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
- int mode);
-extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
- int pipe);
-
-#endif /*__MDFLD_DSI_DBI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
deleted file mode 100644
index a4e2ff442b1f..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * Copyright © 2010-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jim Liu
- * Jackie Li
- */
-
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_dbi.h"
-
-/*
- * NOTE: all mdlfd_x_damage funcs should be called by holding dpu_update_lock
- */
-
-static int mdfld_cursor_damage(struct mdfld_dbi_dpu_info *dpu_info,
- mdfld_plane_t plane,
- struct psb_drm_dpu_rect *damaged_rect)
-{
- int x, y;
- int new_x, new_y;
- struct psb_drm_dpu_rect *rect;
- struct psb_drm_dpu_rect *pipe_rect;
- int cursor_size;
- struct mdfld_cursor_info *cursor;
- mdfld_plane_t fb_plane;
-
- if (plane == MDFLD_CURSORA) {
- cursor = &dpu_info->cursors[0];
- x = dpu_info->cursors[0].x;
- y = dpu_info->cursors[0].y;
- cursor_size = dpu_info->cursors[0].size;
- pipe_rect = &dpu_info->damage_pipea;
- fb_plane = MDFLD_PLANEA;
- } else {
- cursor = &dpu_info->cursors[1];
- x = dpu_info->cursors[1].x;
- y = dpu_info->cursors[1].y;
- cursor_size = dpu_info->cursors[1].size;
- pipe_rect = &dpu_info->damage_pipec;
- fb_plane = MDFLD_PLANEC;
- }
- new_x = damaged_rect->x;
- new_y = damaged_rect->y;
-
- if (x == new_x && y == new_y)
- return 0;
-
- rect = &dpu_info->damaged_rects[plane];
- /* Move to right */
- if (new_x >= x) {
- if (new_y > y) {
- rect->x = x;
- rect->y = y;
- rect->width = (new_x + cursor_size) - x;
- rect->height = (new_y + cursor_size) - y;
- goto cursor_out;
- } else {
- rect->x = x;
- rect->y = new_y;
- rect->width = (new_x + cursor_size) - x;
- rect->height = (y - new_y);
- goto cursor_out;
- }
- } else {
- if (new_y > y) {
- rect->x = new_x;
- rect->y = y;
- rect->width = (x + cursor_size) - new_x;
- rect->height = new_y - y;
- goto cursor_out;
- } else {
- rect->x = new_x;
- rect->y = new_y;
- rect->width = (x + cursor_size) - new_x;
- rect->height = (y + cursor_size) - new_y;
- }
- }
-cursor_out:
- if (new_x < 0)
- cursor->x = 0;
- else if (new_x > 864)
- cursor->x = 864;
- else
- cursor->x = new_x;
-
- if (new_y < 0)
- cursor->y = 0;
- else if (new_y > 480)
- cursor->y = 480;
- else
- cursor->y = new_y;
-
- /*
- * FIXME: this is a workaround for cursor plane update,
- * remove it later!
- */
- rect->x = 0;
- rect->y = 0;
- rect->width = 864;
- rect->height = 480;
-
- mdfld_check_boundary(dpu_info, rect);
- mdfld_dpu_region_extent(pipe_rect, rect);
-
- /* Update pending status of dpu_info */
- dpu_info->pending |= (1 << plane);
- /* Update fb panel as well */
- dpu_info->pending |= (1 << fb_plane);
- return 0;
-}
-
-static int mdfld_fb_damage(struct mdfld_dbi_dpu_info *dpu_info,
- mdfld_plane_t plane,
- struct psb_drm_dpu_rect *damaged_rect)
-{
- struct psb_drm_dpu_rect *rect;
-
- if (plane == MDFLD_PLANEA)
- rect = &dpu_info->damage_pipea;
- else
- rect = &dpu_info->damage_pipec;
-
- mdfld_check_boundary(dpu_info, damaged_rect);
-
- /* Add fb damage area to this pipe */
- mdfld_dpu_region_extent(rect, damaged_rect);
-
- /* Update pending status of dpu_info */
- dpu_info->pending |= (1 << plane);
- return 0;
-}
-
-/* Do nothing here, right now */
-static int mdfld_overlay_damage(struct mdfld_dbi_dpu_info *dpu_info,
- mdfld_plane_t plane,
- struct psb_drm_dpu_rect *damaged_rect)
-{
- return 0;
-}
-
-int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
- mdfld_plane_t plane,
- struct psb_drm_dpu_rect *rect)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
- int ret = 0;
-
- /* DPU not in use, no damage reporting needed */
- if (dpu_info == NULL)
- return 0;
-
- spin_lock(&dpu_info->dpu_update_lock);
-
- switch (plane) {
- case MDFLD_PLANEA:
- case MDFLD_PLANEC:
- mdfld_fb_damage(dpu_info, plane, rect);
- break;
- case MDFLD_CURSORA:
- case MDFLD_CURSORC:
- mdfld_cursor_damage(dpu_info, plane, rect);
- break;
- case MDFLD_OVERLAYA:
- case MDFLD_OVERLAYC:
- mdfld_overlay_damage(dpu_info, plane, rect);
- break;
- default:
- DRM_ERROR("Invalid plane type %d\n", plane);
- ret = -EINVAL;
- }
- spin_unlock(&dpu_info->dpu_update_lock);
- return ret;
-}
-
-int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv;
- struct mdfld_dbi_dpu_info *dpu_info;
- struct mdfld_dsi_config *dsi_config;
- struct psb_drm_dpu_rect rect;
- int i;
-
- if (!dev) {
- DRM_ERROR("Invalid parameter\n");
- return -EINVAL;
- }
-
- dev_priv = dev->dev_private;
- dpu_info = dev_priv->dbi_dpu_info;
-
- /* This is fine - we may be in non DPU mode */
- if (!dpu_info)
- return -EINVAL;
-
- for (i = 0; i < dpu_info->dbi_output_num; i++) {
- dsi_config = dev_priv->dsi_configs[i];
- if (dsi_config) {
- rect.x = rect.y = 0;
- rect.width = dsi_config->fixed_mode->hdisplay;
- rect.height = dsi_config->fixed_mode->vdisplay;
- mdfld_dbi_dpu_report_damage(dev,
- i ? (MDFLD_PLANEC) : (MDFLD_PLANEA),
- &rect);
- }
- }
- /* Exit DSR state */
- mdfld_dpu_exit_dsr(dev);
- return 0;
-}
-
-int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
- struct psb_drm_dpu_rect *rect)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
- mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, rect);
-
- /* If dual display mode */
- if (dpu_info->dbi_output_num == 2)
- mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, rect);
-
- /* Force dsi to exit DSR mode */
- mdfld_dpu_exit_dsr(dev);
- return 0;
-}
-
-static void mdfld_dpu_cursor_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
- mdfld_plane_t plane)
-{
- struct drm_device *dev = dpu_info->dev;
- u32 curpos_reg = CURAPOS;
- u32 curbase_reg = CURABASE;
- u32 curcntr_reg = CURACNTR;
- struct mdfld_cursor_info *cursor = &dpu_info->cursors[0];
-
- if (plane == MDFLD_CURSORC) {
- curpos_reg = CURCPOS;
- curbase_reg = CURCBASE;
- curcntr_reg = CURCCNTR;
- cursor = &dpu_info->cursors[1];
- }
-
- REG_WRITE(curcntr_reg, REG_READ(curcntr_reg));
- REG_WRITE(curpos_reg,
- (((cursor->x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |
- ((cursor->y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT)));
- REG_WRITE(curbase_reg, REG_READ(curbase_reg));
-}
-
-static void mdfld_dpu_fb_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
- mdfld_plane_t plane)
-{
- u32 pipesrc_reg = PIPEASRC;
- u32 dspsize_reg = DSPASIZE;
- u32 dspoff_reg = DSPALINOFF;
- u32 dspsurf_reg = DSPASURF;
- u32 dspstride_reg = DSPASTRIDE;
- u32 stride;
- struct psb_drm_dpu_rect *rect = &dpu_info->damage_pipea;
- struct drm_device *dev = dpu_info->dev;
-
- if (plane == MDFLD_PLANEC) {
- pipesrc_reg = PIPECSRC;
- dspsize_reg = DSPCSIZE;
- dspoff_reg = DSPCLINOFF;
- dspsurf_reg = DSPCSURF;
- dspstride_reg = DSPCSTRIDE;
- rect = &dpu_info->damage_pipec;
- }
-
- stride = REG_READ(dspstride_reg);
- /* FIXME: should I do the pipe src update here? */
- REG_WRITE(pipesrc_reg, ((rect->width - 1) << 16) | (rect->height - 1));
- /* Flush plane */
- REG_WRITE(dspsize_reg, ((rect->height - 1) << 16) | (rect->width - 1));
- REG_WRITE(dspoff_reg, ((rect->x * 4) + (rect->y * stride)));
- REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-
- /*
- * TODO: wait for flip finished and restore the pipesrc reg,
- * or cursor will be show at a wrong position
- */
-}
-
-static void mdfld_dpu_overlay_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
- mdfld_plane_t plane)
-{
-}
-
-/*
- * TODO: we are still in dbi normal mode now, we will try to use partial
- * mode later.
- */
-static int mdfld_dbi_prepare_cb(struct mdfld_dsi_dbi_output *dbi_output,
- struct mdfld_dbi_dpu_info *dpu_info, int pipe)
-{
- u8 *cb_addr = (u8 *)dbi_output->dbi_cb_addr;
- u32 *index;
- struct psb_drm_dpu_rect *rect = pipe ?
- (&dpu_info->damage_pipec) : (&dpu_info->damage_pipea);
-
- /* FIXME: lock command buffer, this may lead to a deadlock,
- as we already hold the dpu_update_lock */
- if (!spin_trylock(&dbi_output->cb_lock)) {
- DRM_ERROR("lock command buffer failed, try again\n");
- return -EAGAIN;
- }
-
- index = &dbi_output->cb_write;
-
- if (*index) {
- DRM_ERROR("DBI command buffer unclean\n");
- return -EAGAIN;
- }
-
- /* Column address */
- *(cb_addr + ((*index)++)) = set_column_address;
- *(cb_addr + ((*index)++)) = rect->x >> 8;
- *(cb_addr + ((*index)++)) = rect->x;
- *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1) >> 8;
- *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1);
-
- *index = 8;
-
- /* Page address */
- *(cb_addr + ((*index)++)) = set_page_addr;
- *(cb_addr + ((*index)++)) = rect->y >> 8;
- *(cb_addr + ((*index)++)) = rect->y;
- *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1) >> 8;
- *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1);
-
- *index = 16;
-
- /*write memory*/
- *(cb_addr + ((*index)++)) = write_mem_start;
-
- return 0;
-}
-
-static int mdfld_dbi_flush_cb(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
-{
- u32 cmd_phy = dbi_output->dbi_cb_phy;
- u32 *index = &dbi_output->cb_write;
- int reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- struct drm_device *dev = dbi_output->dev;
-
- if (*index == 0 || !dbi_output)
- return 0;
-
- REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 0x010505);
- REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | 3);
-
- *index = 0;
-
- /* FIXME: unlock command buffer */
- spin_unlock(&dbi_output->cb_lock);
- return 0;
-}
-
-static int mdfld_dpu_update_pipe(struct mdfld_dsi_dbi_output *dbi_output,
- struct mdfld_dbi_dpu_info *dpu_info, int pipe)
-{
- struct drm_device *dev = dbi_output->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- mdfld_plane_t cursor_plane = MDFLD_CURSORA;
- mdfld_plane_t fb_plane = MDFLD_PLANEA;
- mdfld_plane_t overlay_plane = MDFLD_OVERLAYA;
- int ret = 0;
- u32 plane_mask = MDFLD_PIPEA_PLANE_MASK;
-
- /* Damaged rects on this pipe */
- if (pipe) {
- cursor_plane = MDFLD_CURSORC;
- fb_plane = MDFLD_PLANEC;
- overlay_plane = MDFLD_OVERLAYC;
- plane_mask = MDFLD_PIPEC_PLANE_MASK;
- }
-
- /*update cursor which assigned to @pipe*/
- if (dpu_info->pending & (1 << cursor_plane))
- mdfld_dpu_cursor_plane_flush(dpu_info, cursor_plane);
-
- /*update fb which assigned to @pipe*/
- if (dpu_info->pending & (1 << fb_plane))
- mdfld_dpu_fb_plane_flush(dpu_info, fb_plane);
-
- /* TODO: update overlay */
- if (dpu_info->pending & (1 << overlay_plane))
- mdfld_dpu_overlay_plane_flush(dpu_info, overlay_plane);
-
- /* Flush damage area to panel fb */
- if (dpu_info->pending & plane_mask) {
- ret = mdfld_dbi_prepare_cb(dbi_output, dpu_info, pipe);
- /*
- * TODO: remove b_dsr_enable later,
- * added it so that text console could boot smoothly
- */
- /* Clean pending flags on this pipe */
- if (!ret && dev_priv->dsr_enable) {
- dpu_info->pending &= ~plane_mask;
- /* Reset overlay pipe damage rect */
- mdfld_dpu_init_damage(dpu_info, pipe);
- }
- }
- return ret;
-}
-
-static int mdfld_dpu_update_fb(struct drm_device *dev)
-{
- struct drm_crtc *crtc;
- struct psb_intel_crtc *psb_crtc;
- struct mdfld_dsi_dbi_output **dbi_output;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
- bool pipe_updated[2];
- unsigned long irq_flags;
- u32 dpll_reg = MRST_DPLL_A;
- u32 dspcntr_reg = DSPACNTR;
- u32 pipeconf_reg = PIPEACONF;
- u32 dsplinoff_reg = DSPALINOFF;
- u32 dspsurf_reg = DSPASURF;
- u32 mipi_state_reg = MIPIA_INTR_STAT_REG;
- u32 reg_offset = 0;
- int pipe;
- int i;
- int ret;
-
- dbi_output = dpu_info->dbi_outputs;
- pipe_updated[0] = pipe_updated[1] = false;
-
- if (!gma_power_begin(dev, true))
- return -EAGAIN;
-
- /* Try to prevent any new damage reports */
- if (!spin_trylock_irqsave(&dpu_info->dpu_update_lock, irq_flags))
- return -EAGAIN;
-
- for (i = 0; i < dpu_info->dbi_output_num; i++) {
- crtc = dbi_output[i]->base.base.crtc;
- psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL;
-
- pipe = dbi_output[i]->channel_num ? 2 : 0;
-
- if (pipe == 2) {
- dspcntr_reg = DSPCCNTR;
- pipeconf_reg = PIPECCONF;
- dsplinoff_reg = DSPCLINOFF;
- dspsurf_reg = DSPCSURF;
- reg_offset = MIPIC_REG_OFFSET;
- }
-
- if (!(REG_READ((MIPIA_GEN_FIFO_STAT_REG + reg_offset))
- & (1 << 27)) ||
- !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
- !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
- !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
- dev_err(dev->dev,
- "DBI FIFO is busy, DSI %d state %x\n",
- pipe,
- REG_READ(mipi_state_reg + reg_offset));
- continue;
- }
-
- /*
- * If DBI output is in a exclusive state then the pipe
- * change won't be updated
- */
- if (dbi_output[i]->dbi_panel_on &&
- !(dbi_output[i]->mode_flags & MODE_SETTING_ON_GOING) &&
- !(psb_crtc &&
- psb_crtc->mode_flags & MODE_SETTING_ON_GOING) &&
- !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
- ret = mdfld_dpu_update_pipe(dbi_output[i],
- dpu_info, dbi_output[i]->channel_num ? 2 : 0);
- if (!ret)
- pipe_updated[i] = true;
- }
- }
-
- for (i = 0; i < dpu_info->dbi_output_num; i++)
- if (pipe_updated[i])
- mdfld_dbi_flush_cb(dbi_output[i],
- dbi_output[i]->channel_num ? 2 : 0);
-
- spin_unlock_irqrestore(&dpu_info->dpu_update_lock, irq_flags);
- gma_power_end(dev);
- return 0;
-}
-
-static int __mdfld_dbi_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
- int pipe)
-{
- struct drm_device *dev = dbi_output->dev;
- struct drm_crtc *crtc = dbi_output->base.base.crtc;
- struct psb_intel_crtc *psb_crtc = (crtc) ? to_psb_intel_crtc(crtc)
- : NULL;
- u32 reg_val;
- u32 dpll_reg = MRST_DPLL_A;
- u32 pipeconf_reg = PIPEACONF;
- u32 dspcntr_reg = DSPACNTR;
- u32 dspbase_reg = DSPABASE;
- u32 dspsurf_reg = DSPASURF;
- u32 reg_offset = 0;
-
- if (!dbi_output)
- return 0;
-
- /* If mode setting on-going, back off */
- if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
- (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
- return -EAGAIN;
-
- if (pipe == 2) {
- dpll_reg = MRST_DPLL_A;
- pipeconf_reg = PIPECCONF;
- dspcntr_reg = DSPCCNTR;
- dspbase_reg = MDFLD_DSPCBASE;
- dspsurf_reg = DSPCSURF;
-
- reg_offset = MIPIC_REG_OFFSET;
- }
-
- if (!gma_power_begin(dev, true))
- return -EAGAIN;
-
- /* Enable DPLL */
- reg_val = REG_READ(dpll_reg);
- if (!(reg_val & DPLL_VCO_ENABLE)) {
-
- if (reg_val & MDFLD_PWR_GATE_EN) {
- reg_val &= ~MDFLD_PWR_GATE_EN;
- REG_WRITE(dpll_reg, reg_val);
- REG_READ(dpll_reg);
- udelay(500);
- }
-
- reg_val |= DPLL_VCO_ENABLE;
- REG_WRITE(dpll_reg, reg_val);
- REG_READ(dpll_reg);
- udelay(500);
-
- /* FIXME: add timeout */
- while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
- cpu_relax();
- }
-
- /* Enable pipe */
- reg_val = REG_READ(pipeconf_reg);
- if (!(reg_val & PIPEACONF_ENABLE)) {
- reg_val |= PIPEACONF_ENABLE;
- REG_WRITE(pipeconf_reg, reg_val);
- REG_READ(pipeconf_reg);
- udelay(500);
- mdfldWaitForPipeEnable(dev, pipe);
- }
-
- /* Enable plane */
- reg_val = REG_READ(dspcntr_reg);
- if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
- reg_val |= DISPLAY_PLANE_ENABLE;
- REG_WRITE(dspcntr_reg, reg_val);
- REG_READ(dspcntr_reg);
- udelay(500);
- }
-
- gma_power_end(dev);
-
- /* Clean IN_DSR flag */
- dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-
- return 0;
-}
-
-int mdfld_dpu_exit_dsr(struct drm_device *dev)
-{
- struct mdfld_dsi_dbi_output **dbi_output;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
- int i;
- int pipe;
-
- dbi_output = dpu_info->dbi_outputs;
-
- for (i = 0; i < dpu_info->dbi_output_num; i++) {
- /* If this output is not in DSR mode, don't call exit dsr */
- if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)
- __mdfld_dbi_exit_dsr(dbi_output[i],
- dbi_output[i]->channel_num ? 2 : 0);
- }
-
- /* Enable TE interrupt */
- for (i = 0; i < dpu_info->dbi_output_num; i++) {
- /* If this output is not in DSR mode, don't call exit dsr */
- pipe = dbi_output[i]->channel_num ? 2 : 0;
- if (dbi_output[i]->dbi_panel_on && pipe) {
- mdfld_disable_te(dev, 0);
- mdfld_enable_te(dev, 2);
- } else if (dbi_output[i]->dbi_panel_on && !pipe) {
- mdfld_disable_te(dev, 2);
- mdfld_enable_te(dev, 0);
- }
- }
- return 0;
-}
-
-static int mdfld_dpu_enter_dsr(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
- struct mdfld_dsi_dbi_output **dbi_output;
- int i;
-
- dbi_output = dpu_info->dbi_outputs;
-
- for (i = 0; i < dpu_info->dbi_output_num; i++) {
- /* If output is off or already in DSR state, don't re-enter */
- if (dbi_output[i]->dbi_panel_on &&
- !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
- mdfld_dsi_dbi_enter_dsr(dbi_output[i],
- dbi_output[i]->channel_num ? 2 : 0);
- }
- }
-
- return 0;
-}
-
-static void mdfld_dbi_dpu_timer_func(unsigned long data)
-{
- struct drm_device *dev = (struct drm_device *)data;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
- struct timer_list *dpu_timer = &dpu_info->dpu_timer;
- unsigned long flags;
-
- if (dpu_info->pending) {
- dpu_info->idle_count = 0;
- /* Update panel fb with damaged area */
- mdfld_dpu_update_fb(dev);
- } else {
- dpu_info->idle_count++;
- }
-
- if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
- mdfld_dpu_enter_dsr(dev);
- /* Stop timer by return */
- return;
- }
-
- spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
- if (!timer_pending(dpu_timer)) {
- dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
- add_timer(dpu_timer);
- }
- spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-}
-
-void mdfld_dpu_update_panel(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
- if (dpu_info->pending) {
- dpu_info->idle_count = 0;
-
- /*update panel fb with damaged area*/
- mdfld_dpu_update_fb(dev);
- } else {
- dpu_info->idle_count++;
- }
-
- if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
- /*enter dsr*/
- mdfld_dpu_enter_dsr(dev);
- }
-}
-
-static int mdfld_dbi_dpu_timer_init(struct drm_device *dev,
- struct mdfld_dbi_dpu_info *dpu_info)
-{
- struct timer_list *dpu_timer = &dpu_info->dpu_timer;
- unsigned long flags;
-
- spin_lock_init(&dpu_info->dpu_timer_lock);
- spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
-
- init_timer(dpu_timer);
-
- dpu_timer->data = (unsigned long)dev;
- dpu_timer->function = mdfld_dbi_dpu_timer_func;
- dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
-
- spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-
- return 0;
-}
-
-void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info)
-{
- struct timer_list *dpu_timer = &dpu_info->dpu_timer;
- unsigned long flags;
-
- spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
- if (!timer_pending(dpu_timer)) {
- dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
- add_timer(dpu_timer);
- }
- spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-}
-
-int mdfld_dbi_dpu_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
- if (!dpu_info || IS_ERR(dpu_info)) {
- dpu_info = kzalloc(sizeof(struct mdfld_dbi_dpu_info),
- GFP_KERNEL);
- if (!dpu_info) {
- DRM_ERROR("No memory\n");
- return -ENOMEM;
- }
- dev_priv->dbi_dpu_info = dpu_info;
- }
-
- dpu_info->dev = dev;
-
- dpu_info->cursors[0].size = MDFLD_CURSOR_SIZE;
- dpu_info->cursors[1].size = MDFLD_CURSOR_SIZE;
-
- /*init dpu_update_lock*/
- spin_lock_init(&dpu_info->dpu_update_lock);
-
- /*init dpu refresh timer*/
- mdfld_dbi_dpu_timer_init(dev, dpu_info);
-
- /*init pipe damage area*/
- mdfld_dpu_init_damage(dpu_info, 0);
- mdfld_dpu_init_damage(dpu_info, 2);
-
- return 0;
-}
-
-void mdfld_dbi_dpu_exit(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
- if (!dpu_info)
- return;
-
- del_timer_sync(&dpu_info->dpu_timer);
- kfree(dpu_info);
- dev_priv->dbi_dpu_info = NULL;
-}
-
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
deleted file mode 100644
index 42367ed48c08..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#ifndef __MDFLD_DSI_DBI_DPU_H__
-#define __MDFLD_DSI_DBI_DPU_H__
-
-#include "mdfld_dsi_dbi.h"
-
-typedef enum {
- MDFLD_PLANEA,
- MDFLD_PLANEC,
- MDFLD_CURSORA,
- MDFLD_CURSORC,
- MDFLD_OVERLAYA,
- MDFLD_OVERLAYC,
- MDFLD_PLANE_NUM,
-} mdfld_plane_t;
-
-#define MDFLD_PIPEA_PLANE_MASK 0x15
-#define MDFLD_PIPEC_PLANE_MASK 0x2A
-
-struct mdfld_cursor_info {
- int x, y;
- int size;
-};
-
-#define MDFLD_CURSOR_SIZE 64
-
-/*
- * enter DSR mode if screen has no update for 2 frames.
- */
-#define MDFLD_MAX_IDLE_COUNT 2
-
-struct mdfld_dbi_dpu_info {
- struct drm_device *dev;
- /* Lock */
- spinlock_t dpu_update_lock;
-
- /* Cursor postion */
- struct mdfld_cursor_info cursors[2];
-
- /* Damaged area for each plane */
- struct psb_drm_dpu_rect damaged_rects[MDFLD_PLANE_NUM];
-
- /* Final damaged area */
- struct psb_drm_dpu_rect damage_pipea;
- struct psb_drm_dpu_rect damage_pipec;
-
- /* Pending */
- u32 pending;
-
- /* DPU timer */
- struct timer_list dpu_timer;
- spinlock_t dpu_timer_lock;
-
- /* DPU idle count */
- u32 idle_count;
-
- /* DSI outputs */
- struct mdfld_dsi_dbi_output *dbi_outputs[2];
- int dbi_output_num;
-};
-
-static inline int mdfld_dpu_region_extent(struct psb_drm_dpu_rect *origin,
- struct psb_drm_dpu_rect *rect)
-{
- int x1, y1, x2, y2;
-
- x1 = origin->x + origin->width;
- y1 = origin->y + origin->height;
-
- x2 = rect->x + rect->width;
- y2 = rect->y + rect->height;
-
- origin->x = min(origin->x, rect->x);
- origin->y = min(origin->y, rect->y);
- origin->width = max(x1, x2) - origin->x;
- origin->height = max(y1, y2) - origin->y;
-
- return 0;
-}
-
-static inline void mdfld_check_boundary(struct mdfld_dbi_dpu_info *dpu_info,
- struct psb_drm_dpu_rect *rect)
-{
- if (rect->x < 0)
- rect->x = 0;
- if (rect->y < 0)
- rect->y = 0;
-
- if (rect->x + rect->width > 864)
- rect->width = 864 - rect->x;
- if (rect->y + rect->height > 480)
- rect->height = 480 - rect->height;
-
- if (!rect->width)
- rect->width = 1;
- if (!rect->height)
- rect->height = 1;
-}
-
-static inline void mdfld_dpu_init_damage(struct mdfld_dbi_dpu_info *dpu_info,
- int pipe)
-{
- struct psb_drm_dpu_rect *rect;
-
- if (pipe == 0)
- rect = &dpu_info->damage_pipea;
- else
- rect = &dpu_info->damage_pipec;
-
- rect->x = 864;
- rect->y = 480;
- rect->width = -864;
- rect->height = -480;
-}
-
-extern int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
- struct psb_drm_dpu_rect *rect);
-extern int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
- mdfld_plane_t plane,
- struct psb_drm_dpu_rect *rect);
-extern int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev);
-extern int mdfld_dpu_exit_dsr(struct drm_device *dev);
-extern void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info);
-extern int mdfld_dbi_dpu_init(struct drm_device *dev);
-extern void mdfld_dbi_dpu_exit(struct drm_device *dev);
-extern void mdfld_dpu_update_panel(struct drm_device *dev);
-
-#endif /*__MDFLD_DSI_DBI_DPU_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.c b/drivers/staging/gma500/mdfld_dsi_dpi.c
deleted file mode 100644
index e685f1217baa..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_dpi.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-
-static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
-{
- u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
- int timeout = 0;
-
- if (pipe == 2)
- gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
- udelay(500);
-
- /* This will time out after approximately 2+ seconds */
- while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
- udelay(100);
- timeout++;
- }
-
- if (timeout == 20000)
- dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
-{
- u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
- int timeout = 0;
-
- if (pipe == 2)
- gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
- udelay(500);
-
- /* This will time out after approximately 2+ seconds */
- while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) {
- udelay(100);
- timeout++;
- }
- if (timeout == 20000)
- dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
-{
- u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
- int timeout = 0;
-
- if (pipe == 2)
- gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
- udelay(500);
-
- /* This will time out after approximately 2+ seconds */
- while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY)
- != DPI_FIFO_EMPTY)) {
- udelay(100);
- timeout++;
- }
-
- if (timeout == 20000)
- dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
-{
- u32 intr_stat_reg = MIPIA_INTR_STAT_REG;
- int timeout = 0;
-
- if (pipe == 2)
- intr_stat_reg += MIPIC_REG_OFFSET;
-
- udelay(500);
-
- /* This will time out after approximately 2+ seconds */
- while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) {
- udelay(100);
- timeout++;
- }
-
- if (timeout == 20000)
- dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
-}
-
-
-/* ************************************************************************* *\
- * FUNCTION: mdfld_dsi_tpo_ic_init
- *
- * DESCRIPTION: This function is called only by mrst_dsi_mode_set and
- * restore_display_registers. since this function does not
- * acquire the mutex, it is important that the calling function
- * does!
-\* ************************************************************************* */
-void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
-{
- struct drm_device *dev = dsi_config->dev;
- u32 dcsChannelNumber = dsi_config->channel_num;
- u32 gen_data_reg = MIPIA_HS_GEN_DATA_REG;
- u32 gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
- u32 gen_ctrl_val = GEN_LONG_WRITE;
-
- if (pipe == 2) {
- gen_data_reg = HS_GEN_DATA_REG + MIPIC_REG_OFFSET;
- gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
- }
-
- gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
-
- /* Flip page order */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x00008036);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
-
- /* 0xF0 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x005a5af0);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
- /* Write protection key */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x005a5af1);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
- /* 0xFC */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x005a5afc);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
- /* 0xB7 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x770000b7);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x00000044);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS));
-
- /* 0xB6 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x000a0ab6);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
- /* 0xF2 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x081010f2);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x4a070708);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x000000c5);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
- /* 0xF8 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x024003f8);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x01030a04);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x0e020220);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x00000004);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS));
-
- /* 0xE2 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x398fc3e2);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x0000916f);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS));
-
- /* 0xB0 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x000000b0);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
-
- /* 0xF4 */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x240242f4);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x78ee2002);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x2a071050);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x507fee10);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x10300710);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS));
-
- /* 0xBA */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x19fe07ba);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x101c0a31);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x00000010);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
- /* 0xBB */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x28ff07bb);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x24280a31);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x00000034);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
- /* 0xFB */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x535d05fb);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x1b1a2130);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x221e180e);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x131d2120);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x535d0508);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x1c1a2131);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x231f160d);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x111b2220);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x535c2008);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x1f1d2433);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x2c251a10);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x2c34372d);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x00000023);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
-
- /* 0xFA */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x525c0bfa);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x1c1c232f);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x2623190e);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x18212625);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x545d0d0e);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x1e1d2333);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x26231a10);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x1a222725);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x545d280f);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x21202635);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x31292013);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x31393d33);
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x00000029);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
-
- /* Set DM */
- mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
- REG_WRITE(gen_data_reg, 0x000100f7);
- mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
- REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-}
-
-static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count,
- int num_lane, int bpp)
-{
- return (u16)((pixel_clock_count * bpp) / (num_lane * 8));
-}
-
-/*
- * Calculate the dpi time basing on a given drm mode @mode
- * return 0 on success.
- * FIXME: I was using proposed mode value for calculation, may need to
- * use crtc mode values later
- */
-int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode,
- struct mdfld_dsi_dpi_timing *dpi_timing,
- int num_lane, int bpp)
-{
- int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
- int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive;
-
- if(!mode || !dpi_timing) {
- DRM_ERROR("Invalid parameter\n");
- return -EINVAL;
- }
-
- pclk_hactive = mode->hdisplay;
- pclk_hfp = mode->hsync_start - mode->hdisplay;
- pclk_hsync = mode->hsync_end - mode->hsync_start;
- pclk_hbp = mode->htotal - mode->hsync_end;
-
- pclk_vactive = mode->vdisplay;
- pclk_vfp = mode->vsync_start - mode->vdisplay;
- pclk_vsync = mode->vsync_end - mode->vsync_start;
- pclk_vbp = mode->vtotal - mode->vsync_end;
-
- /*
- * byte clock counts were calculated by following formula
- * bclock_count = pclk_count * bpp / num_lane / 8
- */
- dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp);
- dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp);
- dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp);
- dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp);
- dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp);
- dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp);
- dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp);
-
- return 0;
-}
-
-void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
- struct drm_device *dev = dsi_config->dev;
- u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- int lane_count = dsi_config->lane_count;
- struct mdfld_dsi_dpi_timing dpi_timing;
- struct drm_display_mode *mode = dsi_config->mode;
- u32 val = 0;
-
- /*un-ready device*/
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
- /*init dsi adapter before kicking off*/
- REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
- /*enable all interrupts*/
- REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-
-
- /*set up func_prg*/
- val |= lane_count;
- val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
-
- switch(dsi_config->bpp) {
- case 16:
- val |= DSI_DPI_COLOR_FORMAT_RGB565;
- break;
- case 18:
- val |= DSI_DPI_COLOR_FORMAT_RGB666;
- break;
- case 24:
- val |= DSI_DPI_COLOR_FORMAT_RGB888;
- break;
- default:
- DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
- }
- REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
- REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset),
- (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
- REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
-
- /*max value: 20 clock cycles of txclkesc*/
- REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
-
- /*min 21 txclkesc, max: ffffh*/
- REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
-
- REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
-
- /*set DPI timing registers*/
- mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
-
- REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
-
- REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-
- /*min: 7d0 max: 4e20*/
- REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
-
- /*set up video mode*/
- val = 0;
- val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
- REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
-
- REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-
- REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-
- /*TODO: figure out how to setup these registers*/
- REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-
- REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
- /*set device ready*/
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
-{
- struct drm_device *dev = output->dev;
- u32 reg_offset = 0;
-
- if(output->panel_on)
- return;
-
- if(pipe)
- reg_offset = MIPIC_REG_OFFSET;
-
- /* clear special packet sent bit */
- if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
- REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
- }
-
- /*send turn on package*/
- REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
-
- /*wait for SPL_PKG_SENT interrupt*/
- mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
-
- if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
- REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
- }
-
- output->panel_on = 1;
-
- /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
- /* if(pipe == 2) */
- /* dev_priv->dpi_panel_on2 = true; */
- /* else if (pipe == 0) */
- /* dev_priv->dpi_panel_on = true; */
-}
-
-static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe)
-{
- struct drm_device *dev = output->dev;
- u32 reg_offset = 0;
-
- /*if output is on, or mode setting didn't happen, ignore this*/
- if((!output->panel_on) || output->first_boot) {
- output->first_boot = 0;
- return;
- }
-
- if(pipe)
- reg_offset = MIPIC_REG_OFFSET;
-
- /* Wait for dpi fifo to empty */
- mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
-
- /* Clear the special packet interrupt bit if set */
- if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
- REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
- }
-
- if(REG_READ(MIPIA_DPI_CONTROL_REG + reg_offset) == DSI_DPI_CTRL_HS_SHUTDOWN) {
- dev_warn(dev->dev, "try to send the same package again, abort!");
- goto shutdown_out;
- }
-
- REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
-
-shutdown_out:
- output->panel_on = 0;
- output->first_boot = 0;
-
- /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
- /* if(pipe == 2) */
- /* dev_priv->dpi_panel_on2 = false; */
- /* else if (pipe == 0) */
- /* dev_priv->dpi_panel_on = false; */
- /* #ifdef CONFIG_PM_RUNTIME*/
- /* if (drm_psb_ospm && !enable_gfx_rtpm) { */
- /* pm_runtime_allow(&gpDrmDevice->pdev->dev); */
- /* schedule_delayed_work(&dev_priv->rtpm_work, 30 * 1000); */
- /* } */
- /*if (enable_gfx_rtpm) */
- /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
- /* #endif */
-}
-
-void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
- struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
- int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
- struct drm_device *dev = dsi_config->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 mipi_reg = MIPI;
- u32 pipeconf_reg = PIPEACONF;
-
- if(pipe) {
- mipi_reg = MIPI_C;
- pipeconf_reg = PIPECCONF;
- }
-
- /* Start up display island if it was shutdown */
- if (!gma_power_begin(dev, true))
- return;
-
- if(on) {
- if (mdfld_get_panel_type(dev, pipe) == TMD_VID){
- mdfld_dsi_dpi_turn_on(dpi_output, pipe);
- } else {
- /* Enable mipi port */
- REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31)));
- REG_READ(mipi_reg);
-
- mdfld_dsi_dpi_turn_on(dpi_output, pipe);
- mdfld_dsi_tpo_ic_init(dsi_config, pipe);
- }
-
- if(pipe == 2) {
- dev_priv->dpi_panel_on2 = true;
- }
- else {
- dev_priv->dpi_panel_on = true;
- }
-
- } else {
- if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
- mdfld_dsi_dpi_shut_down(dpi_output, pipe);
- } else {
- mdfld_dsi_dpi_shut_down(dpi_output, pipe);
- /* Disable mipi port */
- REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31)));
- REG_READ(mipi_reg);
- }
-
- if(pipe == 2)
- dev_priv->dpi_panel_on2 = false;
- else
- dev_priv->dpi_panel_on = false;
- }
- gma_power_end(dev);
-}
-
-void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
-{
- dev_dbg(encoder->dev->dev, "DPMS %s\n",
- (mode == DRM_MODE_DPMS_ON ? "on":"off"));
-
- if (mode == DRM_MODE_DPMS_ON)
- mdfld_dsi_dpi_set_power(encoder, true);
- else {
- mdfld_dsi_dpi_set_power(encoder, false);
-#if 0 /* FIXME */
-#ifdef CONFIG_PM_RUNTIME
- if (enable_gfx_rtpm)
- pm_schedule_suspend(&gpDrmDevice->pdev->dev, gfxrtdelay);
-#endif
-#endif
- }
-}
-
-bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
- struct drm_display_mode *fixed_mode = dsi_config->fixed_mode;
-
- if(fixed_mode) {
- adjusted_mode->hdisplay = fixed_mode->hdisplay;
- adjusted_mode->hsync_start = fixed_mode->hsync_start;
- adjusted_mode->hsync_end = fixed_mode->hsync_end;
- adjusted_mode->htotal = fixed_mode->htotal;
- adjusted_mode->vdisplay = fixed_mode->vdisplay;
- adjusted_mode->vsync_start = fixed_mode->vsync_start;
- adjusted_mode->vsync_end = fixed_mode->vsync_end;
- adjusted_mode->vtotal = fixed_mode->vtotal;
- adjusted_mode->clock = fixed_mode->clock;
- drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
- }
-
- return true;
-}
-
-void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder)
-{
- mdfld_dsi_dpi_set_power(encoder, false);
-}
-
-void mdfld_dsi_dpi_commit(struct drm_encoder *encoder)
-{
- mdfld_dsi_dpi_set_power(encoder, true);
-}
-
-void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
- struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
- struct drm_device *dev = dsi_config->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
-
- u32 pipeconf_reg = PIPEACONF;
- u32 dspcntr_reg = DSPACNTR;
- u32 mipi_reg = MIPI;
- u32 reg_offset = 0;
-
- u32 pipeconf = dev_priv->pipeconf;
- u32 dspcntr = dev_priv->dspcntr;
- u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
-
- dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
- mode->hdisplay, mode->vdisplay, pipe);
-
- if(pipe) {
- pipeconf_reg = PIPECCONF;
- dspcntr_reg = DSPCCNTR;
- mipi_reg = MIPI_C;
- reg_offset = MIPIC_REG_OFFSET;
- } else {
- mipi |= 2;
- }
-
- if (!gma_power_begin(dev, true))
- return;
-
- /* Set up mipi port FIXME: do at init time */
- REG_WRITE(mipi_reg, mipi);
- REG_READ(mipi_reg);
-
- /* Set up DSI controller DPI interface */
- mdfld_dsi_dpi_controller_init(dsi_config, pipe);
-
- if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
- /* Turn on DPI interface */
- mdfld_dsi_dpi_turn_on(dpi_output, pipe);
- }
-
- /* Set up pipe */
- REG_WRITE(pipeconf_reg, pipeconf);
- REG_READ(pipeconf_reg);
-
- /* Set up display plane */
- REG_WRITE(dspcntr_reg, dspcntr);
- REG_READ(dspcntr_reg);
-
- msleep(20); /* FIXME: this should wait for vblank */
-
- dev_dbg(dev->dev, "State %x, power %d\n",
- REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
- dpi_output->panel_on);
-
- if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
- /* Init driver ic */
- mdfld_dsi_tpo_ic_init(dsi_config, pipe);
- /* Init backlight */
- mdfld_dsi_brightness_init(dsi_config, pipe);
- }
- gma_power_end(dev);
-}
-
-
-/*
- * Init DSI DPI encoder.
- * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
- * return pointer of newly allocated DPI encoder, NULL on error
- */
-struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
- struct mdfld_dsi_connector *dsi_connector,
- struct panel_funcs *p_funcs)
-{
- struct mdfld_dsi_dpi_output *dpi_output = NULL;
- struct mdfld_dsi_config *dsi_config;
- struct drm_connector *connector = NULL;
- struct drm_encoder *encoder = NULL;
- struct drm_display_mode *fixed_mode = NULL;
- int pipe;
- u32 data;
- int ret;
-
- if (!dsi_connector || !p_funcs) {
- WARN_ON(1);
- return NULL;
- }
-
- dsi_config = mdfld_dsi_get_config(dsi_connector);
- pipe = dsi_connector->pipe;
-
- /* Panel hard-reset */
- if (p_funcs->reset) {
- ret = p_funcs->reset(pipe);
- if (ret) {
- DRM_ERROR("Panel %d hard-reset failed\n", pipe);
- return NULL;
- }
- }
-
- /* Panel drvIC init */
- if (p_funcs->drv_ic_init)
- p_funcs->drv_ic_init(dsi_config, pipe);
-
- /* Panel power mode detect */
- ret = mdfld_dsi_get_power_mode(dsi_config,
- &data,
- MDFLD_DSI_LP_TRANSMISSION);
- if (ret) {
- DRM_ERROR("Panel %d get power mode failed\n", pipe);
- dsi_connector->status = connector_status_disconnected;
- } else {
- DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
- dsi_connector->status = connector_status_connected;
- }
-
- dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL);
- if(!dpi_output) {
- dev_err(dev->dev, "No memory for dsi_dpi_output\n");
- return NULL;
- }
-
- if(dsi_connector->pipe)
- dpi_output->panel_on = 0;
- else
- dpi_output->panel_on = 0;
-
- dpi_output->dev = dev;
- dpi_output->p_funcs = p_funcs;
- dpi_output->first_boot = 1;
-
- /* Get fixed mode */
- dsi_config = mdfld_dsi_get_config(dsi_connector);
- fixed_mode = dsi_config->fixed_mode;
-
- /* Create drm encoder object */
- connector = &dsi_connector->base.base;
- encoder = &dpi_output->base.base;
- /*
- * On existing hardware this will be a panel of some form,
- * if future devices also have HDMI bridges this will need
- * revisiting
- */
- drm_encoder_init(dev,
- encoder,
- p_funcs->encoder_funcs,
- DRM_MODE_ENCODER_LVDS);
- drm_encoder_helper_add(encoder,
- p_funcs->encoder_helper_funcs);
-
- /* Attach to given connector */
- drm_mode_connector_attach_encoder(connector, encoder);
-
- /* Set possible crtcs and clones */
- if(dsi_connector->pipe) {
- encoder->possible_crtcs = (1 << 2);
- encoder->possible_clones = (1 << 1);
- } else {
- encoder->possible_crtcs = (1 << 0);
- encoder->possible_clones = (1 << 0);
- }
- return &dpi_output->base;
-}
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.h b/drivers/staging/gma500/mdfld_dsi_dpi.h
deleted file mode 100644
index ed92d45ee74a..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_dpi.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#ifndef __MDFLD_DSI_DPI_H__
-#define __MDFLD_DSI_DPI_H__
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-struct mdfld_dsi_dpi_timing {
- u16 hsync_count;
- u16 hbp_count;
- u16 hfp_count;
- u16 hactive_count;
- u16 vsync_count;
- u16 vbp_count;
- u16 vfp_count;
-};
-
-struct mdfld_dsi_dpi_output {
- struct mdfld_dsi_encoder base;
- struct drm_device *dev;
-
- int panel_on;
- int first_boot;
-
- struct panel_funcs *p_funcs;
-};
-
-#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \
- container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base)
-
-extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode,
- struct mdfld_dsi_dpi_timing *dpi_timing,
- int num_lane, int bpp);
-extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
- struct mdfld_dsi_connector *dsi_connector,
- struct panel_funcs *p_funcs);
-
-/* Medfield DPI helper functions */
-extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode);
-extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder);
-extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder);
-extern void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output,
- int pipe);
-extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config,
- int pipe);
-#endif /*__MDFLD_DSI_DPI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c
deleted file mode 100644
index 3f979db2c3a5..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_output.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_output.h"
-#include
-#include "mdfld_dsi_pkg_sender.h"
-#include
-#include
-
-#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
-
-static int CABC_control = 1;
-static int LABC_control = 1;
-
-module_param (CABC_control, int, 0644);
-module_param (LABC_control, int, 0644);
-
-/**
- * make these MCS command global
- * we don't need 'movl' everytime we send them.
- * FIXME: these datas were provided by OEM, we should get them from GCT.
- **/
-static u32 mdfld_dbi_mcs_hysteresis[] = {
- 0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x000000ff,
-};
-
-static u32 mdfld_dbi_mcs_display_profile[] = {
- 0x50281450, 0x0000c882, 0x00000000, 0x00000000,
- 0x00000000,
-};
-
-static u32 mdfld_dbi_mcs_kbbc_profile[] = {
- 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
-};
-
-static u32 mdfld_dbi_mcs_gamma_profile[] = {
- 0x81111158, 0x88888888, 0x88888888,
-};
-
-/*
- * write hysteresis values.
- */
-static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config *dsi_config,
- int pipe)
-{
- struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
- if(!sender) {
- WARN_ON(1);
- return;
- }
- mdfld_dsi_send_mcs_long_hs(sender,
- mdfld_dbi_mcs_hysteresis,
- 17,
- MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write display profile values.
- */
-static void mdfld_dsi_write_display_profile(struct mdfld_dsi_config *dsi_config, int pipe)
-{
- struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
- if(!sender) {
- WARN_ON(1);
- return;
- }
- mdfld_dsi_send_mcs_long_hs(sender,
- mdfld_dbi_mcs_display_profile,
- 5,
- MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write KBBC profile values.
- */
-static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, int pipe)
-{
- struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
- if(!sender) {
- WARN_ON(1);
- return;
- }
- mdfld_dsi_send_mcs_long_hs(sender,
- mdfld_dbi_mcs_kbbc_profile,
- 4,
- MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write gamma setting.
- */
-static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config *dsi_config, int pipe)
-{
- struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
- if(!sender) {
- WARN_ON(1);
- return;
- }
- mdfld_dsi_send_mcs_long_hs(sender,
- mdfld_dbi_mcs_gamma_profile,
- 3,
- MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * Check and see if the generic control or data buffer is empty and ready.
- */
-void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat)
-{
- u32 GEN_BF_time_out_count = 0;
-
- /* Check MIPI Adatper command registers */
- for (GEN_BF_time_out_count = 0; GEN_BF_time_out_count < GEN_FB_TIME_OUT; GEN_BF_time_out_count++)
- {
- if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat)
- break;
- udelay (100);
- }
-
- if (GEN_BF_time_out_count == GEN_FB_TIME_OUT)
- dev_err(dev->dev,
- "mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n",
- gen_fifo_stat_reg);
-}
-
-/*
- * Manage the DSI MIPI keyboard and display brightness.
- * FIXME: this is exported to OSPM code. should work out an specific
- * display interface to OSPM.
- */
-void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
- struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
- struct drm_device *dev = sender->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 gen_ctrl_val;
-
- if(!sender) {
- WARN_ON(1);
- return;
- }
- /* Set default display backlight value to 85% (0xd8)*/
- mdfld_dsi_send_mcs_short_hs(sender,
- write_display_brightness,
- 0xd8,
- 1,
- MDFLD_DSI_SEND_PACKAGE);
-
- /* Set minimum brightness setting of CABC function to 20% (0x33)*/
- mdfld_dsi_send_mcs_short_hs(sender,
- write_cabc_min_bright,
- 0x33,
- 1,
- MDFLD_DSI_SEND_PACKAGE);
-
- mdfld_dsi_write_hysteresis(dsi_config, pipe);
- mdfld_dsi_write_display_profile (dsi_config, pipe);
- mdfld_dsi_write_kbbc_profile (dsi_config, pipe);
- mdfld_dsi_write_gamma_setting (dsi_config, pipe);
-
- /* Enable backlight or/and LABC */
- gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON| BACKLIGHT_ON;
- if (LABC_control == 1 || CABC_control == 1)
- gen_ctrl_val |= DISPLAY_DIMMING_ON| DISPLAY_BRIGHTNESS_AUTO | GAMMA_AUTO;
-
- if (LABC_control == 1)
- gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON;
-
- dev_priv->mipi_ctrl_display = gen_ctrl_val;
-
- mdfld_dsi_send_mcs_short_hs(sender,
- write_ctrl_display,
- (u8)gen_ctrl_val,
- 1,
- MDFLD_DSI_SEND_PACKAGE);
-
- if (CABC_control == 0)
- return;
- mdfld_dsi_send_mcs_short_hs(sender,
- write_ctrl_cabc,
- UI_IMAGE,
- 1,
- MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * Manage the mipi display brightness.
- * TODO: refine this interface later
- */
-void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level)
-{
- struct mdfld_dsi_pkg_sender *sender;
- struct drm_psb_private *dev_priv;
- struct mdfld_dsi_config *dsi_config;
- u32 gen_ctrl_val;
- int p_type;
-
- if (!dev || (pipe != 0 && pipe != 2)) {
- dev_err(dev->dev, "Invalid parameter\n");
- return;
- }
-
- p_type = mdfld_get_panel_type(dev, 0);
-
- dev_priv = dev->dev_private;
-
- if(pipe)
- dsi_config = dev_priv->dsi_configs[1];
- else
- dsi_config = dev_priv->dsi_configs[0];
-
- sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
- if(!sender) {
- WARN_ON(1);
- return;
- }
-
- gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff;
-
- dev_dbg(dev->dev,
- "pipe = %d, gen_ctrl_val = %d. \n", pipe, gen_ctrl_val);
-
- if(p_type == TMD_VID || p_type == TMD_CMD){
- /* Set display backlight value */
- mdfld_dsi_send_mcs_short_hs(sender,
- tmd_write_display_brightness,
- (u8)gen_ctrl_val,
- 1,
- MDFLD_DSI_SEND_PACKAGE);
- } else {
- /* Set display backlight value */
- mdfld_dsi_send_mcs_short_hs(sender,
- write_display_brightness,
- (u8)gen_ctrl_val,
- 1,
- MDFLD_DSI_SEND_PACKAGE);
-
-
- /* Enable backlight control */
- if (level == 0)
- gen_ctrl_val = 0;
- else
- gen_ctrl_val = dev_priv->mipi_ctrl_display;
-
- mdfld_dsi_send_mcs_short_hs(sender,
- write_ctrl_display,
- (u8)gen_ctrl_val,
- 1,
- MDFLD_DSI_SEND_PACKAGE);
- }
-}
-
-/*
- * shut down DSI controller
- */
-void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pipe)
-{
- struct drm_device * dev;
- u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- int retry = 100;
-
- if (!dsi_config) {
- WARN_ON(1);
- return;
- }
-
- dev = dsi_config->dev;
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- if(!(REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY))
- goto shutdown_out;
-
- /* Send shut down package, clean packet send bit first */
- if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
- REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset),
- (REG_READ(MIPIA_INTR_STAT_REG + reg_offset) | DSI_INTR_STATE_SPL_PKG_SENT));
- }
-
- /*send shut down package in HS*/
- REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
-
-
- /*
- * make sure shut down is sent.
- * FIXME: add max retry counter
- */
- while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
- retry--;
-
- if(!retry) {
- dev_err(dev->dev, "timeout\n");
- break;
- }
- }
-
- /*sleep 1 ms to ensure shutdown finished*/
- msleep(100);
-
- /*un-ready device*/
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
- (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & ~DSI_DEVICE_READY));
-
-shutdown_out:
- gma_power_end(dev);
-}
-
-void mdfld_dsi_controller_startup(struct mdfld_dsi_config * dsi_config, int pipe)
-{
- struct drm_device * dev;
- u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- int retry = 100;
-
-
- if (!dsi_config) {
- WARN_ON(1);
- return;
- }
-
- dev = dsi_config->dev;
- dev_dbg(dev->dev, "starting up DSI controller on pipe %d...\n", pipe);
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- if((REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY))
- goto startup_out;
-
- /*if config DPI, turn on DPI interface*/
- if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
- if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
- REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
- }
-
- REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
-
- /*
- * make sure shut down is sent.
- * FIXME: add max retry counter
- */
- while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
- retry--;
- if(!retry) {
- dev_err(dev->dev, "timeout\n");
- break;
- }
- }
-
- msleep(100);
- }
-
- /*set device ready*/
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
- (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) | DSI_DEVICE_READY));
-
-startup_out:
- gma_power_end(dev);
-}
-
-
-static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config,
- u8 dcs,
- u32 *data,
- u8 transmission)
-{
- struct mdfld_dsi_pkg_sender *sender
- = mdfld_dsi_get_pkg_sender(dsi_config);
-
- if (!sender || !data) {
- DRM_ERROR("Invalid parameter\n");
- return -EINVAL;
- }
-
- if (transmission == MDFLD_DSI_HS_TRANSMISSION)
- return mdfld_dsi_read_mcs_hs(sender, dcs, data, 1);
- else if (transmission == MDFLD_DSI_LP_TRANSMISSION)
- return mdfld_dsi_read_mcs_lp(sender, dcs, data, 1);
- else
- return -EINVAL;
-}
-
-int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,
- u32 *mode,
- u8 transmission)
-{
- if (!dsi_config || !mode) {
- DRM_ERROR("Invalid parameter\n");
- return -EINVAL;
- }
-
- return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, transmission);
-}
-
-int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config,
- u32 *result,
- u8 transmission)
-{
- if (!dsi_config || !result) {
- DRM_ERROR("Invalid parameter\n");
- return -EINVAL;
- }
-
- return mdfld_dsi_get_panel_status(dsi_config, 0x0f, result,
- transmission);
-}
-
-/*
- * NOTE: this function was used by OSPM.
- * TODO: will be removed later, should work out display interfaces for OSPM
- */
-void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
- if(!dsi_config || ((pipe != 0) && (pipe != 2))) {
- WARN_ON(1);
- return;
- }
-
- if(dsi_config->type)
- mdfld_dsi_dpi_controller_init(dsi_config, pipe);
- else
- mdfld_dsi_controller_dbi_init(dsi_config, pipe);
-}
-
-static void mdfld_dsi_connector_save(struct drm_connector * connector)
-{
-}
-
-static void mdfld_dsi_connector_restore(struct drm_connector * connector)
-{
-}
-
-static enum drm_connector_status mdfld_dsi_connector_detect(struct drm_connector * connector, bool force)
-{
- struct psb_intel_output *psb_output
- = to_psb_intel_output(connector);
- struct mdfld_dsi_connector *dsi_connector
- = MDFLD_DSI_CONNECTOR(psb_output);
- return dsi_connector->status;
-}
-
-static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t value)
-{
- struct drm_encoder *encoder = connector->encoder;
-
- if (!strcmp(property->name, "scaling mode") && encoder) {
- struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);
- bool bTransitionFromToCentered;
- uint64_t curValue;
-
- if (!psb_crtc)
- goto set_prop_error;
-
- switch (value) {
- case DRM_MODE_SCALE_FULLSCREEN:
- break;
- case DRM_MODE_SCALE_NO_SCALE:
- break;
- case DRM_MODE_SCALE_ASPECT:
- break;
- default:
- goto set_prop_error;
- }
-
- if (drm_connector_property_get_value(connector, property, &curValue))
- goto set_prop_error;
-
- if (curValue == value)
- goto set_prop_done;
-
- if (drm_connector_property_set_value(connector, property, value))
- goto set_prop_error;
-
- bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
- (value == DRM_MODE_SCALE_NO_SCALE);
-
- if (psb_crtc->saved_mode.hdisplay != 0 &&
- psb_crtc->saved_mode.vdisplay != 0) {
- if (bTransitionFromToCentered) {
- if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode,
- encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
- goto set_prop_error;
- } else {
- struct drm_encoder_helper_funcs *pEncHFuncs = encoder->helper_private;
- pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode,
- &psb_crtc->saved_adjusted_mode);
- }
- }
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- } else if (!strcmp(property->name, "backlight") && encoder) {
- struct drm_psb_private *dev_priv = encoder->dev->dev_private;
- struct backlight_device *psb_bd = dev_priv->backlight_device;
- dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);
- if (drm_connector_property_set_value(connector, property, value))
- goto set_prop_error;
- else {
- dev_dbg(encoder->dev->dev,
- "set brightness to %d", (int)value);
- if (psb_bd) {
- psb_bd->props.brightness = value;
- backlight_update_status(psb_bd);
- }
- }
-#endif
- }
-set_prop_done:
- return 0;
-set_prop_error:
- return -1;
-}
-
-static void mdfld_dsi_connector_destroy(struct drm_connector *connector)
-{
- struct psb_intel_output * psb_output = to_psb_intel_output(connector);
- struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
- struct mdfld_dsi_pkg_sender * sender;
-
- if(!dsi_connector)
- return;
-
- drm_sysfs_connector_remove(connector);
- drm_connector_cleanup(connector);
-
- sender = dsi_connector->pkg_sender;
-
- mdfld_dsi_pkg_sender_destroy(sender);
-
- kfree(dsi_connector);
-}
-
-static int mdfld_dsi_connector_get_modes(struct drm_connector * connector)
-{
- struct psb_intel_output * psb_output = to_psb_intel_output(connector);
- struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
- struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
- struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
- struct drm_display_mode * dup_mode = NULL;
- struct drm_device * dev = connector->dev;
-
- connector->display_info.min_vfreq = 0;
- connector->display_info.max_vfreq = 200;
- connector->display_info.min_hfreq = 0;
- connector->display_info.max_hfreq = 200;
-
- if(fixed_mode) {
- dev_dbg(dev->dev, "fixed_mode %dx%d\n",
- fixed_mode->hdisplay, fixed_mode->vdisplay);
-
- dup_mode = drm_mode_duplicate(dev, fixed_mode);
- drm_mode_probed_add(connector, dup_mode);
- return 1;
- }
- dev_err(dev->dev, "Didn't get any modes!\n");
- return 0;
-}
-
-static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode)
-{
- struct psb_intel_output * psb_output = to_psb_intel_output(connector);
- struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
- struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
- struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
-
- dev_dbg(connector->dev->dev, "mode %p, fixed mode %p\n",
- mode, fixed_mode);
-
- if(mode->flags & DRM_MODE_FLAG_DBLSCAN)
- return MODE_NO_DBLESCAN;
-
- if(mode->flags & DRM_MODE_FLAG_INTERLACE)
- return MODE_NO_INTERLACE;
-
- /**
- * FIXME: current DC has no fitting unit, reject any mode setting request
- * will figure out a way to do up-scaling(pannel fitting) later.
- **/
- if(fixed_mode) {
- if(mode->hdisplay != fixed_mode->hdisplay)
- return MODE_PANEL;
-
- if(mode->vdisplay != fixed_mode->vdisplay)
- return MODE_PANEL;
- }
- dev_dbg(connector->dev->dev, "mode ok\n");
-
- return MODE_OK;
-}
-
-static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode)
-{
-#ifdef CONFIG_PM_RUNTIME
- struct drm_device * dev = connector->dev;
- struct drm_psb_private * dev_priv = dev->dev_private;
- bool panel_on, panel_on2;
-#endif
- /* First, execute DPMS */
- drm_helper_connector_dpms(connector, mode);
-
-#ifdef CONFIG_PM_RUNTIME
- if(mdfld_panel_dpi(dev)) {
- /* DPI panel */
- panel_on = dev_priv->dpi_panel_on;
- panel_on2 = dev_priv->dpi_panel_on2;
- } else {
- /* DBI panel */
- panel_on = dev_priv->dbi_panel_on;
- panel_on2 = dev_priv->dbi_panel_on2;
- }
-
- /* Then check all display panels + monitors status */
- /* Make sure that the Display (B) sub-system status isn't i3 when
- * R/W the DC register, otherwise "Fabric error" issue would occur
- * during S0i3 state. */
- if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL)
- & HDMIB_PORT_EN)) {
- /* Request rpm idle */
- if(dev_priv->rpm_enabled)
- pm_request_idle(&dev->pdev->dev);
- }
- /*
- * if rpm wasn't enabled yet, try to allow it
- * FIXME: won't enable rpm for DPI since DPI
- * CRTC setting is a little messy now.
- * Enable it later!
- */
-#if 0
- if(!dev_priv->rpm_enabled && !mdfld_panel_dpi(dev))
- ospm_runtime_pm_allow(dev);
-#endif
-#endif
-}
-
-static struct drm_encoder *mdfld_dsi_connector_best_encoder(
- struct drm_connector *connector)
-{
- struct psb_intel_output * psb_output = to_psb_intel_output(connector);
- struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
- struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
- struct mdfld_dsi_encoder * encoder = NULL;
-
- if(dsi_config->type == MDFLD_DSI_ENCODER_DBI)
- encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI];
- else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
- encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI];
-
- dev_dbg(connector->dev->dev, "get encoder %p\n", encoder);
-
- if(!encoder) {
- dev_err(connector->dev->dev,
- "Invalid encoder for type %d\n", dsi_config->type);
- return NULL;
- }
- dsi_config->encoder = encoder;
- return &encoder->base;
-}
-
-/* DSI connector funcs */
-static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
- .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms,
- .save = mdfld_dsi_connector_save,
- .restore = mdfld_dsi_connector_restore,
- .detect = mdfld_dsi_connector_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = mdfld_dsi_connector_set_property,
- .destroy = mdfld_dsi_connector_destroy,
-};
-
-/* DSI connector helper funcs */
-static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = {
- .get_modes = mdfld_dsi_connector_get_modes,
- .mode_valid = mdfld_dsi_connector_mode_valid,
- .best_encoder = mdfld_dsi_connector_best_encoder,
-};
-
-static int mdfld_dsi_get_default_config(struct drm_device * dev,
- struct mdfld_dsi_config * config, int pipe)
-{
- if(!dev || !config) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- config->bpp = 24;
- config->type = mdfld_panel_dpi(dev);
- config->lane_count = 2;
- config->channel_num = 0;
- /*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/
- if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
- config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE;
- } else {
- config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE;
- }
-
- return 0;
-}
-
-/*
- * Returns the panel fixed mode from configuration.
- */
-struct drm_display_mode *
-mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe)
-{
- struct drm_device *dev = dsi_config->dev;
- struct drm_display_mode *mode;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
- bool use_gct = false;
-
- mode = kzalloc(sizeof(*mode), GFP_KERNEL);
- if (!mode) {
- dev_err(dev->dev, "Out of memory for mode\n");
- return NULL;
- }
- if (use_gct) {
- dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
- mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
- mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
- mode->hsync_start = mode->hdisplay + \
- ((ti->hsync_offset_hi << 8) | \
- ti->hsync_offset_lo);
- mode->hsync_end = mode->hsync_start + \
- ((ti->hsync_pulse_width_hi << 8) | \
- ti->hsync_pulse_width_lo);
- mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
- ti->hblank_lo);
- mode->vsync_start = \
- mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
- ti->vsync_offset_lo);
- mode->vsync_end = \
- mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
- ti->vsync_pulse_width_lo);
- mode->vtotal = mode->vdisplay + \
- ((ti->vblank_hi << 8) | ti->vblank_lo);
- mode->clock = ti->pixel_clock * 10;
- } else {
- if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
- if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
- mode->hdisplay = 480;
- mode->vdisplay = 854;
- mode->hsync_start = 487;
- mode->hsync_end = 490;
- mode->htotal = 499;
- mode->vsync_start = 861;
- mode->vsync_end = 865;
- mode->vtotal = 873;
- mode->clock = 33264;
- } else {
- mode->hdisplay = 864;
- mode->vdisplay = 480;
- mode->hsync_start = 873;
- mode->hsync_end = 876;
- mode->htotal = 887;
- mode->vsync_start = 487;
- mode->vsync_end = 490;
- mode->vtotal = 499;
- mode->clock = 33264;
- }
- } else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
- mode->hdisplay = 864;
- mode->vdisplay = 480;
- mode->hsync_start = 872;
- mode->hsync_end = 876;
- mode->htotal = 884;
- mode->vsync_start = 482;
- mode->vsync_end = 494;
- mode->vtotal = 486;
- mode->clock = 25777;
-
- }
- }
-
- drm_mode_set_name(mode);
- drm_mode_set_crtcinfo(mode, 0);
-
- mode->type |= DRM_MODE_TYPE_PREFERRED;
-
- return mode;
-}
-
-int mdfld_dsi_panel_reset(int pipe)
-{
- unsigned gpio;
- int ret = 0;
-
- switch (pipe) {
- case 0:
- gpio = 128;
- break;
- case 2:
- gpio = 34;
- break;
- default:
- DRM_ERROR("Invalid output\n");
- return -EINVAL;
- }
-
- ret = gpio_request(gpio, "gfx");
- if (ret) {
- DRM_ERROR("gpio_rqueset failed\n");
- return ret;
- }
-
- ret = gpio_direction_output(gpio, 1);
- if (ret) {
- DRM_ERROR("gpio_direction_output failed\n");
- goto gpio_error;
- }
-
- gpio_get_value(128);
-
-gpio_error:
- if (gpio_is_valid(gpio))
- gpio_free(gpio);
-
- return ret;
-}
-
-/*
- * MIPI output init
- * @dev drm device
- * @pipe pipe number. 0 or 2
- * @config
- *
- * Do the initialization of a MIPI output, including create DRM mode objects
- * initialization of DSI output on @pipe
- */
-void mdfld_dsi_output_init(struct drm_device *dev,
- int pipe,
- struct mdfld_dsi_config *config,
- struct panel_funcs* p_cmd_funcs,
- struct panel_funcs* p_vid_funcs)
-{
- struct mdfld_dsi_config * dsi_config;
- struct mdfld_dsi_connector * dsi_connector;
- struct psb_intel_output * psb_output;
- struct drm_connector * connector;
- struct mdfld_dsi_encoder * encoder;
- struct drm_psb_private * dev_priv = dev->dev_private;
- struct panel_info dsi_panel_info;
- u32 width_mm, height_mm;
-
- dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe);
-
- if(!dev || ((pipe != 0) && (pipe != 2))) {
- WARN_ON(1);
- return;
- }
-
- /*create a new connetor*/
- dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL);
- if(!dsi_connector) {
- DRM_ERROR("No memory");
- return;
- }
-
- dsi_connector->pipe = pipe;
-
- /*set DSI config*/
- if(config) {
- dsi_config = config;
- } else {
- dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL);
- if(!dsi_config) {
- dev_err(dev->dev,
- "cannot allocate memory for DSI config\n");
- goto dsi_init_err0;
- }
-
- mdfld_dsi_get_default_config(dev, dsi_config, pipe);
- }
-
- dsi_connector->private = dsi_config;
-
- dsi_config->changed = 1;
- dsi_config->dev = dev;
-
- /* Init fixed mode basing on DSI config type */
- if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
- dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev);
- if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
- goto dsi_init_err0;
- } else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
- dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev);
- if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
- goto dsi_init_err0;
- }
-
- width_mm = dsi_panel_info.width_mm;
- height_mm = dsi_panel_info.height_mm;
-
- dsi_config->mode = dsi_config->fixed_mode;
- dsi_config->connector = dsi_connector;
-
- if(!dsi_config->fixed_mode) {
- dev_err(dev->dev, "No pannel fixed mode was found\n");
- goto dsi_init_err0;
- }
-
- if(pipe && dev_priv->dsi_configs[0]) {
- dsi_config->dvr_ic_inited = 0;
- dev_priv->dsi_configs[1] = dsi_config;
- } else if(pipe == 0) {
- dsi_config->dvr_ic_inited = 1;
- dev_priv->dsi_configs[0] = dsi_config;
- } else {
- dev_err(dev->dev, "Trying to init MIPI1 before MIPI0\n");
- goto dsi_init_err0;
- }
-
- /*init drm connector object*/
- psb_output = &dsi_connector->base;
-
- psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2;
-
- connector = &psb_output->base;
- /* Revisit type if MIPI/HDMI bridges ever appear on Medfield */
- drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs,
- DRM_MODE_CONNECTOR_LVDS);
- drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs);
-
- connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- connector->display_info.width_mm = width_mm;
- connector->display_info.height_mm = height_mm;
- connector->interlace_allowed = false;
- connector->doublescan_allowed = false;
-
- /* Attach properties */
- drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
- drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
-
- /* Init DSI package sender on this output */
- if (mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) {
- DRM_ERROR("Package Sender initialization failed on pipe %d\n", pipe);
- goto dsi_init_err0;
- }
-
- /* Init DBI & DPI encoders */
- if (p_cmd_funcs) {
- encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs);
- if(!encoder) {
- dev_err(dev->dev, "Create DBI encoder failed\n");
- goto dsi_init_err1;
- }
- encoder->private = dsi_config;
- dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
- }
-
- if(p_vid_funcs) {
- encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs);
- if(!encoder) {
- dev_err(dev->dev, "Create DPI encoder failed\n");
- goto dsi_init_err1;
- }
- encoder->private = dsi_config;
- dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
- }
-
- drm_sysfs_connector_add(connector);
- return;
-
- /*TODO: add code to destroy outputs on error*/
-dsi_init_err1:
- /*destroy sender*/
- mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender);
-
- drm_connector_cleanup(connector);
- kfree(dsi_config->fixed_mode);
- kfree(dsi_config);
-dsi_init_err0:
- kfree(dsi_connector);
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_output.h b/drivers/staging/gma500/mdfld_dsi_output.h
deleted file mode 100644
index 4699267efd60..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_output.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#ifndef __MDFLD_DSI_OUTPUT_H__
-#define __MDFLD_DSI_OUTPUT_H__
-
-#include
-#include
-#include
-#include
-#include
-
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include "mdfld_output.h"
-
-#include
-
-
-static inline struct mdfld_dsi_config *
- mdfld_dsi_get_config(struct mdfld_dsi_connector *connector)
-{
- if (!connector)
- return NULL;
- return (struct mdfld_dsi_config *)connector->private;
-}
-
-static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config)
-{
- struct mdfld_dsi_connector *dsi_connector;
-
- if (!config)
- return NULL;
-
- dsi_connector = config->connector;
-
- if (!dsi_connector)
- return NULL;
-
- return dsi_connector->pkg_sender;
-}
-
-static inline struct mdfld_dsi_config *
- mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder)
-{
- if (!encoder)
- return NULL;
- return (struct mdfld_dsi_config *)encoder->private;
-}
-
-static inline struct mdfld_dsi_connector *
- mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder)
-{
- struct mdfld_dsi_config *config;
-
- if (!encoder)
- return NULL;
-
- config = mdfld_dsi_encoder_get_config(encoder);
- if (!config)
- return NULL;
-
- return config->connector;
-}
-
-static inline void *mdfld_dsi_encoder_get_pkg_sender(
- struct mdfld_dsi_encoder *encoder)
-{
- struct mdfld_dsi_config *dsi_config;
-
- dsi_config = mdfld_dsi_encoder_get_config(encoder);
- if (!dsi_config)
- return NULL;
-
- return mdfld_dsi_get_pkg_sender(dsi_config);
-}
-
-static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder)
-{
- struct mdfld_dsi_connector *connector;
-
- if (!encoder)
- return -1;
-
- connector = mdfld_dsi_encoder_get_connector(encoder);
- if (!connector)
- return -1;
-
- return connector->pipe;
-}
-
-extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev,
- u32 gen_fifo_stat_reg, u32 fifo_stat);
-extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config,
- int pipe);
-extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe,
- int level);
-extern void mdfld_dsi_output_init(struct drm_device *dev, int pipe,
- struct mdfld_dsi_config *config,
- struct panel_funcs *p_cmd_funcs,
- struct panel_funcs *p_vid_funcs);
-extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config,
- int pipe);
-extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,
- u32 *mode,
- u8 transmission);
-extern int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config,
- u32 *result,
- u8 transmission);
-extern int mdfld_dsi_panel_reset(int pipe);
-
-#endif /*__MDFLD_DSI_OUTPUT_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.c b/drivers/staging/gma500/mdfld_dsi_pkg_sender.c
deleted file mode 100644
index 9b96a5c9abcd..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_pkg_sender.c
+++ /dev/null
@@ -1,1484 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jackie Li
- */
-
-#include
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_dsi_pkg_sender.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-
-#define MDFLD_DSI_DBI_FIFO_TIMEOUT 100
-#define MDFLD_DSI_MAX_RETURN_PACKET_SIZE 512
-#define MDFLD_DSI_READ_MAX_COUNT 5000
-
-static const char * const dsi_errors[] = {
- "RX SOT Error",
- "RX SOT Sync Error",
- "RX EOT Sync Error",
- "RX Escape Mode Entry Error",
- "RX LP TX Sync Error",
- "RX HS Receive Timeout Error",
- "RX False Control Error",
- "RX ECC Single Bit Error",
- "RX ECC Multibit Error",
- "RX Checksum Error",
- "RX DSI Data Type Not Recognised",
- "RX DSI VC ID Invalid",
- "TX False Control Error",
- "TX ECC Single Bit Error",
- "TX ECC Multibit Error",
- "TX Checksum Error",
- "TX DSI Data Type Not Recognised",
- "TX DSI VC ID invalid",
- "High Contention",
- "Low contention",
- "DPI FIFO Under run",
- "HS TX Timeout",
- "LP RX Timeout",
- "Turn Around ACK Timeout",
- "ACK With No Error",
- "RX Invalid TX Length",
- "RX Prot Violation",
- "HS Generic Write FIFO Full",
- "LP Generic Write FIFO Full",
- "Generic Read Data Avail",
- "Special Packet Sent",
- "Tearing Effect",
-};
-
-static int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
- u32 mask)
-{
- struct drm_device *dev = sender->dev;
- u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
- int retry = 0xffff;
-
- while (retry--) {
- if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
- return 0;
- udelay(100);
- }
- dev_err(dev->dev, "fifo is NOT empty 0x%08x\n",
- REG_READ(gen_fifo_stat_reg));
- return -EIO;
-}
-
-static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
- return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 10) | (1 << 18)
- | (1 << 26) | (1 << 27) | (1 << 28));
-}
-
-static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
- return wait_for_gen_fifo_empty(sender, (1 << 10) | (1 << 26));
-}
-
-static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
- return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 18));
-}
-
-static int wait_for_dbi_fifo_empty(struct mdfld_dsi_pkg_sender *sender)
-{
- return wait_for_gen_fifo_empty(sender, (1 << 27));
-}
-
-static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
-{
- u32 intr_stat_reg = sender->mipi_intr_stat_reg;
- struct drm_device *dev = sender->dev;
-
- switch (mask) {
- case (1 << 0):
- case (1 << 1):
- case (1 << 2):
- case (1 << 3):
- case (1 << 4):
- case (1 << 5):
- case (1 << 6):
- case (1 << 7):
- case (1 << 8):
- case (1 << 9):
- case (1 << 10):
- case (1 << 11):
- case (1 << 12):
- case (1 << 13):
- break;
- case (1 << 14):
- /*wait for all fifo empty*/
- /*wait_for_all_fifos_empty(sender)*/;
- break;
- case (1 << 15):
- break;
- case (1 << 16):
- break;
- case (1 << 17):
- break;
- case (1 << 18):
- case (1 << 19):
- /*wait for contention recovery time*/
- /*mdelay(10);*/
- /*wait for all fifo empty*/
- if (0)
- wait_for_all_fifos_empty(sender);
- break;
- case (1 << 20):
- break;
- case (1 << 21):
- /*wait for all fifo empty*/
- /*wait_for_all_fifos_empty(sender);*/
- break;
- case (1 << 22):
- break;
- case (1 << 23):
- case (1 << 24):
- case (1 << 25):
- case (1 << 26):
- case (1 << 27):
- /* HS Gen fifo full */
- REG_WRITE(intr_stat_reg, mask);
- wait_for_hs_fifos_empty(sender);
- break;
- case (1 << 28):
- /* LP Gen fifo full\n */
- REG_WRITE(intr_stat_reg, mask);
- wait_for_lp_fifos_empty(sender);
- break;
- case (1 << 29):
- case (1 << 30):
- case (1 << 31):
- break;
- }
-
- if (mask & REG_READ(intr_stat_reg))
- dev_warn(dev->dev, "Cannot clean interrupt 0x%08x\n", mask);
-
- return 0;
-}
-
-static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
-{
- struct drm_device *dev = sender->dev;
- u32 intr_stat_reg = sender->mipi_intr_stat_reg;
- u32 mask;
- u32 intr_stat;
- int i;
- int err = 0;
-
- intr_stat = REG_READ(intr_stat_reg);
-
- for (i = 0; i < 32; i++) {
- mask = (0x00000001UL) << i;
- if (intr_stat & mask) {
- dev_dbg(dev->dev, "[DSI]: %s\n", dsi_errors[i]);
- err = handle_dsi_error(sender, mask);
- if (err)
- dev_err(dev->dev, "Cannot handle error\n");
- }
- }
- return err;
-}
-
-static inline int dbi_cmd_sent(struct mdfld_dsi_pkg_sender *sender)
-{
- struct drm_device *dev = sender->dev;
- u32 retry = 0xffff;
- u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
-
- /* Query the command execution status */
- while (retry--) {
- if (!(REG_READ(dbi_cmd_addr_reg) & (1 << 0)))
- break;
- }
-
- if (!retry) {
- dev_err(dev->dev, "Timeout waiting for DBI Command status\n");
- return -EAGAIN;
- }
- return 0;
-}
-
-/*
- * NOTE: this interface is abandoned expect for write_mem_start DCS
- * other DCS are sent via generic pkg interfaces
- */
-static int send_dcs_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- struct drm_device *dev = sender->dev;
- struct mdfld_dsi_dcs_pkg *dcs_pkg = &pkg->pkg.dcs_pkg;
- u32 dbi_cmd_len_reg = sender->mipi_cmd_len_reg;
- u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
- u32 cb_phy = sender->dbi_cb_phy;
- u32 index = 0;
- u8 *cb = (u8 *)sender->dbi_cb_addr;
- int i;
- int ret;
-
- if (!sender->dbi_pkg_support) {
- dev_err(dev->dev, "Trying to send DCS on a non DBI output, abort!\n");
- return -ENOTSUPP;
- }
-
- /*wait for DBI fifo empty*/
- wait_for_dbi_fifo_empty(sender);
-
- *(cb + (index++)) = dcs_pkg->cmd;
- if (dcs_pkg->param_num) {
- for (i = 0; i < dcs_pkg->param_num; i++)
- *(cb + (index++)) = *(dcs_pkg->param + i);
- }
-
- REG_WRITE(dbi_cmd_len_reg, (1 + dcs_pkg->param_num));
- REG_WRITE(dbi_cmd_addr_reg,
- (cb_phy << CMD_MEM_ADDR_OFFSET)
- | (1 << 0)
- | ((dcs_pkg->data_src == CMD_DATA_SRC_PIPE) ? (1 << 1) : 0));
-
- ret = dbi_cmd_sent(sender);
- if (ret) {
- dev_err(dev->dev, "command 0x%x not complete\n", dcs_pkg->cmd);
- return -EAGAIN;
- }
- return 0;
-}
-
-static int __send_short_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- struct drm_device *dev = sender->dev;
- u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
- u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
- u32 gen_ctrl_val = 0;
- struct mdfld_dsi_gen_short_pkg *short_pkg = &pkg->pkg.short_pkg;
-
- gen_ctrl_val |= short_pkg->cmd << MCS_COMMANDS_POS;
- gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
- gen_ctrl_val |= pkg->pkg_type;
- gen_ctrl_val |= short_pkg->param << MCS_PARAMETER_POS;
-
- if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
- /* wait for hs fifo empty */
- /* wait_for_hs_fifos_empty(sender); */
- /* Send pkg */
- REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
- } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
- /* wait_for_lp_fifos_empty(sender); */
- /* Send pkg*/
- REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
- } else {
- dev_err(dev->dev, "Unknown transmission type %d\n",
- pkg->transmission_type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int __send_long_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- struct drm_device *dev = sender->dev;
- u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
- u32 hs_gen_data_reg = sender->mipi_hs_gen_data_reg;
- u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
- u32 lp_gen_data_reg = sender->mipi_lp_gen_data_reg;
- u32 gen_ctrl_val = 0;
- u32 *dp;
- int i;
- struct mdfld_dsi_gen_long_pkg *long_pkg = &pkg->pkg.long_pkg;
-
- dp = long_pkg->data;
-
- /*
- * Set up word count for long pkg
- * FIXME: double check word count field.
- * currently, using the byte counts of the payload as the word count.
- * ------------------------------------------------------------
- * | DI | WC | ECC| PAYLOAD |CHECKSUM|
- * ------------------------------------------------------------
- */
- gen_ctrl_val |= (long_pkg->len << 2) << WORD_COUNTS_POS;
- gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
- gen_ctrl_val |= pkg->pkg_type;
-
- if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
- /* Wait for hs ctrl and data fifos to be empty */
- /* wait_for_hs_fifos_empty(sender); */
- for (i = 0; i < long_pkg->len; i++)
- REG_WRITE(hs_gen_data_reg, *(dp + i));
- REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
- } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
- /* wait_for_lp_fifos_empty(sender); */
- for (i = 0; i < long_pkg->len; i++)
- REG_WRITE(lp_gen_data_reg, *(dp + i));
- REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
- } else {
- dev_err(dev->dev, "Unknown transmission type %d\n",
- pkg->transmission_type);
- return -EINVAL;
- }
-
- return 0;
-
-}
-
-static int send_mcs_short_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- return __send_short_pkg(sender, pkg);
-}
-
-static int send_mcs_long_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- return __send_long_pkg(sender, pkg);
-}
-
-static int send_gen_short_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- return __send_short_pkg(sender, pkg);
-}
-
-static int send_gen_long_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- return __send_long_pkg(sender, pkg);
-}
-
-static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- u8 cmd;
- u8 *data;
-
- switch (pkg->pkg_type) {
- case MDFLD_DSI_PKG_DCS:
- cmd = pkg->pkg.dcs_pkg.cmd;
- break;
- case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
- case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
- cmd = pkg->pkg.short_pkg.cmd;
- break;
- case MDFLD_DSI_PKG_MCS_LONG_WRITE:
- data = (u8 *)pkg->pkg.long_pkg.data;
- cmd = *data;
- break;
- default:
- return 0;
- }
-
- /* This prevents other package sending while doing msleep */
- sender->status = MDFLD_DSI_PKG_SENDER_BUSY;
-
- /* Check panel mode v.s. sending command */
- if ((sender->panel_mode & MDFLD_DSI_PANEL_MODE_SLEEP) &&
- cmd != exit_sleep_mode) {
- dev_err(sender->dev->dev,
- "sending 0x%x when panel sleep in\n", cmd);
- sender->status = MDFLD_DSI_PKG_SENDER_FREE;
- return -EINVAL;
- }
-
- /* Wait for 120 milliseconds in case exit_sleep_mode just be sent */
- if (cmd == DCS_ENTER_SLEEP_MODE) {
- /*TODO: replace it with msleep later*/
- mdelay(120);
- }
- return 0;
-}
-
-static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- u8 cmd;
- u8 *data;
-
- switch (pkg->pkg_type) {
- case MDFLD_DSI_PKG_DCS:
- cmd = pkg->pkg.dcs_pkg.cmd;
- break;
- case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
- case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
- cmd = pkg->pkg.short_pkg.cmd;
- break;
- case MDFLD_DSI_PKG_MCS_LONG_WRITE:
- data = (u8 *)pkg->pkg.long_pkg.data;
- cmd = *data;
- break;
- default:
- return 0;
- }
-
- /* Update panel status */
- if (cmd == DCS_ENTER_SLEEP_MODE) {
- sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
- /*TODO: replace it with msleep later*/
- mdelay(120);
- } else if (cmd == DCS_EXIT_SLEEP_MODE) {
- sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
- /*TODO: replace it with msleep later*/
- mdelay(120);
- } else if (unlikely(cmd == DCS_SOFT_RESET)) {
- /*TODO: replace it with msleep later*/
- mdelay(5);
- }
- sender->status = MDFLD_DSI_PKG_SENDER_FREE;
- return 0;
-
-}
-
-static int do_send_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- int ret;
-
- if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
- dev_err(sender->dev->dev, "sender is busy\n");
- return -EAGAIN;
- }
-
- ret = send_pkg_prepare(sender, pkg);
- if (ret) {
- dev_err(sender->dev->dev, "send_pkg_prepare error\n");
- return ret;
- }
-
- switch (pkg->pkg_type) {
- case MDFLD_DSI_PKG_DCS:
- ret = send_dcs_pkg(sender, pkg);
- break;
- case MDFLD_DSI_PKG_GEN_SHORT_WRITE_0:
- case MDFLD_DSI_PKG_GEN_SHORT_WRITE_1:
- case MDFLD_DSI_PKG_GEN_SHORT_WRITE_2:
- case MDFLD_DSI_PKG_GEN_READ_0:
- case MDFLD_DSI_PKG_GEN_READ_1:
- case MDFLD_DSI_PKG_GEN_READ_2:
- ret = send_gen_short_pkg(sender, pkg);
- break;
- case MDFLD_DSI_PKG_GEN_LONG_WRITE:
- ret = send_gen_long_pkg(sender, pkg);
- break;
- case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
- case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
- case MDFLD_DSI_PKG_MCS_READ:
- ret = send_mcs_short_pkg(sender, pkg);
- break;
- case MDFLD_DSI_PKG_MCS_LONG_WRITE:
- ret = send_mcs_long_pkg(sender, pkg);
- break;
- default:
- dev_err(sender->dev->dev, "Invalid pkg type 0x%x\n",
- pkg->pkg_type);
- ret = -EINVAL;
- }
- send_pkg_done(sender, pkg);
- return ret;
-}
-
-static int send_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- int err ;
-
- /* Handle DSI error */
- err = dsi_error_handler(sender);
- if (err) {
- dev_err(sender->dev->dev, "Error handling failed\n");
- err = -EAGAIN;
- goto send_pkg_err;
- }
-
- /* Send pkg */
- err = do_send_pkg(sender, pkg);
- if (err) {
- dev_err(sender->dev->dev, "sent pkg failed\n");
- err = -EAGAIN;
- goto send_pkg_err;
- }
-
- /* FIXME: should I query complete and fifo empty here? */
-send_pkg_err:
- return err;
-}
-
-static struct mdfld_dsi_pkg *pkg_sender_get_pkg_locked(
- struct mdfld_dsi_pkg_sender *sender)
-{
- struct mdfld_dsi_pkg *pkg;
-
- if (list_empty(&sender->free_list)) {
- dev_err(sender->dev->dev, "No free pkg left\n");
- return NULL;
- }
- pkg = list_first_entry(&sender->free_list, struct mdfld_dsi_pkg, entry);
- /* Detach from free list */
- list_del_init(&pkg->entry);
- return pkg;
-}
-
-static void pkg_sender_put_pkg_locked(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg)
-{
- memset(pkg, 0, sizeof(struct mdfld_dsi_pkg));
- INIT_LIST_HEAD(&pkg->entry);
- list_add_tail(&pkg->entry, &sender->free_list);
-}
-
-static int mdfld_dbi_cb_init(struct mdfld_dsi_pkg_sender *sender,
- struct psb_gtt *pg, int pipe)
-{
- unsigned long phys;
- void *virt_addr = NULL;
-
- switch (pipe) {
- case 0:
- /* FIXME: Doesn't this collide with stolen space ? */
- phys = pg->gtt_phys_start - 0x1000;
- break;
- case 2:
- phys = pg->gtt_phys_start - 0x800;
- break;
- default:
- dev_err(sender->dev->dev, "Unsupported channel %d\n", pipe);
- return -EINVAL;
- }
-
- virt_addr = ioremap_nocache(phys, 0x800);
- if (!virt_addr) {
- dev_err(sender->dev->dev, "Map DBI command buffer error\n");
- return -ENOMEM;
- }
- sender->dbi_cb_phy = phys;
- sender->dbi_cb_addr = virt_addr;
- return 0;
-}
-
-static void mdfld_dbi_cb_destroy(struct mdfld_dsi_pkg_sender *sender)
-{
- if (sender && sender->dbi_cb_addr)
- iounmap(sender->dbi_cb_addr);
-}
-
-static void pkg_sender_queue_pkg(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg,
- int delay)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
-
- if (!delay) {
- send_pkg(sender, pkg);
- pkg_sender_put_pkg_locked(sender, pkg);
- } else {
- /* Queue it */
- list_add_tail(&pkg->entry, &sender->pkg_list);
- }
- spin_unlock_irqrestore(&sender->lock, flags);
-}
-
-static void process_pkg_list(struct mdfld_dsi_pkg_sender *sender)
-{
- struct mdfld_dsi_pkg *pkg;
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
-
- while (!list_empty(&sender->pkg_list)) {
- pkg = list_first_entry(&sender->pkg_list,
- struct mdfld_dsi_pkg, entry);
- send_pkg(sender, pkg);
- list_del_init(&pkg->entry);
- pkg_sender_put_pkg_locked(sender, pkg);
- }
-
- spin_unlock_irqrestore(&sender->lock, flags);
-}
-
-static int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender,
- u32 *data, u32 len, u8 transmission, int delay)
-{
- struct mdfld_dsi_pkg *pkg;
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
- pkg = pkg_sender_get_pkg_locked(sender);
- spin_unlock_irqrestore(&sender->lock, flags);
-
- if (!pkg) {
- dev_err(sender->dev->dev, "No memory\n");
- return -ENOMEM;
- }
- pkg->pkg_type = MDFLD_DSI_PKG_MCS_LONG_WRITE;
- pkg->transmission_type = transmission;
- pkg->pkg.long_pkg.data = data;
- pkg->pkg.long_pkg.len = len;
- INIT_LIST_HEAD(&pkg->entry);
-
- pkg_sender_queue_pkg(sender, pkg, delay);
- return 0;
-}
-
-static int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd, u8 param, u8 param_num,
- u8 transmission,
- int delay)
-{
- struct mdfld_dsi_pkg *pkg;
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
- pkg = pkg_sender_get_pkg_locked(sender);
- spin_unlock_irqrestore(&sender->lock, flags);
-
- if (!pkg) {
- dev_err(sender->dev->dev, "No memory\n");
- return -ENOMEM;
- }
-
- if (param_num) {
- pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_1;
- pkg->pkg.short_pkg.param = param;
- } else {
- pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_0;
- pkg->pkg.short_pkg.param = 0;
- }
- pkg->transmission_type = transmission;
- pkg->pkg.short_pkg.cmd = cmd;
- INIT_LIST_HEAD(&pkg->entry);
-
- pkg_sender_queue_pkg(sender, pkg, delay);
- return 0;
-}
-
-static int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender,
- u8 param0, u8 param1, u8 param_num,
- u8 transmission,
- int delay)
-{
- struct mdfld_dsi_pkg *pkg;
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
- pkg = pkg_sender_get_pkg_locked(sender);
- spin_unlock_irqrestore(&sender->lock, flags);
-
- if (!pkg) {
- dev_err(sender->dev->dev, "No pkg memory\n");
- return -ENOMEM;
- }
-
- switch (param_num) {
- case 0:
- pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_0;
- pkg->pkg.short_pkg.cmd = 0;
- pkg->pkg.short_pkg.param = 0;
- break;
- case 1:
- pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_1;
- pkg->pkg.short_pkg.cmd = param0;
- pkg->pkg.short_pkg.param = 0;
- break;
- case 2:
- pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_2;
- pkg->pkg.short_pkg.cmd = param0;
- pkg->pkg.short_pkg.param = param1;
- break;
- }
-
- pkg->transmission_type = transmission;
- INIT_LIST_HEAD(&pkg->entry);
-
- pkg_sender_queue_pkg(sender, pkg, delay);
- return 0;
-}
-
-static int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender,
- u32 *data, u32 len, u8 transmission, int delay)
-{
- struct mdfld_dsi_pkg *pkg;
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
- pkg = pkg_sender_get_pkg_locked(sender);
- spin_unlock_irqrestore(&sender->lock, flags);
-
- if (!pkg) {
- dev_err(sender->dev->dev, "No pkg memory\n");
- return -ENOMEM;
- }
-
- pkg->pkg_type = MDFLD_DSI_PKG_GEN_LONG_WRITE;
- pkg->transmission_type = transmission;
- pkg->pkg.long_pkg.data = data;
- pkg->pkg.long_pkg.len = len;
-
- INIT_LIST_HEAD(&pkg->entry);
-
- pkg_sender_queue_pkg(sender, pkg, delay);
-
- return 0;
-}
-
-static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender,
- struct mdfld_dsi_pkg *pkg,
- u32 *data,
- u16 len)
-{
- unsigned long flags;
- struct drm_device *dev = sender->dev;
- int i;
- u32 gen_data_reg;
- int retry = MDFLD_DSI_READ_MAX_COUNT;
- u8 transmission = pkg->transmission_type;
-
- /*
- * do reading.
- * 0) send out generic read request
- * 1) polling read data avail interrupt
- * 2) read data
- */
- spin_lock_irqsave(&sender->lock, flags);
-
- REG_WRITE(sender->mipi_intr_stat_reg, 1 << 29);
-
- if ((REG_READ(sender->mipi_intr_stat_reg) & (1 << 29)))
- DRM_ERROR("Can NOT clean read data valid interrupt\n");
-
- /*send out read request*/
- send_pkg(sender, pkg);
-
- pkg_sender_put_pkg_locked(sender, pkg);
-
- /*polling read data avail interrupt*/
- while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & (1 << 29))) {
- udelay(100);
- retry--;
- }
-
- if (!retry) {
- spin_unlock_irqrestore(&sender->lock, flags);
- return -ETIMEDOUT;
- }
-
- REG_WRITE(sender->mipi_intr_stat_reg, (1 << 29));
-
- /*read data*/
- if (transmission == MDFLD_DSI_HS_TRANSMISSION)
- gen_data_reg = sender->mipi_hs_gen_data_reg;
- else if (transmission == MDFLD_DSI_LP_TRANSMISSION)
- gen_data_reg = sender->mipi_lp_gen_data_reg;
- else {
- DRM_ERROR("Unknown transmission");
- spin_unlock_irqrestore(&sender->lock, flags);
- return -EINVAL;
- }
-
- for (i=0; ilock, flags);
-
- return 0;
-}
-
-static int mdfld_dsi_read_gen(struct mdfld_dsi_pkg_sender *sender,
- u8 param0,
- u8 param1,
- u8 param_num,
- u32 *data,
- u16 len,
- u8 transmission)
-{
- struct mdfld_dsi_pkg *pkg;
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
-
- pkg = pkg_sender_get_pkg_locked(sender);
-
- spin_unlock_irqrestore(&sender->lock,flags);
-
- if (!pkg) {
- dev_err(sender->dev->dev, "No pkg memory\n");
- return -ENOMEM;
- }
-
- switch (param_num) {
- case 0:
- pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_0;
- pkg->pkg.short_pkg.cmd = 0;
- pkg->pkg.short_pkg.param = 0;
- break;
- case 1:
- pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_1;
- pkg->pkg.short_pkg.cmd = param0;
- pkg->pkg.short_pkg.param = 0;
- break;
- case 2:
- pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_2;
- pkg->pkg.short_pkg.cmd = param0;
- pkg->pkg.short_pkg.param = param1;
- break;
- }
-
- pkg->transmission_type = transmission;
-
- INIT_LIST_HEAD(&pkg->entry);
-
- return __read_panel_data(sender, pkg, data, len);
-}
-
-static int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd,
- u32 *data,
- u16 len,
- u8 transmission)
-{
- struct mdfld_dsi_pkg *pkg;
- unsigned long flags;
-
- spin_lock_irqsave(&sender->lock, flags);
-
- pkg = pkg_sender_get_pkg_locked(sender);
-
- spin_unlock_irqrestore(&sender->lock, flags);
-
- if (!pkg) {
- dev_err(sender->dev->dev, "No pkg memory\n");
- return -ENOMEM;
- }
-
- pkg->pkg_type = MDFLD_DSI_PKG_MCS_READ;
- pkg->pkg.short_pkg.cmd = cmd;
- pkg->pkg.short_pkg.param = 0;
-
- pkg->transmission_type = transmission;
-
- INIT_LIST_HEAD(&pkg->entry);
-
- return __read_panel_data(sender, pkg, data, len);
-}
-
-void dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
- struct drm_device * dev = dsi_config->dev;
- u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- int lane_count = dsi_config->lane_count;
- u32 val = 0;
-
- /*un-ready device*/
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
- /*init dsi adapter before kicking off*/
- REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
- /*TODO: figure out how to setup these registers*/
- REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
- REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), 0x000a0014);
- REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
- REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
- REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
- /*enable all interrupts*/
- REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
- /*max value: 20 clock cycles of txclkesc*/
- REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
- /*min 21 txclkesc, max: ffffh*/
- REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
- /*min: 7d0 max: 4e20*/
- REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
- /*set up max return packet size*/
- REG_WRITE((MIPIA_MAX_RETURN_PACK_SIZE_REG + reg_offset),
- MDFLD_DSI_MAX_RETURN_PACKET_SIZE);
-
- /*set up func_prg*/
- val |= lane_count;
- val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
- val |= DSI_DBI_COLOR_FORMAT_OPTION2;
- REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
- REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
- REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
- REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
- REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
- REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-void dsi_controller_dpi_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
- struct drm_device * dev = dsi_config->dev;
- u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- int lane_count = dsi_config->lane_count;
- struct mdfld_dsi_dpi_timing dpi_timing;
- struct drm_display_mode * mode = dsi_config->mode;
- u32 val = 0;
-
- /*un-ready device*/
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
- /*init dsi adapter before kicking off*/
- REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
- /*enable all interrupts*/
- REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-
- /*set up func_prg*/
- val |= lane_count;
- val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
-
- switch(dsi_config->bpp) {
- case 16:
- val |= DSI_DPI_COLOR_FORMAT_RGB565;
- break;
- case 18:
- val |= DSI_DPI_COLOR_FORMAT_RGB666;
- break;
- case 24:
- val |= DSI_DPI_COLOR_FORMAT_RGB888;
- break;
- default:
- DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
- }
-
- REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
- REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset),
- (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
- REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
-
- /*max value: 20 clock cycles of txclkesc*/
- REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
-
- /*min 21 txclkesc, max: ffffh*/
- REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
-
- REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
-
- /*set DPI timing registers*/
- mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
-
- REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
- REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
-
- REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-
- /*min: 7d0 max: 4e20*/
- REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
-
- /*set up video mode*/
- val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
- REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
-
- REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-
- REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-
- /*TODO: figure out how to setup these registers*/
- REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-
- REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
-
- /*set device ready*/
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-static void dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
- if (!dsi_config || ((pipe != 0) && (pipe != 2))) {
- DRM_ERROR("Invalid parameters\n");
- return;
- }
-
- if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
- dsi_controller_dpi_init(dsi_config, pipe);
- else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI)
- dsi_controller_dbi_init(dsi_config, pipe);
- else
- DRM_ERROR("Bad DSI encoder type\n");
-}
-
-void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender)
-{
- process_pkg_list(sender);
-}
-
-int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender,
- u8 dcs, u8 *param, u32 param_num, u8 data_src,
- int delay)
-{
- struct mdfld_dsi_pkg *pkg;
- u32 cb_phy = sender->dbi_cb_phy;
- struct drm_device *dev = sender->dev;
- u32 index = 0;
- u8 *cb = (u8 *)sender->dbi_cb_addr;
- unsigned long flags;
- int retry;
- u8 *dst = NULL;
- u32 len;
-
- if (!sender) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- if (!sender->dbi_pkg_support) {
- dev_err(dev->dev, "No DBI pkg sending on this sender\n");
- return -ENOTSUPP;
- }
-
- if (param_num > MDFLD_MAX_DCS_PARAM) {
- dev_err(dev->dev, "Sender only supports up to %d DCS params\n",
- MDFLD_MAX_DCS_PARAM);
- return -EINVAL;
- }
-
- /*
- * If dcs is write_mem_start, send it directly using DSI adapter
- * interface
- */
- if (dcs == DCS_WRITE_MEM_START) {
- if (!spin_trylock(&sender->lock))
- return -EAGAIN;
-
- /*
- * query whether DBI FIFO is empty,
- * if not wait it becoming empty
- */
- retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
- while (retry &&
- !(REG_READ(sender->mipi_gen_fifo_stat_reg) & (1 << 27))) {
- udelay(500);
- retry--;
- }
-
- /* If DBI FIFO timeout, drop this frame */
- if (!retry) {
- spin_unlock(&sender->lock);
- return 0;
- }
-
- *(cb + (index++)) = write_mem_start;
-
- REG_WRITE(sender->mipi_cmd_len_reg, 1);
- REG_WRITE(sender->mipi_cmd_addr_reg,
- cb_phy | (1 << 0) | (1 << 1));
-
- retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
- while (retry &&
- (REG_READ(sender->mipi_cmd_addr_reg) & (1 << 0))) {
- udelay(1);
- retry--;
- }
-
- spin_unlock(&sender->lock);
- return 0;
- }
-
- /* Get a free pkg */
- spin_lock_irqsave(&sender->lock, flags);
- pkg = pkg_sender_get_pkg_locked(sender);
- spin_unlock_irqrestore(&sender->lock, flags);
-
- if (!pkg) {
- dev_err(dev->dev, "No packages memory\n");
- return -ENOMEM;
- }
-
- dst = pkg->pkg.dcs_pkg.param;
- memcpy(dst, param, param_num);
-
- pkg->pkg_type = MDFLD_DSI_PKG_DCS;
- pkg->transmission_type = MDFLD_DSI_DCS;
- pkg->pkg.dcs_pkg.cmd = dcs;
- pkg->pkg.dcs_pkg.param_num = param_num;
- pkg->pkg.dcs_pkg.data_src = data_src;
-
- INIT_LIST_HEAD(&pkg->entry);
-
- if (param_num == 0)
- return mdfld_dsi_send_mcs_short_hs(sender, dcs, 0, 0, delay);
- else if (param_num == 1)
- return mdfld_dsi_send_mcs_short_hs(sender, dcs,
- param[0], 1, delay);
- else if (param_num > 1) {
- len = (param_num + 1) / 4;
- if ((param_num + 1) % 4)
- len++;
- return mdfld_dsi_send_mcs_long_hs(sender,
- (u32 *)&pkg->pkg.dcs_pkg, len, delay);
- }
- return 0;
-}
-
-int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd, u8 param, u8 param_num, int delay)
-{
- if (!sender) {
- WARN_ON(1);
- return -EINVAL;
- }
- return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
- MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd, u8 param, u8 param_num, int delay)
-{
- if (!sender) {
- WARN_ON(1);
- return -EINVAL;
- }
- return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
- MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
- u32 *data,
- u32 len,
- int delay)
-{
- if (!sender || !data || !len) {
- DRM_ERROR("Invalid parameters\n");
- return -EINVAL;
- }
- return mdfld_dsi_send_mcs_long(sender, data, len,
- MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
- u32 *data,
- u32 len,
- int delay)
-{
- if (!sender || !data || !len) {
- WARN_ON(1);
- return -EINVAL;
- }
- return mdfld_dsi_send_mcs_long(sender, data, len,
- MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 param0, u8 param1, u8 param_num, int delay)
-{
- if (!sender) {
- WARN_ON(1);
- return -EINVAL;
- }
- return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
- MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 param0, u8 param1, u8 param_num, int delay)
-{
- if (!sender || param_num < 0 || param_num > 2) {
- WARN_ON(1);
- return -EINVAL;
- }
- return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
- MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
- u32 *data,
- u32 len,
- int delay)
-{
- if (!sender || !data || !len) {
- WARN_ON(1);
- return -EINVAL;
- }
- return mdfld_dsi_send_gen_long(sender, data, len,
- MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
- u32 *data,
- u32 len,
- int delay)
-{
- if (!sender || !data || !len) {
- WARN_ON(1);
- return -EINVAL;
- }
- return mdfld_dsi_send_gen_long(sender, data, len,
- MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 param0,
- u8 param1,
- u8 param_num,
- u32 *data,
- u16 len)
-{
- if (!sender || !data || param_num < 0 || param_num > 2
- || !data || !len) {
- DRM_ERROR("Invalid parameters\n");
- return -EINVAL;
- }
-
- return mdfld_dsi_read_gen(sender, param0, param1, param_num,
- data, len, MDFLD_DSI_HS_TRANSMISSION);
-
-}
-
-int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 param0,
- u8 param1,
- u8 param_num,
- u32 *data,
- u16 len)
-{
- if (!sender || !data || param_num < 0 || param_num > 2
- || !data || !len) {
- DRM_ERROR("Invalid parameters\n");
- return -EINVAL;
- }
-
- return mdfld_dsi_read_gen(sender, param0, param1, param_num,
- data, len, MDFLD_DSI_LP_TRANSMISSION);
-}
-
-int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd,
- u32 *data,
- u16 len)
-{
- if (!sender || !data || !len) {
- DRM_ERROR("Invalid parameters\n");
- return -EINVAL;
- }
-
- return mdfld_dsi_read_mcs(sender, cmd, data, len,
- MDFLD_DSI_HS_TRANSMISSION);
-}
-
-int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd,
- u32 *data,
- u16 len)
-{
- if (!sender || !data || !len) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- return mdfld_dsi_read_mcs(sender, cmd, data, len,
- MDFLD_DSI_LP_TRANSMISSION);
-}
-
-int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
- int pipe)
-{
- int ret;
- struct mdfld_dsi_pkg_sender *pkg_sender;
- struct mdfld_dsi_config *dsi_config =
- mdfld_dsi_get_config(dsi_connector);
- struct drm_device *dev = dsi_config->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_gtt *pg = &dev_priv->gtt;
- int i;
- struct mdfld_dsi_pkg *pkg, *tmp;
- u32 mipi_val = 0;
-
- if (!dsi_connector) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- pkg_sender = dsi_connector->pkg_sender;
-
- if (!pkg_sender || IS_ERR(pkg_sender)) {
- pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
- GFP_KERNEL);
- if (!pkg_sender) {
- dev_err(dev->dev, "Create DSI pkg sender failed\n");
- return -ENOMEM;
- }
-
- dsi_connector->pkg_sender = (void *)pkg_sender;
- }
-
- pkg_sender->dev = dev;
- pkg_sender->dsi_connector = dsi_connector;
- pkg_sender->pipe = pipe;
- pkg_sender->pkg_num = 0;
- pkg_sender->panel_mode = 0;
- pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;
-
- /* Init dbi command buffer*/
-
- if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
- pkg_sender->dbi_pkg_support = 1;
- ret = mdfld_dbi_cb_init(pkg_sender, pg, pipe);
- if (ret) {
- dev_err(dev->dev, "DBI command buffer map failed\n");
- goto mapping_err;
- }
- }
-
- /* Init regs */
- if (pipe == 0) {
- pkg_sender->dpll_reg = MRST_DPLL_A;
- pkg_sender->dspcntr_reg = DSPACNTR;
- pkg_sender->pipeconf_reg = PIPEACONF;
- pkg_sender->dsplinoff_reg = DSPALINOFF;
- pkg_sender->dspsurf_reg = DSPASURF;
- pkg_sender->pipestat_reg = PIPEASTAT;
-
- pkg_sender->mipi_intr_stat_reg = MIPIA_INTR_STAT_REG;
- pkg_sender->mipi_lp_gen_data_reg = MIPIA_LP_GEN_DATA_REG;
- pkg_sender->mipi_hs_gen_data_reg = MIPIA_HS_GEN_DATA_REG;
- pkg_sender->mipi_lp_gen_ctrl_reg = MIPIA_LP_GEN_CTRL_REG;
- pkg_sender->mipi_hs_gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
- pkg_sender->mipi_gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
- pkg_sender->mipi_data_addr_reg = MIPIA_DATA_ADD_REG;
- pkg_sender->mipi_data_len_reg = MIPIA_DATA_LEN_REG;
- pkg_sender->mipi_cmd_addr_reg = MIPIA_CMD_ADD_REG;
- pkg_sender->mipi_cmd_len_reg = MIPIA_CMD_LEN_REG;
- } else if (pipe == 2) {
- pkg_sender->dpll_reg = MRST_DPLL_A;
- pkg_sender->dspcntr_reg = DSPCCNTR;
- pkg_sender->pipeconf_reg = PIPECCONF;
- pkg_sender->dsplinoff_reg = DSPCLINOFF;
- pkg_sender->dspsurf_reg = DSPCSURF;
- pkg_sender->pipestat_reg = PIPECSTAT;
-
- pkg_sender->mipi_intr_stat_reg =
- MIPIA_INTR_STAT_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_lp_gen_data_reg =
- MIPIA_LP_GEN_DATA_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_hs_gen_data_reg =
- MIPIA_HS_GEN_DATA_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_lp_gen_ctrl_reg =
- MIPIA_LP_GEN_CTRL_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_hs_gen_ctrl_reg =
- MIPIA_HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_gen_fifo_stat_reg =
- MIPIA_GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_data_addr_reg =
- MIPIA_DATA_ADD_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_data_len_reg =
- MIPIA_DATA_LEN_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_cmd_addr_reg =
- MIPIA_CMD_ADD_REG + MIPIC_REG_OFFSET;
- pkg_sender->mipi_cmd_len_reg =
- MIPIA_CMD_LEN_REG + MIPIC_REG_OFFSET;
- }
-
- /* Init pkg list */
- INIT_LIST_HEAD(&pkg_sender->pkg_list);
- INIT_LIST_HEAD(&pkg_sender->free_list);
-
- spin_lock_init(&pkg_sender->lock);
-
- /* Allocate free pkg pool */
- for (i = 0; i < MDFLD_MAX_PKG_NUM; i++) {
- pkg = kzalloc(sizeof(struct mdfld_dsi_pkg), GFP_KERNEL);
- if (!pkg) {
- dev_err(dev->dev, "Out of memory allocating pkg pool");
- ret = -ENOMEM;
- goto pkg_alloc_err;
- }
- INIT_LIST_HEAD(&pkg->entry);
- list_add_tail(&pkg->entry, &pkg_sender->free_list);
- }
-
- /*
- * For video mode, don't enable DPI timing output here,
- * will init the DPI timing output during mode setting.
- */
- if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
- mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
- else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI)
- mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX
- | TE_TRIGGER_GPIO_PIN;
- else
- DRM_ERROR("Bad DSI encoder type\n");
-
- if (pipe == 0) {
- mipi_val |= 0x2;
- REG_WRITE(MIPI, mipi_val);
- REG_READ(MIPI);
- } else if (pipe == 2) {
- REG_WRITE(MIPI_C, mipi_val);
- REG_READ(MIPI_C);
- }
-
- /*do dsi controller init*/
- dsi_controller_init(dsi_config, pipe);
-
- return 0;
-
-pkg_alloc_err:
- list_for_each_entry_safe(pkg, tmp, &pkg_sender->free_list, entry) {
- list_del(&pkg->entry);
- kfree(pkg);
- }
-
- /* Free mapped command buffer */
- mdfld_dbi_cb_destroy(pkg_sender);
-mapping_err:
- kfree(pkg_sender);
- dsi_connector->pkg_sender = NULL;
- return ret;
-}
-
-void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
-{
- struct mdfld_dsi_pkg *pkg, *tmp;
-
- if (!sender || IS_ERR(sender))
- return;
-
- /* Free pkg pool */
- list_for_each_entry_safe(pkg, tmp, &sender->free_list, entry) {
- list_del(&pkg->entry);
- kfree(pkg);
- }
- /* Free pkg list */
- list_for_each_entry_safe(pkg, tmp, &sender->pkg_list, entry) {
- list_del(&pkg->entry);
- kfree(pkg);
- }
- mdfld_dbi_cb_destroy(sender); /* free mapped command buffer */
- kfree(sender);
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.h b/drivers/staging/gma500/mdfld_dsi_pkg_sender.h
deleted file mode 100644
index f24abc700684..000000000000
--- a/drivers/staging/gma500/mdfld_dsi_pkg_sender.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jackie Li
- */
-#ifndef __MDFLD_DSI_PKG_SENDER_H__
-#define __MDFLD_DSI_PKG_SENDER_H__
-
-#include
-
-#define MDFLD_MAX_DCS_PARAM 8
-#define MDFLD_MAX_PKG_NUM 2048
-
-enum {
- MDFLD_DSI_PKG_DCS,
- MDFLD_DSI_PKG_GEN_SHORT_WRITE_0 = 0x03,
- MDFLD_DSI_PKG_GEN_SHORT_WRITE_1 = 0x13,
- MDFLD_DSI_PKG_GEN_SHORT_WRITE_2 = 0x23,
- MDFLD_DSI_PKG_GEN_READ_0 = 0x04,
- MDFLD_DSI_PKG_GEN_READ_1 = 0x14,
- MDFLD_DSI_PKG_GEN_READ_2 = 0x24,
- MDFLD_DSI_PKG_GEN_LONG_WRITE = 0x29,
- MDFLD_DSI_PKG_MCS_SHORT_WRITE_0 = 0x05,
- MDFLD_DSI_PKG_MCS_SHORT_WRITE_1 = 0x15,
- MDFLD_DSI_PKG_MCS_READ = 0x06,
- MDFLD_DSI_PKG_MCS_LONG_WRITE = 0x39,
-};
-
-enum {
- MDFLD_DSI_LP_TRANSMISSION,
- MDFLD_DSI_HS_TRANSMISSION,
- MDFLD_DSI_DCS,
-};
-
-enum {
- MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
-};
-
-enum {
- MDFLD_DSI_PKG_SENDER_FREE = 0x0,
- MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
-};
-
-enum {
- MDFLD_DSI_SEND_PACKAGE,
- MDFLD_DSI_QUEUE_PACKAGE,
-};
-
-struct mdfld_dsi_gen_short_pkg {
- u8 cmd;
- u8 param;
-};
-
-struct mdfld_dsi_gen_long_pkg {
- u32 *data;
- u32 len;
-};
-
-struct mdfld_dsi_dcs_pkg {
- u8 cmd;
- u8 param[MDFLD_MAX_DCS_PARAM];
- u32 param_num;
- u8 data_src;
-};
-
-struct mdfld_dsi_pkg {
- u8 pkg_type;
- u8 transmission_type;
-
- union {
- struct mdfld_dsi_gen_short_pkg short_pkg;
- struct mdfld_dsi_gen_long_pkg long_pkg;
- struct mdfld_dsi_dcs_pkg dcs_pkg;
- } pkg;
-
- struct list_head entry;
-};
-
-struct mdfld_dsi_pkg_sender {
- struct drm_device *dev;
- struct mdfld_dsi_connector *dsi_connector;
- u32 status;
-
- u32 panel_mode;
-
- int pipe;
-
- spinlock_t lock;
- struct list_head pkg_list;
- struct list_head free_list;
-
- u32 pkg_num;
-
- int dbi_pkg_support;
-
- u32 dbi_cb_phy;
- void *dbi_cb_addr;
-
- /* Registers */
- u32 dpll_reg;
- u32 dspcntr_reg;
- u32 pipeconf_reg;
- u32 pipestat_reg;
- u32 dsplinoff_reg;
- u32 dspsurf_reg;
-
- u32 mipi_intr_stat_reg;
- u32 mipi_lp_gen_data_reg;
- u32 mipi_hs_gen_data_reg;
- u32 mipi_lp_gen_ctrl_reg;
- u32 mipi_hs_gen_ctrl_reg;
- u32 mipi_gen_fifo_stat_reg;
- u32 mipi_data_addr_reg;
- u32 mipi_data_len_reg;
- u32 mipi_cmd_addr_reg;
- u32 mipi_cmd_len_reg;
-};
-
-/* DCS definitions */
-#define DCS_SOFT_RESET 0x01
-#define DCS_ENTER_SLEEP_MODE 0x10
-#define DCS_EXIT_SLEEP_MODE 0x11
-#define DCS_SET_DISPLAY_OFF 0x28
-#define DCS_SET_DISPLAY_ON 0x29
-#define DCS_SET_COLUMN_ADDRESS 0x2a
-#define DCS_SET_PAGE_ADDRESS 0x2b
-#define DCS_WRITE_MEM_START 0x2c
-#define DCS_SET_TEAR_OFF 0x34
-#define DCS_SET_TEAR_ON 0x35
-
-extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
- int pipe);
-extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender);
-extern int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender, u8 dcs,
- u8 *param, u32 param_num, u8 data_src, int delay);
-extern int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd, u8 param, u8 param_num, int delay);
-extern int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd, u8 param, u8 param_num, int delay);
-extern int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
- u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
- u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 param0, u8 param1, u8 param_num, int delay);
-extern int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 param0, u8 param1, u8 param_num, int delay);
-extern int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
- u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
- u32 *data, u32 len, int delay);
-
-extern int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
-extern int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
-extern int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd, u32 *data, u16 len);
-extern int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender,
- u8 cmd, u32 *data, u16 len);
-
-extern void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender);
-
-#endif /* __MDFLD_DSI_PKG_SENDER_H__ */
diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c
deleted file mode 100644
index 0b37b7b6b02a..000000000000
--- a/drivers/staging/gma500/mdfld_intel_display.c
+++ /dev/null
@@ -1,1404 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt
- */
-
-#include "framebuffer.h"
-#include "psb_intel_display.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_dbi_dpu.h"
-
-#include
-
-#ifdef MIN
-#undef MIN
-#endif
-
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-
-/* Hardcoded currently */
-static int ksel = KSEL_CRYSTAL_19;
-
-extern void mdfld_save_display(struct drm_device *dev);
-extern bool gbgfxsuspended;
-
-struct psb_intel_range_t {
- int min, max;
-};
-
-struct mdfld_limit_t {
- struct psb_intel_range_t dot, m, p1;
-};
-
-struct mdfld_intel_clock_t {
- /* given values */
- int n;
- int m1, m2;
- int p1, p2;
- /* derived values */
- int dot;
- int vco;
- int m;
- int p;
-};
-
-
-
-#define COUNT_MAX 0x10000000
-
-void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
-{
- int count, temp;
- u32 pipeconf_reg = PIPEACONF;
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- pipeconf_reg = PIPEBCONF;
- break;
- case 2:
- pipeconf_reg = PIPECCONF;
- break;
- default:
- DRM_ERROR("Illegal Pipe Number. \n");
- return;
- }
-
- /* FIXME JLIU7_PO */
- psb_intel_wait_for_vblank(dev);
- return;
-
- /* Wait for for the pipe disable to take effect. */
- for (count = 0; count < COUNT_MAX; count++) {
- temp = REG_READ(pipeconf_reg);
- if ((temp & PIPEACONF_PIPE_STATE) == 0)
- break;
- }
-}
-
-void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
-{
- int count, temp;
- u32 pipeconf_reg = PIPEACONF;
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- pipeconf_reg = PIPEBCONF;
- break;
- case 2:
- pipeconf_reg = PIPECCONF;
- break;
- default:
- dev_err(dev->dev, "Illegal Pipe Number.\n");
- return;
- }
-
- /* FIXME JLIU7_PO */
- psb_intel_wait_for_vblank(dev);
- return;
-
- /* Wait for for the pipe enable to take effect. */
- for (count = 0; count < COUNT_MAX; count++) {
- temp = REG_READ(pipeconf_reg);
- if ((temp & PIPEACONF_PIPE_STATE) == 1)
- break;
- }
-}
-
-
-static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
- struct drm_file *file_priv,
- uint32_t handle,
- uint32_t width, uint32_t height)
-{
- struct drm_device *dev = crtc->dev;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- uint32_t control = CURACNTR;
- uint32_t base = CURABASE;
- uint32_t temp;
- size_t addr = 0;
- struct gtt_range *gt;
- struct drm_gem_object *obj;
- int ret;
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- control = CURBCNTR;
- base = CURBBASE;
- break;
- case 2:
- control = CURCCNTR;
- base = CURCBASE;
- break;
- default:
- dev_err(dev->dev, "Illegal Pipe Number. \n");
- return -EINVAL;
- }
-
-#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
- if (pipe != 0)
- return 0;
-#endif
- /* if we want to turn of the cursor ignore width and height */
- if (!handle) {
- dev_dbg(dev->dev, "cursor off\n");
- /* turn off the cursor */
- temp = 0;
- temp |= CURSOR_MODE_DISABLE;
-
- if (gma_power_begin(dev, true)) {
- REG_WRITE(control, temp);
- REG_WRITE(base, 0);
- gma_power_end(dev);
- }
- /* Unpin the old GEM object */
- if (psb_intel_crtc->cursor_obj) {
- gt = container_of(psb_intel_crtc->cursor_obj,
- struct gtt_range, gem);
- psb_gtt_unpin(gt);
- drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
- psb_intel_crtc->cursor_obj = NULL;
- }
- return 0;
- }
-
- /* Currently we only support 64x64 cursors */
- if (width != 64 || height != 64) {
- DRM_ERROR("we currently only support 64x64 cursors\n");
- return -EINVAL;
- }
-
- obj = drm_gem_object_lookup(dev, file_priv, handle);
- if (!obj)
- return -ENOENT;
-
- if (obj->size < width * height * 4) {
- dev_dbg(dev->dev, "buffer is to small\n");
- return -ENOMEM;
- }
-
- gt = container_of(obj, struct gtt_range, gem);
-
- /* Pin the memory into the GTT */
- ret = psb_gtt_pin(gt);
- if (ret) {
- dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
- return ret;
- }
-
-
- addr = gt->offset; /* Or resource.start ??? */
-
- psb_intel_crtc->cursor_addr = addr;
-
- temp = 0;
- /* set the pipe for the cursor */
- temp |= (pipe << 28);
- temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
- if (gma_power_begin(dev, true)) {
- REG_WRITE(control, temp);
- REG_WRITE(base, addr);
- gma_power_end(dev);
- }
- /* unpin the old GEM object */
- if (psb_intel_crtc->cursor_obj) {
- gt = container_of(psb_intel_crtc->cursor_obj,
- struct gtt_range, gem);
- psb_gtt_unpin(gt);
- drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
- psb_intel_crtc->cursor_obj = obj;
- }
- return 0;
-}
-
-static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
- struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
- struct psb_drm_dpu_rect rect;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- uint32_t pos = CURAPOS;
- uint32_t base = CURABASE;
- uint32_t temp = 0;
- uint32_t addr;
-
- switch (pipe) {
- case 0:
- if (dpu_info) {
- rect.x = x;
- rect.y = y;
-
- mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect);
- mdfld_dpu_exit_dsr(dev);
- } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
- mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_0);
- break;
- case 1:
- pos = CURBPOS;
- base = CURBBASE;
- break;
- case 2:
- if (dpu_info) {
- mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
- mdfld_dpu_exit_dsr(dev);
- } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
- mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_2);
- pos = CURCPOS;
- base = CURCBASE;
- break;
- default:
- DRM_ERROR("Illegal Pipe Number. \n");
- return -EINVAL;
- }
-
-#if 1 /* FIXME_JLIU7 can't enable cursorB/C HW issue. need to remove after HW fix */
- if (pipe != 0)
- return 0;
-#endif
- if (x < 0) {
- temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
- x = -x;
- }
- if (y < 0) {
- temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
- y = -y;
- }
-
- temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
- temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
- addr = psb_intel_crtc->cursor_addr;
-
- if (gma_power_begin(dev, true)) {
- REG_WRITE(pos, temp);
- REG_WRITE(base, addr);
- gma_power_end(dev);
- }
-
- return 0;
-}
-
-const struct drm_crtc_funcs mdfld_intel_crtc_funcs = {
- .cursor_set = mdfld_intel_crtc_cursor_set,
- .cursor_move = mdfld_intel_crtc_cursor_move,
- .gamma_set = psb_intel_crtc_gamma_set,
- .set_config = drm_crtc_helper_set_config,
- .destroy = psb_intel_crtc_destroy,
-};
-
-static struct drm_device globle_dev;
-
-void mdfld__intel_plane_set_alpha(int enable)
-{
- struct drm_device *dev = &globle_dev;
- int dspcntr_reg = DSPACNTR;
- u32 dspcntr;
-
- dspcntr = REG_READ(dspcntr_reg);
-
- if (enable) {
- dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
- dspcntr |= DISPPLANE_32BPP;
- } else {
- dspcntr &= ~DISPPLANE_32BPP;
- dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
- }
-
- REG_WRITE(dspcntr_reg, dspcntr);
-}
-
-int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb)
-{
- struct drm_device *dev = crtc->dev;
- /* struct drm_i915_master_private *master_priv; */
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
- int pipe = psb_intel_crtc->pipe;
- unsigned long start, offset;
- int dsplinoff = DSPALINOFF;
- int dspsurf = DSPASURF;
- int dspstride = DSPASTRIDE;
- int dspcntr_reg = DSPACNTR;
- u32 dspcntr;
- int ret = 0;
-
- memcpy(&globle_dev, dev, sizeof(struct drm_device));
-
- if (!gma_power_begin(dev, true))
- return 0;
-
- /* no fb bound */
- if (!crtc->fb) {
- dev_err(dev->dev, "No FB bound\n");
- goto psb_intel_pipe_cleaner;
- }
-
- switch (pipe) {
- case 0:
- dsplinoff = DSPALINOFF;
- break;
- case 1:
- dsplinoff = DSPBLINOFF;
- dspsurf = DSPBSURF;
- dspstride = DSPBSTRIDE;
- dspcntr_reg = DSPBCNTR;
- break;
- case 2:
- dsplinoff = DSPCLINOFF;
- dspsurf = DSPCSURF;
- dspstride = DSPCSTRIDE;
- dspcntr_reg = DSPCCNTR;
- break;
- default:
- dev_err(dev->dev, "Illegal Pipe Number.\n");
- return -EINVAL;
- }
-
- ret = psb_gtt_pin(psbfb->gtt);
- if (ret < 0)
- goto psb_intel_pipe_set_base_exit;
-
- start = psbfb->gtt->offset;
- offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
- REG_WRITE(dspstride, crtc->fb->pitches[0]);
- dspcntr = REG_READ(dspcntr_reg);
- dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
- switch (crtc->fb->bits_per_pixel) {
- case 8:
- dspcntr |= DISPPLANE_8BPP;
- break;
- case 16:
- if (crtc->fb->depth == 15)
- dspcntr |= DISPPLANE_15_16BPP;
- else
- dspcntr |= DISPPLANE_16BPP;
- break;
- case 24:
- case 32:
- dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
- break;
- default:
- dev_err(dev->dev, "Unknown color depth\n");
- ret = -EINVAL;
- goto psb_intel_pipe_set_base_exit;
- }
- REG_WRITE(dspcntr_reg, dspcntr);
-
- dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
- start, offset, x, y);
-
- REG_WRITE(dsplinoff, offset);
- REG_READ(dsplinoff);
- REG_WRITE(dspsurf, start);
- REG_READ(dspsurf);
-
-psb_intel_pipe_cleaner:
- /* If there was a previous display we can now unpin it */
- if (old_fb)
- psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
- gma_power_end(dev);
- return ret;
-}
-
-/**
- * Disable the pipe, plane and pll.
- *
- */
-void mdfld_disable_crtc (struct drm_device *dev, int pipe)
-{
- int dpll_reg = MRST_DPLL_A;
- int dspcntr_reg = DSPACNTR;
- int dspbase_reg = MRST_DSPABASE;
- int pipeconf_reg = PIPEACONF;
- u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
- u32 temp;
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- dpll_reg = MDFLD_DPLL_B;
- dspcntr_reg = DSPBCNTR;
- dspbase_reg = DSPBSURF;
- pipeconf_reg = PIPEBCONF;
- break;
- case 2:
- dpll_reg = MRST_DPLL_A;
- dspcntr_reg = DSPCCNTR;
- dspbase_reg = MDFLD_DSPCBASE;
- pipeconf_reg = PIPECCONF;
- gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
- break;
- default:
- dev_err(dev->dev, "Illegal Pipe Number. \n");
- return;
- }
-
- if (pipe != 1)
- mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
- /* Disable display plane */
- temp = REG_READ(dspcntr_reg);
- if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
- REG_WRITE(dspcntr_reg,
- temp & ~DISPLAY_PLANE_ENABLE);
- /* Flush the plane changes */
- REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
- REG_READ(dspbase_reg);
- }
-
- /* FIXME_JLIU7 MDFLD_PO revisit */
- /* Wait for vblank for the disable to take effect */
-/* MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev); */
-
- /* Next, disable display pipes */
- temp = REG_READ(pipeconf_reg);
- if ((temp & PIPEACONF_ENABLE) != 0) {
- temp &= ~PIPEACONF_ENABLE;
- temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
- REG_WRITE(pipeconf_reg, temp);
- REG_READ(pipeconf_reg);
-
- /* Wait for for the pipe disable to take effect. */
- mdfldWaitForPipeDisable(dev, pipe);
- }
-
- temp = REG_READ(dpll_reg);
- if (temp & DPLL_VCO_ENABLE) {
- if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
- || (pipe == 1)){
- temp &= ~(DPLL_VCO_ENABLE);
- REG_WRITE(dpll_reg, temp);
- REG_READ(dpll_reg);
- /* Wait for the clocks to turn off. */
- /* FIXME_MDFLD PO may need more delay */
- udelay(500);
-
- if (!(temp & MDFLD_PWR_GATE_EN)) {
- /* gating power of DPLL */
- REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(5000);
- }
- }
- }
-
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- int pipe = psb_intel_crtc->pipe;
- int dpll_reg = MRST_DPLL_A;
- int dspcntr_reg = DSPACNTR;
- int dspbase_reg = MRST_DSPABASE;
- int pipeconf_reg = PIPEACONF;
- u32 pipestat_reg = PIPEASTAT;
- u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
- u32 pipeconf = dev_priv->pipeconf;
- u32 dspcntr = dev_priv->dspcntr;
- u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG;
- u32 temp;
- bool enabled;
- int timeout = 0;
-
- if (!gma_power_begin(dev, true))
- return;
-
- /* Ignore if system is already in DSR and in suspended state. */
- if(/*gbgfxsuspended */0 && dev_priv->dispstatus == false && mode == 3){
- if(dev_priv->rpm_enabled && pipe == 1){
- // dev_priv->is_mipi_on = false;
- pm_request_idle(&dev->pdev->dev);
- }
- return;
- }else if(mode == 0) {
- //do not need to set gbdispstatus=true in crtc.
- //this will be set in encoder such as mdfld_dsi_dbi_dpms
- //gbdispstatus = true;
- }
-
-/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
-/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- dpll_reg = DPLL_B;
- dspcntr_reg = DSPBCNTR;
- dspbase_reg = MRST_DSPBBASE;
- pipeconf_reg = PIPEBCONF;
- pipeconf = dev_priv->pipeconf1;
- dspcntr = dev_priv->dspcntr1;
- dpll_reg = MDFLD_DPLL_B;
- break;
- case 2:
- dpll_reg = MRST_DPLL_A;
- dspcntr_reg = DSPCCNTR;
- dspbase_reg = MDFLD_DSPCBASE;
- pipeconf_reg = PIPECCONF;
- pipestat_reg = PIPECSTAT;
- pipeconf = dev_priv->pipeconf2;
- dspcntr = dev_priv->dspcntr2;
- gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
- mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET;
- break;
- default:
- dev_err(dev->dev, "Illegal Pipe Number.\n");
- return;
- }
-
- /* XXX: When our outputs are all unaware of DPMS modes other than off
- * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
- */
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- /* Enable the DPLL */
- temp = REG_READ(dpll_reg);
-
- if ((temp & DPLL_VCO_ENABLE) == 0) {
- /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
- if (temp & MDFLD_PWR_GATE_EN) {
- temp &= ~MDFLD_PWR_GATE_EN;
- REG_WRITE(dpll_reg, temp);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
- }
-
- REG_WRITE(dpll_reg, temp);
- REG_READ(dpll_reg);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
-
- REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
- REG_READ(dpll_reg);
-
- /**
- * wait for DSI PLL to lock
- * NOTE: only need to poll status of pipe 0 and pipe 1,
- * since both MIPI pipes share the same PLL.
- */
- while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
- udelay(150);
- timeout ++;
- }
- }
-
- /* Enable the plane */
- temp = REG_READ(dspcntr_reg);
- if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
- REG_WRITE(dspcntr_reg,
- temp | DISPLAY_PLANE_ENABLE);
- /* Flush the plane changes */
- REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
- }
-
- /* Enable the pipe */
- temp = REG_READ(pipeconf_reg);
- if ((temp & PIPEACONF_ENABLE) == 0) {
- REG_WRITE(pipeconf_reg, pipeconf);
-
- /* Wait for for the pipe enable to take effect. */
- mdfldWaitForPipeEnable(dev, pipe);
- }
-
- /*workaround for sighting 3741701 Random X blank display*/
- /*perform w/a in video mode only on pipe A or C*/
- if ((pipe == 0 || pipe == 2) &&
- (mdfld_panel_dpi(dev) == true)) {
- REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
- msleep(100);
- if(PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) {
- printk(KERN_ALERT "OK");
- } else {
- printk(KERN_ALERT "STUCK!!!!");
- /*shutdown controller*/
- temp = REG_READ(dspcntr_reg);
- REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
- REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
- /*mdfld_dsi_dpi_shut_down(dev, pipe);*/
- REG_WRITE(0xb048, 1);
- msleep(100);
- temp = REG_READ(pipeconf_reg);
- temp &= ~PIPEACONF_ENABLE;
- REG_WRITE(pipeconf_reg, temp);
- msleep(100); /*wait for pipe disable*/
- /*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
- printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/
- REG_WRITE(mipi_enable_reg, 0);
- msleep(100);
- printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
- printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));
- REG_WRITE(0xb004, REG_READ(0xb004));
- /* try to bring the controller back up again*/
- REG_WRITE(mipi_enable_reg, 1);
- temp = REG_READ(dspcntr_reg);
- REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
- REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
- /*mdfld_dsi_dpi_turn_on(dev, pipe);*/
- REG_WRITE(0xb048, 2);
- msleep(100);
- temp = REG_READ(pipeconf_reg);
- temp |= PIPEACONF_ENABLE;
- REG_WRITE(pipeconf_reg, temp);
- }
- }
-
- psb_intel_crtc_load_lut(crtc);
-
- /* Give the overlay scaler a chance to enable
- if it's on this pipe */
- /* psb_intel_crtc_dpms_video(crtc, true); TODO */
-
- break;
- case DRM_MODE_DPMS_OFF:
- /* Give the overlay scaler a chance to disable
- * if it's on this pipe */
- /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
- if (pipe != 1)
- mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
- /* Disable the VGA plane that we never use */
- REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
- /* Disable display plane */
- temp = REG_READ(dspcntr_reg);
- if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
- REG_WRITE(dspcntr_reg,
- temp & ~DISPLAY_PLANE_ENABLE);
- /* Flush the plane changes */
- REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
- REG_READ(dspbase_reg);
- }
-
- /* FIXME_JLIU7 MDFLD_PO revisit */
- /* Wait for vblank for the disable to take effect */
-// MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
-
- /* Next, disable display pipes */
- temp = REG_READ(pipeconf_reg);
- if ((temp & PIPEACONF_ENABLE) != 0) {
- temp &= ~PIPEACONF_ENABLE;
- temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
- REG_WRITE(pipeconf_reg, temp);
-// REG_WRITE(pipeconf_reg, 0);
- REG_READ(pipeconf_reg);
-
- /* Wait for for the pipe disable to take effect. */
- mdfldWaitForPipeDisable(dev, pipe);
- }
-
- temp = REG_READ(dpll_reg);
- if (temp & DPLL_VCO_ENABLE) {
- if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
- || (pipe == 1)){
- temp &= ~(DPLL_VCO_ENABLE);
- REG_WRITE(dpll_reg, temp);
- REG_READ(dpll_reg);
- /* Wait for the clocks to turn off. */
- /* FIXME_MDFLD PO may need more delay */
- udelay(500);
-#if 0 /* MDFLD_PO_JLIU7 */
- if (!(temp & MDFLD_PWR_GATE_EN)) {
- /* gating power of DPLL */
- REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(5000);
- }
-#endif /* MDFLD_PO_JLIU7 */
- }
- }
- break;
- }
-
- enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
-#if 0 /* JB: Add vblank support later */
- if (enabled)
- dev_priv->vblank_pipe |= (1 << pipe);
- else
- dev_priv->vblank_pipe &= ~(1 << pipe);
-#endif
-
- gma_power_end(dev);
-}
-
-
-#define MDFLD_LIMT_DPLL_19 0
-#define MDFLD_LIMT_DPLL_25 1
-#define MDFLD_LIMT_DPLL_83 2
-#define MDFLD_LIMT_DPLL_100 3
-#define MDFLD_LIMT_DSIPLL_19 4
-#define MDFLD_LIMT_DSIPLL_25 5
-#define MDFLD_LIMT_DSIPLL_83 6
-#define MDFLD_LIMT_DSIPLL_100 7
-
-#define MDFLD_DOT_MIN 19750 /* FIXME_MDFLD JLIU7 need to find out min & max for MDFLD */
-#define MDFLD_DOT_MAX 120000
-#define MDFLD_DPLL_M_MIN_19 113
-#define MDFLD_DPLL_M_MAX_19 155
-#define MDFLD_DPLL_P1_MIN_19 2
-#define MDFLD_DPLL_P1_MAX_19 10
-#define MDFLD_DPLL_M_MIN_25 101
-#define MDFLD_DPLL_M_MAX_25 130
-#define MDFLD_DPLL_P1_MIN_25 2
-#define MDFLD_DPLL_P1_MAX_25 10
-#define MDFLD_DPLL_M_MIN_83 64
-#define MDFLD_DPLL_M_MAX_83 64
-#define MDFLD_DPLL_P1_MIN_83 2
-#define MDFLD_DPLL_P1_MAX_83 2
-#define MDFLD_DPLL_M_MIN_100 64
-#define MDFLD_DPLL_M_MAX_100 64
-#define MDFLD_DPLL_P1_MIN_100 2
-#define MDFLD_DPLL_P1_MAX_100 2
-#define MDFLD_DSIPLL_M_MIN_19 131
-#define MDFLD_DSIPLL_M_MAX_19 175
-#define MDFLD_DSIPLL_P1_MIN_19 3
-#define MDFLD_DSIPLL_P1_MAX_19 8
-#define MDFLD_DSIPLL_M_MIN_25 97
-#define MDFLD_DSIPLL_M_MAX_25 140
-#define MDFLD_DSIPLL_P1_MIN_25 3
-#define MDFLD_DSIPLL_P1_MAX_25 9
-#define MDFLD_DSIPLL_M_MIN_83 33
-#define MDFLD_DSIPLL_M_MAX_83 92
-#define MDFLD_DSIPLL_P1_MIN_83 2
-#define MDFLD_DSIPLL_P1_MAX_83 3
-#define MDFLD_DSIPLL_M_MIN_100 97
-#define MDFLD_DSIPLL_M_MAX_100 140
-#define MDFLD_DSIPLL_P1_MIN_100 3
-#define MDFLD_DSIPLL_P1_MAX_100 9
-
-static const struct mdfld_limit_t mdfld_limits[] = {
- { /* MDFLD_LIMT_DPLL_19 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
- .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
- },
- { /* MDFLD_LIMT_DPLL_25 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
- .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
- },
- { /* MDFLD_LIMT_DPLL_83 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
- .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
- },
- { /* MDFLD_LIMT_DPLL_100 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
- .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
- },
- { /* MDFLD_LIMT_DSIPLL_19 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
- .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
- },
- { /* MDFLD_LIMT_DSIPLL_25 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
- .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
- },
- { /* MDFLD_LIMT_DSIPLL_83 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
- .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
- },
- { /* MDFLD_LIMT_DSIPLL_100 */
- .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
- .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
- .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
- },
-};
-
-#define MDFLD_M_MIN 21
-#define MDFLD_M_MAX 180
-static const u32 mdfld_m_converts[] = {
-/* M configuration table from 9-bit LFSR table */
- 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
- 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */
- 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
- 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
- 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
- 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
- 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
- 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
- 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
- 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
- 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
- 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
- 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
- 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
- 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
- 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
-};
-
-static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc)
-{
- const struct mdfld_limit_t *limit = NULL;
- struct drm_device *dev = crtc->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
- || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
- if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
- limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
- else if (ksel == KSEL_BYPASS_25)
- limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
- else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
- limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
- else if ((ksel == KSEL_BYPASS_83_100) &&
- (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
- limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
- } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
- if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
- limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
- else if (ksel == KSEL_BYPASS_25)
- limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
- else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
- limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
- else if ((ksel == KSEL_BYPASS_83_100) &&
- (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
- limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
- } else {
- limit = NULL;
- dev_err(dev->dev, "mdfld_limit Wrong display type.\n");
- }
-
- return limit;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-static void mdfld_clock(int refclk, struct mdfld_intel_clock_t *clock)
-{
- clock->dot = (refclk * clock->m) / clock->p1;
-}
-
-/**
- * Returns a set of divisors for the desired target clock with the given refclk,
- * or FALSE. Divisor values are the actual divisors for
- */
-static bool
-mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
- struct mdfld_intel_clock_t *best_clock)
-{
- struct mdfld_intel_clock_t clock;
- const struct mdfld_limit_t *limit = mdfld_limit(crtc);
- int err = target;
-
- memset(best_clock, 0, sizeof(*best_clock));
-
- for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
- for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
- clock.p1++) {
- int this_err;
-
- mdfld_clock(refclk, &clock);
-
- this_err = abs(clock.dot - target);
- if (this_err < err) {
- *best_clock = clock;
- err = this_err;
- }
- }
- }
- return err != target;
-}
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int mdfld_panel_fitter_pipe(struct drm_device *dev)
-{
- u32 pfit_control;
-
- pfit_control = REG_READ(PFIT_CONTROL);
-
- /* See if the panel fitter is in use */
- if ((pfit_control & PFIT_ENABLE) == 0)
- return -1;
- return (pfit_control >> 29) & 3;
-}
-
-static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y,
- struct drm_framebuffer *old_fb)
-{
- struct drm_device *dev = crtc->dev;
- struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
- struct drm_psb_private *dev_priv = dev->dev_private;
- int pipe = psb_intel_crtc->pipe;
- int fp_reg = MRST_FPA0;
- int dpll_reg = MRST_DPLL_A;
- int dspcntr_reg = DSPACNTR;
- int pipeconf_reg = PIPEACONF;
- int htot_reg = HTOTAL_A;
- int hblank_reg = HBLANK_A;
- int hsync_reg = HSYNC_A;
- int vtot_reg = VTOTAL_A;
- int vblank_reg = VBLANK_A;
- int vsync_reg = VSYNC_A;
- int dspsize_reg = DSPASIZE;
- int dsppos_reg = DSPAPOS;
- int pipesrc_reg = PIPEASRC;
- u32 *pipeconf = &dev_priv->pipeconf;
- u32 *dspcntr = &dev_priv->dspcntr;
- int refclk = 0;
- int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0;
- struct mdfld_intel_clock_t clock;
- bool ok;
- u32 dpll = 0, fp = 0;
- bool is_crt = false, is_lvds = false, is_tv = false;
- bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
- struct drm_mode_config *mode_config = &dev->mode_config;
- struct psb_intel_output *psb_intel_output = NULL;
- uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
- struct drm_encoder *encoder;
- struct drm_connector *connector;
- int timeout = 0;
-
- dev_dbg(dev->dev, "pipe = 0x%x \n", pipe);
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- fp_reg = FPB0;
- dpll_reg = DPLL_B;
- dspcntr_reg = DSPBCNTR;
- pipeconf_reg = PIPEBCONF;
- htot_reg = HTOTAL_B;
- hblank_reg = HBLANK_B;
- hsync_reg = HSYNC_B;
- vtot_reg = VTOTAL_B;
- vblank_reg = VBLANK_B;
- vsync_reg = VSYNC_B;
- dspsize_reg = DSPBSIZE;
- dsppos_reg = DSPBPOS;
- pipesrc_reg = PIPEBSRC;
- pipeconf = &dev_priv->pipeconf1;
- dspcntr = &dev_priv->dspcntr1;
- fp_reg = MDFLD_DPLL_DIV0;
- dpll_reg = MDFLD_DPLL_B;
- break;
- case 2:
- dpll_reg = MRST_DPLL_A;
- dspcntr_reg = DSPCCNTR;
- pipeconf_reg = PIPECCONF;
- htot_reg = HTOTAL_C;
- hblank_reg = HBLANK_C;
- hsync_reg = HSYNC_C;
- vtot_reg = VTOTAL_C;
- vblank_reg = VBLANK_C;
- vsync_reg = VSYNC_C;
- dspsize_reg = DSPCSIZE;
- dsppos_reg = DSPCPOS;
- pipesrc_reg = PIPECSRC;
- pipeconf = &dev_priv->pipeconf2;
- dspcntr = &dev_priv->dspcntr2;
- break;
- default:
- DRM_ERROR("Illegal Pipe Number. \n");
- return 0;
- }
-
- dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
- adjusted_mode->hdisplay);
- dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
- adjusted_mode->vdisplay);
- dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
- adjusted_mode->hsync_start);
- dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
- adjusted_mode->hsync_end);
- dev_dbg(dev->dev, "adjusted_htotal = %d\n",
- adjusted_mode->htotal);
- dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
- adjusted_mode->vsync_start);
- dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
- adjusted_mode->vsync_end);
- dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
- adjusted_mode->vtotal);
- dev_dbg(dev->dev, "adjusted_clock = %d\n",
- adjusted_mode->clock);
- dev_dbg(dev->dev, "hdisplay = %d\n",
- mode->hdisplay);
- dev_dbg(dev->dev, "vdisplay = %d\n",
- mode->vdisplay);
-
- if (!gma_power_begin(dev, true))
- return 0;
-
- memcpy(&psb_intel_crtc->saved_mode, mode, sizeof(struct drm_display_mode));
- memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, sizeof(struct drm_display_mode));
-
- list_for_each_entry(connector, &mode_config->connector_list, head) {
-
- encoder = connector->encoder;
-
- if(!encoder)
- continue;
-
- if (encoder->crtc != crtc)
- continue;
-
- psb_intel_output = to_psb_intel_output(connector);
-
- dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type);
-
- switch (psb_intel_output->type) {
- case INTEL_OUTPUT_LVDS:
- is_lvds = true;
- break;
- case INTEL_OUTPUT_TVOUT:
- is_tv = true;
- break;
- case INTEL_OUTPUT_ANALOG:
- is_crt = true;
- break;
- case INTEL_OUTPUT_MIPI:
- is_mipi = true;
- break;
- case INTEL_OUTPUT_MIPI2:
- is_mipi2 = true;
- break;
- case INTEL_OUTPUT_HDMI:
- is_hdmi = true;
- break;
- }
- }
-
- /* Disable the VGA plane that we never use */
- REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
- /* Disable the panel fitter if it was on our pipe */
- if (mdfld_panel_fitter_pipe(dev) == pipe)
- REG_WRITE(PFIT_CONTROL, 0);
-
- /* pipesrc and dspsize control the size that is scaled from,
- * which should always be the user's requested size.
- */
- if (pipe == 1) {
- /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
- * width/height and souce image size registers with the adjusted mode for pipe B. */
-
- /* The defined sprite rectangle must always be completely contained within the displayable
- * area of the screen image (frame buffer). */
- REG_WRITE(dspsize_reg, ((MIN(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
- | (MIN(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
- /* Set the CRTC with encoder mode. */
- REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
- | (mode->crtc_vdisplay - 1));
- } else {
- REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1));
- REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
- }
-
- REG_WRITE(dsppos_reg, 0);
-
- if (psb_intel_output)
- drm_connector_property_get_value(&psb_intel_output->base,
- dev->mode_config.scaling_mode_property, &scalingType);
-
- if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
- /*
- * Medfield doesn't have register support for centering so
- * we need to mess with the h/vblank and h/vsync start and
- * ends to get central
- */
- int offsetX = 0, offsetY = 0;
-
- offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
- offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
-
- REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
- ((adjusted_mode->crtc_htotal - 1) << 16));
- REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
- ((adjusted_mode->crtc_vtotal - 1) << 16));
- REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) |
- ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
- REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) |
- ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
- REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) |
- ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
- REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) |
- ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
- } else {
- REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
- ((adjusted_mode->crtc_htotal - 1) << 16));
- REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
- ((adjusted_mode->crtc_vtotal - 1) << 16));
- REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
- ((adjusted_mode->crtc_hblank_end - 1) << 16));
- REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
- ((adjusted_mode->crtc_hsync_end - 1) << 16));
- REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
- ((adjusted_mode->crtc_vblank_end - 1) << 16));
- REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
- ((adjusted_mode->crtc_vsync_end - 1) << 16));
- }
-
- /* Flush the plane changes */
- {
- struct drm_crtc_helper_funcs *crtc_funcs =
- crtc->helper_private;
- crtc_funcs->mode_set_base(crtc, x, y, old_fb);
- }
-
- /* setup pipeconf */
- *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
-
- /* Set up the display plane register */
- *dspcntr = REG_READ(dspcntr_reg);
- *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
- *dspcntr |= DISPLAY_PLANE_ENABLE;
-/* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_BOTTOM; */
-/* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_GAMMA_ENABLE; */
-
- if (is_mipi2)
- {
- goto mrst_crtc_mode_set_exit;
- }
-/* FIXME JLIU7 Add MDFLD HDMI supports */
-/* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */
-/* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */
- clk = adjusted_mode->clock;
-
- if (is_hdmi) {
- if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
- {
- refclk = 19200;
-
- if (is_mipi || is_mipi2)
- {
- clk_n = 1, clk_p2 = 8;
- } else if (is_hdmi) {
- clk_n = 1, clk_p2 = 10;
- }
- } else if (ksel == KSEL_BYPASS_25) {
- refclk = 25000;
-
- if (is_mipi || is_mipi2)
- {
- clk_n = 1, clk_p2 = 8;
- } else if (is_hdmi) {
- clk_n = 1, clk_p2 = 10;
- }
- } else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) {
- refclk = 83000;
-
- if (is_mipi || is_mipi2)
- {
- clk_n = 4, clk_p2 = 8;
- } else if (is_hdmi) {
- clk_n = 4, clk_p2 = 10;
- }
- } else if ((ksel == KSEL_BYPASS_83_100) &&
- (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) {
- refclk = 100000;
- if (is_mipi || is_mipi2)
- {
- clk_n = 4, clk_p2 = 8;
- } else if (is_hdmi) {
- clk_n = 4, clk_p2 = 10;
- }
- }
-
- if (is_mipi)
- clk_byte = dev_priv->bpp / 8;
- else if (is_mipi2)
- clk_byte = dev_priv->bpp2 / 8;
-
- clk_tmp = clk * clk_n * clk_p2 * clk_byte;
-
- dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n, clk_p2);
- dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode->clock, clk_tmp);
-
- ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
-
- if (!ok) {
- dev_err(dev->dev,
- "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n");
- } else {
- m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
-
- dev_dbg(dev->dev, "dot clock = %d,"
- "m = %d, p1 = %d, m_conv = %d. \n", clock.dot, clock.m,
- clock.p1, m_conv);
- }
-
- dpll = REG_READ(dpll_reg);
-
- if (dpll & DPLL_VCO_ENABLE) {
- dpll &= ~DPLL_VCO_ENABLE;
- REG_WRITE(dpll_reg, dpll);
- REG_READ(dpll_reg);
-
- /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
-
- /* reset M1, N1 & P1 */
- REG_WRITE(fp_reg, 0);
- dpll &= ~MDFLD_P1_MASK;
- REG_WRITE(dpll_reg, dpll);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
- }
-
- /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
- if (dpll & MDFLD_PWR_GATE_EN) {
- dpll &= ~MDFLD_PWR_GATE_EN;
- REG_WRITE(dpll_reg, dpll);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
- }
-
- dpll = 0;
-
-#if 0 /* FIXME revisit later */
- if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19) || (ksel == KSEL_BYPASS_25)) {
- dpll &= ~MDFLD_INPUT_REF_SEL;
- } else if (ksel == KSEL_BYPASS_83_100) {
- dpll |= MDFLD_INPUT_REF_SEL;
- }
-#endif /* FIXME revisit later */
-
- if (is_hdmi)
- dpll |= MDFLD_VCO_SEL;
-
- fp = (clk_n / 2) << 16;
- fp |= m_conv;
-
- /* compute bitmask from p1 value */
- dpll |= (1 << (clock.p1 - 2)) << 17;
-
-#if 0 /* 1080p30 & 720p */
- dpll = 0x00050000;
- fp = 0x000001be;
-#endif
-#if 0 /* 480p */
- dpll = 0x02010000;
- fp = 0x000000d2;
-#endif
- } else {
-#if 0 /*DBI_TPO_480x864*/
- dpll = 0x00020000;
- fp = 0x00000156;
-#endif /* DBI_TPO_480x864 */ /* get from spec. */
-
- dpll = 0x00800000;
- fp = 0x000000c1;
-}
-
- REG_WRITE(fp_reg, fp);
- REG_WRITE(dpll_reg, dpll);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
-
- dpll |= DPLL_VCO_ENABLE;
- REG_WRITE(dpll_reg, dpll);
- REG_READ(dpll_reg);
-
- /* wait for DSI PLL to lock */
- while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
- udelay(150);
- timeout ++;
- }
-
- if (is_mipi)
- goto mrst_crtc_mode_set_exit;
-
- dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi);
-
- REG_WRITE(pipeconf_reg, *pipeconf);
- REG_READ(pipeconf_reg);
-
- /* Wait for for the pipe enable to take effect. */
-//FIXME_JLIU7 HDMI mrstWaitForPipeEnable(dev);
-
- REG_WRITE(dspcntr_reg, *dspcntr);
- psb_intel_wait_for_vblank(dev);
-
-mrst_crtc_mode_set_exit:
-
- gma_power_end(dev);
-
- return 0;
-}
-
-static void mdfld_crtc_prepare(struct drm_crtc *crtc)
-{
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void mdfld_crtc_commit(struct drm_crtc *crtc)
-{
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return true;
-}
-
-const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
- .dpms = mdfld_crtc_dpms,
- .mode_fixup = mdfld_crtc_mode_fixup,
- .mode_set = mdfld_crtc_mode_set,
- .mode_set_base = mdfld__intel_pipe_set_base,
- .prepare = mdfld_crtc_prepare,
- .commit = mdfld_crtc_commit,
-};
diff --git a/drivers/staging/gma500/mdfld_msic.h b/drivers/staging/gma500/mdfld_msic.h
deleted file mode 100644
index a7ad65472491..000000000000
--- a/drivers/staging/gma500/mdfld_msic.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jim Liu
- */
-
-#define MSIC_PCI_DEVICE_ID 0x831
-
-int msic_regsiter_driver(void);
-int msic_unregister_driver(void);
-extern void hpd_notify_um(void);
diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c
deleted file mode 100644
index eabf53d58f92..000000000000
--- a/drivers/staging/gma500/mdfld_output.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
-*/
-
-#include
-#include
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-
-#include "displays/tpo_cmd.h"
-#include "displays/tpo_vid.h"
-#include "displays/tmd_cmd.h"
-#include "displays/tmd_vid.h"
-#include "displays/pyr_cmd.h"
-#include "displays/pyr_vid.h"
-/* #include "displays/hdmi.h" */
-
-static int mdfld_dual_mipi;
-static int mdfld_hdmi;
-static int mdfld_dpu;
-
-module_param(mdfld_dual_mipi, int, 0600);
-MODULE_PARM_DESC(mdfld_dual_mipi, "Enable dual MIPI configuration");
-module_param(mdfld_hdmi, int, 0600);
-MODULE_PARM_DESC(mdfld_hdmi, "Enable Medfield HDMI");
-module_param(mdfld_dpu, int, 0600);
-MODULE_PARM_DESC(mdfld_dpu, "Enable Medfield DPU");
-
-/* For now a single type per device is all we cope with */
-int mdfld_get_panel_type(struct drm_device *dev, int pipe)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- return dev_priv->panel_id;
-}
-
-int mdfld_panel_dpi(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- switch (dev_priv->panel_id) {
- case TMD_VID:
- case TPO_VID:
- case PYR_VID:
- return true;
- case TMD_CMD:
- case TPO_CMD:
- case PYR_CMD:
- default:
- return false;
- }
-}
-
-static int init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
-{
- struct panel_funcs *p_cmd_funcs;
- struct panel_funcs *p_vid_funcs;
-
- /* Oh boy ... FIXME */
- p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
- if (p_cmd_funcs == NULL)
- return -ENODEV;
- p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
- if (p_vid_funcs == NULL) {
- kfree(p_cmd_funcs);
- return -ENODEV;
- }
-
- switch (p_type) {
- case TPO_CMD:
- tpo_cmd_init(dev, p_cmd_funcs);
- mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
- break;
- case TPO_VID:
- tpo_vid_init(dev, p_vid_funcs);
- mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
- break;
- case TMD_CMD:
- /*tmd_cmd_init(dev, p_cmd_funcs); */
- mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
- break;
- case TMD_VID:
- tmd_vid_init(dev, p_vid_funcs);
- mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
- break;
- case PYR_CMD:
- pyr_cmd_init(dev, p_cmd_funcs);
- mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
- break;
- case PYR_VID:
- mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
- break;
- case TPO: /* TPO panel supports both cmd & vid interfaces */
- tpo_cmd_init(dev, p_cmd_funcs);
- tpo_vid_init(dev, p_vid_funcs);
- mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs,
- p_vid_funcs);
- break;
- case TMD:
- break;
- case PYR:
- break;
-#if 0
- case HDMI:
- dev_dbg(dev->dev, "Initializing HDMI");
- mdfld_hdmi_init(dev, &dev_priv->mode_dev);
- break;
-#endif
- default:
- dev_err(dev->dev, "Unsupported interface %d", p_type);
- return -ENODEV;
- }
- return 0;
-}
-
-int mdfld_output_init(struct drm_device *dev)
-{
- int type;
-
- /* MIPI panel 1 */
- type = mdfld_get_panel_type(dev, 0);
- dev_info(dev->dev, "panel 1: type is %d\n", type);
- init_panel(dev, 0, type);
-
- if (mdfld_dual_mipi) {
- /* MIPI panel 2 */
- type = mdfld_get_panel_type(dev, 2);
- dev_info(dev->dev, "panel 2: type is %d\n", type);
- init_panel(dev, 2, type);
- }
- if (mdfld_hdmi)
- /* HDMI panel */
- init_panel(dev, 0, HDMI);
- return 0;
-}
-
-void mdfld_output_setup(struct drm_device *dev)
-{
- /* FIXME: this is not the right place for this stuff ! */
- if (IS_MFLD(dev)) {
- if (mdfld_dpu)
- mdfld_dbi_dpu_init(dev);
- else
- mdfld_dbi_dsr_init(dev);
- }
-}
diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h
deleted file mode 100644
index daf33e7df9d5..000000000000
--- a/drivers/staging/gma500/mdfld_output.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
-*/
-
-#ifndef MDFLD_OUTPUT_H
-#define MDFLD_OUTPUT_H
-
-int mdfld_output_init(struct drm_device *dev);
-int mdfld_panel_dpi(struct drm_device *dev);
-int mdfld_get_panel_type(struct drm_device *dev, int pipe);
-void mdfld_disable_crtc (struct drm_device *dev, int pipe);
-
-extern const struct drm_crtc_helper_funcs mdfld_helper_funcs;
-extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
-
-extern void mdfld_output_setup(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/mdfld_pyr_cmd.c b/drivers/staging/gma500/mdfld_pyr_cmd.c
deleted file mode 100644
index 523f2d8fe4f1..000000000000
--- a/drivers/staging/gma500/mdfld_pyr_cmd.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
-*/
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/pyr_cmd.h"
-
-static struct drm_display_mode *pyr_cmd_get_config_mode(struct drm_device *dev)
-{
- struct drm_display_mode *mode;
-
- mode = kzalloc(sizeof(*mode), GFP_KERNEL);
- if (!mode) {
- dev_err(dev->dev, "Out of memory\n");
- return NULL;
- }
-
- dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
- dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
- dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
- dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
- dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
- dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
- dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
- dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
- dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-
- mode->hdisplay = 480;
- mode->vdisplay = 864;
- mode->hsync_start = 487;
- mode->hsync_end = 490;
- mode->htotal = 499;
- mode->vsync_start = 874;
- mode->vsync_end = 878;
- mode->vtotal = 886;
- mode->clock = 25777;
-
- drm_mode_set_name(mode);
- drm_mode_set_crtcinfo(mode, 0);
-
- mode->type |= DRM_MODE_TYPE_PREFERRED;
-
- return mode;
-}
-
-static bool pyr_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct drm_device *dev = encoder->dev;
- struct drm_display_mode *fixed_mode = pyr_cmd_get_config_mode(dev);
-
- if (fixed_mode) {
- adjusted_mode->hdisplay = fixed_mode->hdisplay;
- adjusted_mode->hsync_start = fixed_mode->hsync_start;
- adjusted_mode->hsync_end = fixed_mode->hsync_end;
- adjusted_mode->htotal = fixed_mode->htotal;
- adjusted_mode->vdisplay = fixed_mode->vdisplay;
- adjusted_mode->vsync_start = fixed_mode->vsync_start;
- adjusted_mode->vsync_end = fixed_mode->vsync_end;
- adjusted_mode->vtotal = fixed_mode->vtotal;
- adjusted_mode->clock = fixed_mode->clock;
- drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
- kfree(fixed_mode);
- }
- return true;
-}
-
-static void pyr_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
-{
- int ret = 0;
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct drm_device *dev = encoder->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 reg_offset = 0;
- int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
-
- dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n", pipe,
- on ? "On" : "Off",
- dbi_output->dbi_panel_on ? "True" : "False");
-
- if (pipe == 2) {
- if (on)
- dev_priv->dual_mipi = true;
- else
- dev_priv->dual_mipi = false;
-
- reg_offset = MIPIC_REG_OFFSET;
- } else {
- if (!on)
- dev_priv->dual_mipi = false;
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
-
- if (on) {
- if (dbi_output->dbi_panel_on)
- goto out_err;
-
- ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
- if (ret) {
- dev_err(dev->dev, "power on error\n");
- goto out_err;
- }
-
- dbi_output->dbi_panel_on = true;
-
- if (pipe == 2) {
- dev_priv->dbi_panel_on2 = true;
- } else {
- dev_priv->dbi_panel_on = true;
- mdfld_enable_te(dev, 0);
- }
- } else {
- if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
- goto out_err;
-
- dbi_output->dbi_panel_on = false;
- dbi_output->first_boot = false;
-
- if (pipe == 2) {
- dev_priv->dbi_panel_on2 = false;
- mdfld_disable_te(dev, 2);
- } else {
- dev_priv->dbi_panel_on = false;
- mdfld_disable_te(dev, 0);
-
- if (dev_priv->dbi_panel_on2)
- mdfld_enable_te(dev, 2);
- }
-
- ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
- if (ret) {
- dev_err(dev->dev, "power on error\n");
- goto out_err;
- }
- }
-
-out_err:
- gma_power_end(dev);
-
- if (ret)
- dev_err(dev->dev, "failed\n");
-}
-
-static void pyr_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
- int pipe)
-{
- struct drm_device *dev = dsi_config->dev;
- u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
- int lane_count = dsi_config->lane_count;
- u32 val = 0;
-
- dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
-
- /* Un-ready device */
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
- /* Init dsi adapter before kicking off */
- REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
- /* TODO: figure out how to setup these registers */
- REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c600F);
- REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
- 0x000a0014);
- REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
- REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
- /* Enable all interrupts */
- REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
- /* Max value: 20 clock cycles of txclkesc */
- REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
- /* Min 21 txclkesc, max: ffffh */
- REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
- /* Min: 7d0 max: 4e20 */
- REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
- /* Set up func_prg */
- val |= lane_count;
- val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
- val |= DSI_DBI_COLOR_FORMAT_OPTION2;
- REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
- REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
- REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
- /* De-assert dbi_stall when half of DBI FIFO is empty */
- /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
-
- REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
- REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000002);
- REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
- REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-static void pyr_dsi_dbi_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- int ret = 0;
- struct drm_device *dev = encoder->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dsi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct mdfld_dsi_config *dsi_config =
- mdfld_dsi_encoder_get_config(dsi_encoder);
- struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
- int pipe = dsi_connector->pipe;
- u8 param = 0;
-
- /* Regs */
- u32 mipi_reg = MIPI;
- u32 dspcntr_reg = DSPACNTR;
- u32 pipeconf_reg = PIPEACONF;
- u32 reg_offset = 0;
-
- /* Values */
- u32 dspcntr_val = dev_priv->dspcntr;
- u32 pipeconf_val = dev_priv->pipeconf;
- u32 h_active_area = mode->hdisplay;
- u32 v_active_area = mode->vdisplay;
- u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
- TE_TRIGGER_GPIO_PIN);
-
- dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
-
- dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
- dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
-
- if (pipe == 2) {
- mipi_reg = MIPI_C;
- dspcntr_reg = DSPCCNTR;
- pipeconf_reg = PIPECCONF;
-
- reg_offset = MIPIC_REG_OFFSET;
-
- dspcntr_val = dev_priv->dspcntr2;
- pipeconf_val = dev_priv->pipeconf2;
- } else {
- mipi_val |= 0x2; /* Two lanes for port A and C respectively */
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- /* Set up pipe related registers */
- REG_WRITE(mipi_reg, mipi_val);
- REG_READ(mipi_reg);
-
- pyr_dsi_controller_dbi_init(dsi_config, pipe);
-
- msleep(20);
-
- REG_WRITE(dspcntr_reg, dspcntr_val);
- REG_READ(dspcntr_reg);
-
- /* 20ms delay before sending exit_sleep_mode */
- msleep(20);
-
- /* Send exit_sleep_mode DCS */
- ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL,
- 0, CMD_DATA_SRC_SYSTEM_MEM);
- if (ret) {
- dev_err(dev->dev, "sent exit_sleep_mode faild\n");
- goto out_err;
- }
-
- /*send set_tear_on DCS*/
- ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on,
- ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM);
- if (ret) {
- dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
- goto out_err;
- }
-
- /* Do some init stuff */
- mdfld_dsi_brightness_init(dsi_config, pipe);
- mdfld_dsi_gen_fifo_ready(dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset),
- HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
- REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
- REG_READ(pipeconf_reg);
-
- /* TODO: this looks ugly, try to move it to CRTC mode setting */
- if (pipe == 2)
- dev_priv->pipeconf2 |= PIPEACONF_DSR;
- else
- dev_priv->pipeconf |= PIPEACONF_DSR;
-
- dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg));
-
- ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
- h_active_area - 1, v_active_area - 1);
- if (ret) {
- dev_err(dev->dev, "update area failed\n");
- goto out_err;
- }
-
-out_err:
- gma_power_end(dev);
-
- if (ret)
- dev_err(dev->dev, "mode set failed\n");
- else
- dev_dbg(dev->dev, "mode set done successfully\n");
-}
-
-static void pyr_dsi_dbi_prepare(struct drm_encoder *encoder)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-
- dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
- dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
-
- pyr_dsi_dbi_set_power(encoder, false);
-}
-
-static void pyr_dsi_dbi_commit(struct drm_encoder *encoder)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct drm_device *dev = dbi_output->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_drm_dpu_rect rect;
-
- pyr_dsi_dbi_set_power(encoder, true);
-
- dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
-
- rect.x = rect.y = 0;
- rect.width = 864;
- rect.height = 480;
-
- if (dbi_output->channel_num == 1) {
- dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
- /* If DPU enabled report a fullscreen damage */
- mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
- } else {
- dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
- mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
- }
- dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
-}
-
-static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct drm_device *dev = dbi_output->dev;
-
- dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
-
- if (mode == DRM_MODE_DPMS_ON)
- pyr_dsi_dbi_set_power(encoder, true);
- else
- pyr_dsi_dbi_set_power(encoder, false);
-}
-
-/*
- * Update the DBI MIPI Panel Frame Buffer.
- */
-static void pyr_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
- int pipe)
-{
- struct mdfld_dsi_pkg_sender *sender =
- mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
- struct drm_device *dev = dbi_output->dev;
- struct drm_crtc *crtc = dbi_output->base.base.crtc;
- struct psb_intel_crtc *psb_crtc = (crtc) ?
- to_psb_intel_crtc(crtc) : NULL;
-
- u32 dpll_reg = MRST_DPLL_A;
- u32 dspcntr_reg = DSPACNTR;
- u32 pipeconf_reg = PIPEACONF;
- u32 dsplinoff_reg = DSPALINOFF;
- u32 dspsurf_reg = DSPASURF;
- u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG;
- u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
- u32 reg_offset = 0;
-
- u32 intr_status;
- u32 fifo_stat_reg_val;
- u32 dpll_reg_val;
- u32 dspcntr_reg_val;
- u32 pipeconf_reg_val;
-
- /* If mode setting on-going, back off */
- if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
- (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
- !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
- return;
-
- /*
- * Look for errors here. In particular we're checking for whatever
- * error status might have appeared during the last frame transmit
- * (memory write).
- *
- * Normally, the bits we're testing here would be set infrequently,
- * if at all. However, one panel (at least) returns at least one
- * error bit on most frames. So we've disabled the kernel message
- * for now.
- *
- * Still clear whatever error bits are set, except don't clear the
- * ones that would make the Penwell DSI controller reset if we
- * cleared them.
- */
- intr_status = REG_READ(INTR_STAT_REG);
- if ((intr_status & 0x26FFFFFF) != 0) {
- /* dev_err(dev->dev, "DSI status: 0x%08X\n", intr_status); */
- intr_status &= 0x26F3FFFF;
- REG_WRITE(INTR_STAT_REG, intr_status);
- }
-
- if (pipe == 2) {
- dspcntr_reg = DSPCCNTR;
- pipeconf_reg = PIPECCONF;
- dsplinoff_reg = DSPCLINOFF;
- dspsurf_reg = DSPCSURF;
-
- hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
- gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET,
-
- reg_offset = MIPIC_REG_OFFSET;
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset);
- dpll_reg_val = REG_READ(dpll_reg);
- dspcntr_reg_val = REG_READ(dspcntr_reg);
- pipeconf_reg_val = REG_READ(pipeconf_reg);
-
- if (!(fifo_stat_reg_val & (1 << 27)) ||
- (dpll_reg_val & DPLL_VCO_ENABLE) ||
- !(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) ||
- !(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) {
- goto update_fb_out0;
- }
-
- /* Refresh plane changes */
- REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
- REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
- REG_READ(dspsurf_reg);
-
- mdfld_dsi_send_dcs(sender,
- write_mem_start,
- NULL,
- 0,
- CMD_DATA_SRC_PIPE,
- MDFLD_DSI_SEND_PACKAGE);
-
- /*
- * The idea here is to transmit a Generic Read command after the
- * Write Memory Start/Continue commands finish. This asks for
- * the panel to return an "ACK No Errors," or (if it has errors
- * to report) an Error Report. This allows us to monitor the
- * panel's perception of the health of the DSI.
- */
- mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg,
- HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
- REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0);
-
- dbi_output->dsr_fb_update_done = true;
-update_fb_out0:
- gma_power_end(dev);
-}
-
-/*
- * TODO: will be removed later, should work out display interfaces for power
- */
-void pyr_dsi_adapter_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
- if (!dsi_config || (pipe != 0 && pipe != 2)) {
- WARN_ON(1);
- return;
- }
- pyr_dsi_controller_dbi_init(dsi_config, pipe);
-}
-
-static int pyr_cmd_get_panel_info(struct drm_device *dev, int pipe,
- struct panel_info *pi)
-{
- if (!dev || !pi)
- return -EINVAL;
-
- pi->width_mm = PYR_PANEL_WIDTH;
- pi->height_mm = PYR_PANEL_HEIGHT;
-
- return 0;
-}
-
-/* PYR DBI encoder helper funcs */
-static const struct drm_encoder_helper_funcs pyr_dsi_dbi_helper_funcs = {
- .dpms = pyr_dsi_dbi_dpms,
- .mode_fixup = pyr_dsi_dbi_mode_fixup,
- .prepare = pyr_dsi_dbi_prepare,
- .mode_set = pyr_dsi_dbi_mode_set,
- .commit = pyr_dsi_dbi_commit,
-};
-
-/* PYR DBI encoder funcs */
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
- .destroy = drm_encoder_cleanup,
-};
-
-void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
- p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
- p_funcs->encoder_helper_funcs = &pyr_dsi_dbi_helper_funcs;
- p_funcs->get_config_mode = &pyr_cmd_get_config_mode;
- p_funcs->update_fb = pyr_dsi_dbi_update_fb;
- p_funcs->get_panel_info = pyr_cmd_get_panel_info;
-}
diff --git a/drivers/staging/gma500/mdfld_tmd_vid.c b/drivers/staging/gma500/mdfld_tmd_vid.c
deleted file mode 100644
index affdc09c6769..000000000000
--- a/drivers/staging/gma500/mdfld_tmd_vid.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jim Liu
- * Jackie Li
- * Gideon Eaton
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tmd_vid.h"
-
-/* FIXME: static ? */
-struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev)
-{
- struct drm_display_mode *mode;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
- bool use_gct = false; /*Disable GCT for now*/
-
- mode = kzalloc(sizeof(*mode), GFP_KERNEL);
- if (!mode) {
- dev_err(dev->dev, "Out of memory\n");
- return NULL;
- }
-
- if (use_gct) {
- dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
- mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
- mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
- mode->hsync_start = mode->hdisplay +
- ((ti->hsync_offset_hi << 8) |
- ti->hsync_offset_lo);
- mode->hsync_end = mode->hsync_start +
- ((ti->hsync_pulse_width_hi << 8) |
- ti->hsync_pulse_width_lo);
- mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) |
- ti->hblank_lo);
- mode->vsync_start = \
- mode->vdisplay + ((ti->vsync_offset_hi << 8) |
- ti->vsync_offset_lo);
- mode->vsync_end = \
- mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
- ti->vsync_pulse_width_lo);
- mode->vtotal = mode->vdisplay +
- ((ti->vblank_hi << 8) | ti->vblank_lo);
- mode->clock = ti->pixel_clock * 10;
-
- dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
- dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
- dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
- dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
- dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
- dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
- dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
- dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
- dev_dbg(dev->dev, "clock is %d\n", mode->clock);
- } else {
- mode->hdisplay = 480;
- mode->vdisplay = 854;
- mode->hsync_start = 487;
- mode->hsync_end = 490;
- mode->htotal = 499;
- mode->vsync_start = 861;
- mode->vsync_end = 865;
- mode->vtotal = 873;
- mode->clock = 33264;
- }
- drm_mode_set_name(mode);
- drm_mode_set_crtcinfo(mode, 0);
-
- mode->type |= DRM_MODE_TYPE_PREFERRED;
-
- return mode;
-}
-
-static int tmd_vid_get_panel_info(struct drm_device *dev,
- int pipe,
- struct panel_info *pi)
-{
- if (!dev || !pi)
- return -EINVAL;
-
- pi->width_mm = TMD_PANEL_WIDTH;
- pi->height_mm = TMD_PANEL_HEIGHT;
-
- return 0;
-}
-
-/*
- * mdfld_init_TMD_MIPI - initialise a TMD interface
- * @dsi_config: configuration
- * @pipe: pipe to configure
- *
- * This function is called only by mrst_dsi_mode_set and
- * restore_display_registers. since this function does not
- * acquire the mutex, it is important that the calling function
- * does!
- */
-
-
-static void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config,
- int pipe)
-{
- static u32 tmd_cmd_mcap_off[] = {0x000000b2};
- static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef};
- static u32 tmd_cmd_set_lane_num[] = {0x006360ef};
- static u32 tmd_cmd_pushing_clock0[] = {0x00cc2fef};
- static u32 tmd_cmd_pushing_clock1[] = {0x00dd6eef};
- static u32 tmd_cmd_set_mode[] = {0x000000b3};
- static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef};
- static u32 tmd_cmd_set_column[] = {0x0100002a, 0x000000df};
- static u32 tmd_cmd_set_page[] = {0x0300002b, 0x00000055};
- static u32 tmd_cmd_set_video_mode[] = {0x00000153};
- /*no auto_bl,need add in furture*/
- static u32 tmd_cmd_enable_backlight[] = {0x00005ab4};
- static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd};
-
- struct mdfld_dsi_pkg_sender *sender
- = mdfld_dsi_get_pkg_sender(dsi_config);
-
- DRM_INFO("Enter mdfld init TMD MIPI display.\n");
-
- if (!sender) {
- DRM_ERROR("Cannot get sender\n");
- return;
- }
-
- if (dsi_config->dvr_ic_inited)
- return;
-
- msleep(3);
-
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_mcap_off, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_lane_switch, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_lane_num, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock0, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock1, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_mode, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_sync_pulse_mode, 1, 0);
- mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_column, 2, 0);
- mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_page, 2, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_video_mode, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_backlight, 1, 0);
- mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_backlight_dimming, 1, 0);
-
- dsi_config->dvr_ic_inited = 1;
-}
-
-/* TMD DPI encoder helper funcs */
-static const struct drm_encoder_helper_funcs
- mdfld_tpo_dpi_encoder_helper_funcs = {
- .dpms = mdfld_dsi_dpi_dpms,
- .mode_fixup = mdfld_dsi_dpi_mode_fixup,
- .prepare = mdfld_dsi_dpi_prepare,
- .mode_set = mdfld_dsi_dpi_mode_set,
- .commit = mdfld_dsi_dpi_commit,
-};
-
-/* TMD DPI encoder funcs */
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
- .destroy = drm_encoder_cleanup,
-};
-
-void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
- if (!dev || !p_funcs) {
- dev_err(dev->dev, "Invalid parameters\n");
- return;
- }
-
- p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
- p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
- p_funcs->get_config_mode = &tmd_vid_get_config_mode;
- p_funcs->update_fb = NULL;
- p_funcs->get_panel_info = tmd_vid_get_panel_info;
- p_funcs->reset = mdfld_dsi_panel_reset;
- p_funcs->drv_ic_init = mdfld_dsi_tmd_drv_ic_init;
-}
diff --git a/drivers/staging/gma500/mdfld_tpo_cmd.c b/drivers/staging/gma500/mdfld_tpo_cmd.c
deleted file mode 100644
index c7f7c9c19bc1..000000000000
--- a/drivers/staging/gma500/mdfld_tpo_cmd.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (c) 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton
- * Scott Rowe
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tpo_cmd.h"
-
-static struct drm_display_mode *tpo_cmd_get_config_mode(struct drm_device *dev)
-{
- struct drm_display_mode *mode;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
- bool use_gct = false;
-
- mode = kzalloc(sizeof(*mode), GFP_KERNEL);
- if (!mode)
- return NULL;
-
- if (use_gct) {
- dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
- mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
- mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
- mode->hsync_start = mode->hdisplay + \
- ((ti->hsync_offset_hi << 8) | \
- ti->hsync_offset_lo);
- mode->hsync_end = mode->hsync_start + \
- ((ti->hsync_pulse_width_hi << 8) | \
- ti->hsync_pulse_width_lo);
- mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
- ti->hblank_lo);
- mode->vsync_start = \
- mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
- ti->vsync_offset_lo);
- mode->vsync_end = \
- mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
- ti->vsync_pulse_width_lo);
- mode->vtotal = mode->vdisplay + \
- ((ti->vblank_hi << 8) | ti->vblank_lo);
- mode->clock = ti->pixel_clock * 10;
-
- dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
- dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
- dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
- dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
- dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
- dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
- dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
- dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
- dev_dbg(dev->dev, "clock is %d\n", mode->clock);
- } else {
- mode->hdisplay = 864;
- mode->vdisplay = 480;
- mode->hsync_start = 872;
- mode->hsync_end = 876;
- mode->htotal = 884;
- mode->vsync_start = 482;
- mode->vsync_end = 494;
- mode->vtotal = 486;
- mode->clock = 25777;
- }
-
- drm_mode_set_name(mode);
- drm_mode_set_crtcinfo(mode, 0);
-
- mode->type |= DRM_MODE_TYPE_PREFERRED;
-
- return mode;
-}
-
-static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct drm_device *dev = encoder->dev;
- struct drm_display_mode *fixed_mode = tpo_cmd_get_config_mode(dev);
-
- if (fixed_mode) {
- adjusted_mode->hdisplay = fixed_mode->hdisplay;
- adjusted_mode->hsync_start = fixed_mode->hsync_start;
- adjusted_mode->hsync_end = fixed_mode->hsync_end;
- adjusted_mode->htotal = fixed_mode->htotal;
- adjusted_mode->vdisplay = fixed_mode->vdisplay;
- adjusted_mode->vsync_start = fixed_mode->vsync_start;
- adjusted_mode->vsync_end = fixed_mode->vsync_end;
- adjusted_mode->vtotal = fixed_mode->vtotal;
- adjusted_mode->clock = fixed_mode->clock;
- drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
- kfree(fixed_mode);
- }
- return true;
-}
-
-static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
-{
- int ret = 0;
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct mdfld_dsi_config *dsi_config =
- mdfld_dsi_encoder_get_config(dsi_encoder);
- struct mdfld_dsi_pkg_sender *sender =
- mdfld_dsi_encoder_get_pkg_sender(dsi_encoder);
- struct drm_device *dev = encoder->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 reg_offset = 0;
- int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
- u32 data = 0;
-
- dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
- pipe, on ? "On" : "Off",
- dbi_output->dbi_panel_on ? "True" : "False");
-
- if (pipe == 2) {
- if (on)
- dev_priv->dual_mipi = true;
- else
- dev_priv->dual_mipi = false;
- reg_offset = MIPIC_REG_OFFSET;
- } else {
- if (!on)
- dev_priv->dual_mipi = false;
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- if (on) {
- if (dbi_output->dbi_panel_on)
- goto out_err;
-
- ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
- if (ret) {
- dev_err(dev->dev, "power on error\n");
- goto out_err;
- }
-
- dbi_output->dbi_panel_on = true;
-
- if (pipe == 2)
- dev_priv->dbi_panel_on2 = true;
- else
- dev_priv->dbi_panel_on = true;
- mdfld_enable_te(dev, pipe);
- } else {
- if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
- goto out_err;
-
- dbi_output->dbi_panel_on = false;
- dbi_output->first_boot = false;
-
- if (pipe == 2)
- dev_priv->dbi_panel_on2 = false;
- else
- dev_priv->dbi_panel_on = false;
-
- mdfld_disable_te(dev, pipe);
-
- ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
- if (ret) {
- dev_err(dev->dev, "power on error\n");
- goto out_err;
- }
- }
-
- /*
- * FIXME: this is a WA for TPO panel crash on DPMS on & off around
- * 83 times. the root cause of this issue is that Booster in
- * drvIC crashed. Add this WA so that we can resume the driver IC
- * once we found that booster has a fault
- */
- mdfld_dsi_get_power_mode(dsi_config,
- &data,
- MDFLD_DSI_HS_TRANSMISSION);
-
- if (on && data && !(data & (1 << 7))) {
- /* Soft reset */
- mdfld_dsi_send_dcs(sender,
- DCS_SOFT_RESET,
- NULL,
- 0,
- CMD_DATA_SRC_PIPE,
- MDFLD_DSI_SEND_PACKAGE);
-
- /* Init drvIC */
- if (dbi_output->p_funcs->drv_ic_init)
- dbi_output->p_funcs->drv_ic_init(dsi_config,
- pipe);
- }
-
-out_err:
- gma_power_end(dev);
- if (ret)
- dev_err(dev->dev, "failed\n");
-}
-
-
-static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- int ret = 0;
- struct drm_device *dev = encoder->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dsi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct mdfld_dsi_config *dsi_config =
- mdfld_dsi_encoder_get_config(dsi_encoder);
- struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
- int pipe = dsi_connector->pipe;
- u8 param = 0;
-
- /* Regs */
- u32 mipi_reg = MIPI;
- u32 dspcntr_reg = DSPACNTR;
- u32 pipeconf_reg = PIPEACONF;
- u32 reg_offset = 0;
-
- /* Values */
- u32 dspcntr_val = dev_priv->dspcntr;
- u32 pipeconf_val = dev_priv->pipeconf;
- u32 h_active_area = mode->hdisplay;
- u32 v_active_area = mode->vdisplay;
- u32 mipi_val;
-
- mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
- TE_TRIGGER_GPIO_PIN);
-
- dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
-
- dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
- dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
-
- if (pipe == 2) {
- mipi_reg = MIPI_C;
- dspcntr_reg = DSPCCNTR;
- pipeconf_reg = PIPECCONF;
-
- reg_offset = MIPIC_REG_OFFSET;
-
- dspcntr_val = dev_priv->dspcntr2;
- pipeconf_val = dev_priv->pipeconf2;
- } else {
- mipi_val |= 0x2; /*two lanes for port A and C respectively*/
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- REG_WRITE(dspcntr_reg, dspcntr_val);
- REG_READ(dspcntr_reg);
-
- /* 20ms delay before sending exit_sleep_mode */
- msleep(20);
-
- /* Send exit_sleep_mode DCS */
- ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_EXIT_SLEEP_MODE,
- NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
- if (ret) {
- dev_err(dev->dev, "sent exit_sleep_mode faild\n");
- goto out_err;
- }
-
- /* Send set_tear_on DCS */
- ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON,
- ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM);
- if (ret) {
- dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
- goto out_err;
- }
-
- /* Do some init stuff */
- REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
- REG_READ(pipeconf_reg);
-
- /* TODO: this looks ugly, try to move it to CRTC mode setting*/
- if (pipe == 2)
- dev_priv->pipeconf2 |= PIPEACONF_DSR;
- else
- dev_priv->pipeconf |= PIPEACONF_DSR;
-
- dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg));
-
- ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
- h_active_area - 1, v_active_area - 1);
- if (ret) {
- dev_err(dev->dev, "update area failed\n");
- goto out_err;
- }
-
-out_err:
- gma_power_end(dev);
-
- if (ret)
- dev_err(dev->dev, "mode set failed\n");
-}
-
-static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output
- = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-
- dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
- dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
-
- mdfld_dsi_dbi_set_power(encoder, false);
-}
-
-static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output =
- MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct drm_device *dev = dbi_output->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct psb_drm_dpu_rect rect;
-
- mdfld_dsi_dbi_set_power(encoder, true);
- dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
-
- rect.x = rect.y = 0;
- rect.width = 864;
- rect.height = 480;
-
- if (dbi_output->channel_num == 1) {
- dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
- /*if dpu enabled report a fullscreen damage*/
- mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
- } else {
- dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
- mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
- }
- dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
-}
-
-static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
-{
- struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
- struct mdfld_dsi_dbi_output *dbi_output
- = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
- struct drm_device *dev = dbi_output->dev;
- struct drm_psb_private *dev_priv = dev->dev_private;
- static bool bdispoff;
-
- dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
-
- if (mode == DRM_MODE_DPMS_ON) {
- /*
- * FIXME: in case I am wrong!
- * we don't need to exit dsr here to wake up plane/pipe/pll
- * if everything goes right, hw_begin will resume them all
- * during set_power.
- */
- if (bdispoff /* FIXME && gbgfxsuspended */) {
- mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D);
- bdispoff = false;
- dev_priv->dispstatus = true;
- }
-
- mdfld_dsi_dbi_set_power(encoder, true);
- /* FIXME if (gbgfxsuspended)
- gbgfxsuspended = false; */
- } else {
- /*
- * I am not sure whether this is the perfect place to
- * turn rpm on since we still have a lot of CRTC turnning
- * on work to do.
- */
- bdispoff = true;
- dev_priv->dispstatus = false;
- mdfld_dsi_dbi_set_power(encoder, false);
- }
-}
-
-
-/*
- * Update the DBI MIPI Panel Frame Buffer.
- */
-static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
- int pipe)
-{
- struct mdfld_dsi_pkg_sender *sender =
- mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
- struct drm_device *dev = dbi_output->dev;
- struct drm_crtc *crtc = dbi_output->base.base.crtc;
- struct psb_intel_crtc *psb_crtc = (crtc) ?
- to_psb_intel_crtc(crtc) : NULL;
- u32 dpll_reg = MRST_DPLL_A;
- u32 dspcntr_reg = DSPACNTR;
- u32 pipeconf_reg = PIPEACONF;
- u32 dsplinoff_reg = DSPALINOFF;
- u32 dspsurf_reg = DSPASURF;
- u32 reg_offset = 0;
-
- /* If mode setting on-going, back off */
- if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
- (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
- !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
- return;
-
- if (pipe == 2) {
- dspcntr_reg = DSPCCNTR;
- pipeconf_reg = PIPECCONF;
- dsplinoff_reg = DSPCLINOFF;
- dspsurf_reg = DSPCSURF;
- reg_offset = MIPIC_REG_OFFSET;
- }
-
- if (!gma_power_begin(dev, true)) {
- dev_err(dev->dev, "hw begin failed\n");
- return;
- }
-
- /* Check DBI FIFO status */
- if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
- !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
- !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
- goto update_fb_out0;
-
- /* Refresh plane changes */
- REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
- REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
- REG_READ(dspsurf_reg);
-
- mdfld_dsi_send_dcs(sender,
- DCS_WRITE_MEM_START,
- NULL,
- 0,
- CMD_DATA_SRC_PIPE,
- MDFLD_DSI_SEND_PACKAGE);
-
- dbi_output->dsr_fb_update_done = true;
-update_fb_out0:
- gma_power_end(dev);
-}
-
-static int tpo_cmd_get_panel_info(struct drm_device *dev,
- int pipe,
- struct panel_info *pi)
-{
- if (!dev || !pi)
- return -EINVAL;
-
- pi->width_mm = TPO_PANEL_WIDTH;
- pi->height_mm = TPO_PANEL_HEIGHT;
-
- return 0;
-}
-
-
-/* TPO DBI encoder helper funcs */
-static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
- .dpms = mdfld_dsi_dbi_dpms,
- .mode_fixup = mdfld_dsi_dbi_mode_fixup,
- .prepare = mdfld_dsi_dbi_prepare,
- .mode_set = mdfld_dsi_dbi_mode_set,
- .commit = mdfld_dsi_dbi_commit,
-};
-
-/* TPO DBI encoder funcs */
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
- .destroy = drm_encoder_cleanup,
-};
-
-void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
- p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
- p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs;
- p_funcs->get_config_mode = &tpo_cmd_get_config_mode;
- p_funcs->update_fb = mdfld_dsi_dbi_update_fb;
- p_funcs->get_panel_info = tpo_cmd_get_panel_info;
- p_funcs->reset = mdfld_dsi_panel_reset;
- p_funcs->drv_ic_init = mdfld_dsi_brightness_init;
-}
diff --git a/drivers/staging/gma500/mdfld_tpo_vid.c b/drivers/staging/gma500/mdfld_tpo_vid.c
deleted file mode 100644
index 954901751760..000000000000
--- a/drivers/staging/gma500/mdfld_tpo_vid.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu
- * Jackie Li
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tpo_vid.h"
-
-static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev)
-{
- struct drm_display_mode *mode;
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
- bool use_gct = false;
-
- mode = kzalloc(sizeof(*mode), GFP_KERNEL);
- if (!mode) {
- dev_err(dev->dev, "out of memory\n");
- return NULL;
- }
-
- if (use_gct) {
- mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
- mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
- mode->hsync_start = mode->hdisplay + \
- ((ti->hsync_offset_hi << 8) | \
- ti->hsync_offset_lo);
- mode->hsync_end = mode->hsync_start + \
- ((ti->hsync_pulse_width_hi << 8) | \
- ti->hsync_pulse_width_lo);
- mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
- ti->hblank_lo);
- mode->vsync_start = \
- mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
- ti->vsync_offset_lo);
- mode->vsync_end = \
- mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
- ti->vsync_pulse_width_lo);
- mode->vtotal = mode->vdisplay + \
- ((ti->vblank_hi << 8) | ti->vblank_lo);
- mode->clock = ti->pixel_clock * 10;
-
- dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
- dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
- dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
- dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
- dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
- dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
- dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
- dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
- dev_dbg(dev->dev, "clock is %d\n", mode->clock);
- } else {
- mode->hdisplay = 864;
- mode->vdisplay = 480;
- mode->hsync_start = 873;
- mode->hsync_end = 876;
- mode->htotal = 887;
- mode->vsync_start = 487;
- mode->vsync_end = 490;
- mode->vtotal = 499;
- mode->clock = 33264;
- }
-
- drm_mode_set_name(mode);
- drm_mode_set_crtcinfo(mode, 0);
-
- mode->type |= DRM_MODE_TYPE_PREFERRED;
-
- return mode;
-}
-
-static int tpo_vid_get_panel_info(struct drm_device *dev,
- int pipe,
- struct panel_info *pi)
-{
- if (!dev || !pi)
- return -EINVAL;
-
- pi->width_mm = TPO_PANEL_WIDTH;
- pi->height_mm = TPO_PANEL_HEIGHT;
-
- return 0;
-}
-
-/*TPO DPI encoder helper funcs*/
-static const struct drm_encoder_helper_funcs
- mdfld_tpo_dpi_encoder_helper_funcs = {
- .dpms = mdfld_dsi_dpi_dpms,
- .mode_fixup = mdfld_dsi_dpi_mode_fixup,
- .prepare = mdfld_dsi_dpi_prepare,
- .mode_set = mdfld_dsi_dpi_mode_set,
- .commit = mdfld_dsi_dpi_commit,
-};
-
-/*TPO DPI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
- .destroy = drm_encoder_cleanup,
-};
-
-void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
- if (!dev || !p_funcs) {
- dev_err(dev->dev, "tpo_vid_init: Invalid parameters\n");
- return;
- }
-
- p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
- p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
- p_funcs->get_config_mode = &tpo_vid_get_config_mode;
- p_funcs->update_fb = NULL;
- p_funcs->get_panel_info = tpo_vid_get_panel_info;
-}
diff --git a/drivers/staging/gma500/medfield.h b/drivers/staging/gma500/medfield.h
deleted file mode 100644
index 09e9687431f1..000000000000
--- a/drivers/staging/gma500/medfield.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright © 2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/* Medfield DSI controller registers */
-
-#define MIPIA_DEVICE_READY_REG 0xb000
-#define MIPIA_INTR_STAT_REG 0xb004
-#define MIPIA_INTR_EN_REG 0xb008
-#define MIPIA_DSI_FUNC_PRG_REG 0xb00c
-#define MIPIA_HS_TX_TIMEOUT_REG 0xb010
-#define MIPIA_LP_RX_TIMEOUT_REG 0xb014
-#define MIPIA_TURN_AROUND_TIMEOUT_REG 0xb018
-#define MIPIA_DEVICE_RESET_TIMER_REG 0xb01c
-#define MIPIA_DPI_RESOLUTION_REG 0xb020
-#define MIPIA_DBI_FIFO_THROTTLE_REG 0xb024
-#define MIPIA_HSYNC_COUNT_REG 0xb028
-#define MIPIA_HBP_COUNT_REG 0xb02c
-#define MIPIA_HFP_COUNT_REG 0xb030
-#define MIPIA_HACTIVE_COUNT_REG 0xb034
-#define MIPIA_VSYNC_COUNT_REG 0xb038
-#define MIPIA_VBP_COUNT_REG 0xb03c
-#define MIPIA_VFP_COUNT_REG 0xb040
-#define MIPIA_HIGH_LOW_SWITCH_COUNT_REG 0xb044
-#define MIPIA_DPI_CONTROL_REG 0xb048
-#define MIPIA_DPI_DATA_REG 0xb04c
-#define MIPIA_INIT_COUNT_REG 0xb050
-#define MIPIA_MAX_RETURN_PACK_SIZE_REG 0xb054
-#define MIPIA_VIDEO_MODE_FORMAT_REG 0xb058
-#define MIPIA_EOT_DISABLE_REG 0xb05c
-#define MIPIA_LP_BYTECLK_REG 0xb060
-#define MIPIA_LP_GEN_DATA_REG 0xb064
-#define MIPIA_HS_GEN_DATA_REG 0xb068
-#define MIPIA_LP_GEN_CTRL_REG 0xb06c
-#define MIPIA_HS_GEN_CTRL_REG 0xb070
-#define MIPIA_GEN_FIFO_STAT_REG 0xb074
-#define MIPIA_HS_LS_DBI_ENABLE_REG 0xb078
-#define MIPIA_DPHY_PARAM_REG 0xb080
-#define MIPIA_DBI_BW_CTRL_REG 0xb084
-#define MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG 0xb088
-
-#define DSI_DEVICE_READY (0x1)
-#define DSI_POWER_STATE_ULPS_ENTER (0x2 << 1)
-#define DSI_POWER_STATE_ULPS_EXIT (0x1 << 1)
-#define DSI_POWER_STATE_ULPS_OFFSET (0x1)
-
-
-#define DSI_ONE_DATA_LANE (0x1)
-#define DSI_TWO_DATA_LANE (0x2)
-#define DSI_THREE_DATA_LANE (0X3)
-#define DSI_FOUR_DATA_LANE (0x4)
-#define DSI_DPI_VIRT_CHANNEL_OFFSET (0x3)
-#define DSI_DBI_VIRT_CHANNEL_OFFSET (0x5)
-#define DSI_DPI_COLOR_FORMAT_RGB565 (0x01 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB666 (0x02 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK (0x03 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB888 (0x04 << 7)
-#define DSI_DBI_COLOR_FORMAT_OPTION2 (0x05 << 13)
-
-#define DSI_INTR_STATE_RXSOTERROR 1
-
-#define DSI_INTR_STATE_SPL_PKG_SENT (1 << 30)
-#define DSI_INTR_STATE_TE (1 << 31)
-
-#define DSI_HS_TX_TIMEOUT_MASK (0xffffff)
-
-#define DSI_LP_RX_TIMEOUT_MASK (0xffffff)
-
-#define DSI_TURN_AROUND_TIMEOUT_MASK (0x3f)
-
-#define DSI_RESET_TIMER_MASK (0xffff)
-
-#define DSI_DBI_FIFO_WM_HALF (0x0)
-#define DSI_DBI_FIFO_WM_QUARTER (0x1)
-#define DSI_DBI_FIFO_WM_LOW (0x2)
-
-#define DSI_DPI_TIMING_MASK (0xffff)
-
-#define DSI_INIT_TIMER_MASK (0xffff)
-
-#define DSI_DBI_RETURN_PACK_SIZE_MASK (0x3ff)
-
-#define DSI_LP_BYTECLK_MASK (0x0ffff)
-
-#define DSI_HS_CTRL_GEN_SHORT_W0 (0x03)
-#define DSI_HS_CTRL_GEN_SHORT_W1 (0x13)
-#define DSI_HS_CTRL_GEN_SHORT_W2 (0x23)
-#define DSI_HS_CTRL_GEN_R0 (0x04)
-#define DSI_HS_CTRL_GEN_R1 (0x14)
-#define DSI_HS_CTRL_GEN_R2 (0x24)
-#define DSI_HS_CTRL_GEN_LONG_W (0x29)
-#define DSI_HS_CTRL_MCS_SHORT_W0 (0x05)
-#define DSI_HS_CTRL_MCS_SHORT_W1 (0x15)
-#define DSI_HS_CTRL_MCS_R0 (0x06)
-#define DSI_HS_CTRL_MCS_LONG_W (0x39)
-#define DSI_HS_CTRL_VC_OFFSET (0x06)
-#define DSI_HS_CTRL_WC_OFFSET (0x08)
-
-#define DSI_FIFO_GEN_HS_DATA_FULL (1 << 0)
-#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY (1 << 1)
-#define DSI_FIFO_GEN_HS_DATA_EMPTY (1 << 2)
-#define DSI_FIFO_GEN_LP_DATA_FULL (1 << 8)
-#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY (1 << 9)
-#define DSI_FIFO_GEN_LP_DATA_EMPTY (1 << 10)
-#define DSI_FIFO_GEN_HS_CTRL_FULL (1 << 16)
-#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY (1 << 17)
-#define DSI_FIFO_GEN_HS_CTRL_EMPTY (1 << 18)
-#define DSI_FIFO_GEN_LP_CTRL_FULL (1 << 24)
-#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY (1 << 25)
-#define DSI_FIFO_GEN_LP_CTRL_EMPTY (1 << 26)
-#define DSI_FIFO_DBI_EMPTY (1 << 27)
-#define DSI_FIFO_DPI_EMPTY (1 << 28)
-
-#define DSI_DBI_HS_LP_SWITCH_MASK (0x1)
-
-#define DSI_HS_LP_SWITCH_COUNTER_OFFSET (0x0)
-#define DSI_LP_HS_SWITCH_COUNTER_OFFSET (0x16)
-
-#define DSI_DPI_CTRL_HS_SHUTDOWN (0x00000001)
-#define DSI_DPI_CTRL_HS_TURN_ON (0x00000002)
-
-/* Medfield DSI adapter registers */
-#define MIPIA_CONTROL_REG 0xb104
-#define MIPIA_DATA_ADD_REG 0xb108
-#define MIPIA_DATA_LEN_REG 0xb10c
-#define MIPIA_CMD_ADD_REG 0xb110
-#define MIPIA_CMD_LEN_REG 0xb114
-
-/*dsi power modes*/
-#define DSI_POWER_MODE_DISPLAY_ON (1 << 2)
-#define DSI_POWER_MODE_NORMAL_ON (1 << 3)
-#define DSI_POWER_MODE_SLEEP_OUT (1 << 4)
-#define DSI_POWER_MODE_PARTIAL_ON (1 << 5)
-#define DSI_POWER_MODE_IDLE_ON (1 << 6)
-
-enum {
- MDFLD_DSI_ENCODER_DBI = 0,
- MDFLD_DSI_ENCODER_DPI,
-};
-
-enum {
- MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1,
- MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2,
- MDFLD_DSI_VIDEO_BURST_MODE = 3,
-};
-
-#define DSI_DPI_COMPLETE_LAST_LINE (1 << 2)
-#define DSI_DPI_DISABLE_BTA (1 << 3)
-/* Panel types */
-enum {
- TPO_CMD,
- TPO_VID,
- TMD_CMD,
- TMD_VID,
- PYR_CMD,
- PYR_VID,
- TPO,
- TMD,
- PYR,
- HDMI,
- GCT_DETECT
-};
-
-/* Junk that belongs elsewhere */
-#define TPO_PANEL_WIDTH 84
-#define TPO_PANEL_HEIGHT 46
-#define TMD_PANEL_WIDTH 39
-#define TMD_PANEL_HEIGHT 71
-#define PYR_PANEL_WIDTH 53
-#define PYR_PANEL_HEIGHT 95
-
-/* Panel interface */
-struct panel_info {
- u32 width_mm;
- u32 height_mm;
-};
-
-struct mdfld_dsi_dbi_output;
-
-struct mdfld_dsi_connector_state {
- u32 mipi_ctrl_reg;
-};
-
-struct mdfld_dsi_encoder_state {
-
-};
-
-struct mdfld_dsi_connector {
- /*
- * This is ugly, but I have to use connector in it! :-(
- * FIXME: use drm_connector instead.
- */
- struct psb_intel_output base;
-
- int pipe;
- void *private;
- void *pkg_sender;
-
- /* Connection status */
- enum drm_connector_status status;
-};
-
-struct mdfld_dsi_encoder {
- struct drm_encoder base;
- void *private;
-};
-
-/*
- * DSI config, consists of one DSI connector, two DSI encoders.
- * DRM will pick up on DSI encoder basing on differents configs.
- */
-struct mdfld_dsi_config {
- struct drm_device *dev;
- struct drm_display_mode *fixed_mode;
- struct drm_display_mode *mode;
-
- struct mdfld_dsi_connector *connector;
- struct mdfld_dsi_encoder *encoders[DRM_CONNECTOR_MAX_ENCODER];
- struct mdfld_dsi_encoder *encoder;
-
- int changed;
-
- int bpp;
- int type;
- int lane_count;
- /*Virtual channel number for this encoder*/
- int channel_num;
- /*video mode configure*/
- int video_mode;
-
- int dvr_ic_inited;
-};
-
-#define MDFLD_DSI_CONNECTOR(psb_output) \
- (container_of(psb_output, struct mdfld_dsi_connector, base))
-
-#define MDFLD_DSI_ENCODER(encoder) \
- (container_of(encoder, struct mdfld_dsi_encoder, base))
-
-struct panel_funcs {
- const struct drm_encoder_funcs *encoder_funcs;
- const struct drm_encoder_helper_funcs *encoder_helper_funcs;
- struct drm_display_mode *(*get_config_mode) (struct drm_device *);
- void (*update_fb) (struct mdfld_dsi_dbi_output *, int);
- int (*get_panel_info) (struct drm_device *, int, struct panel_info *);
- int (*reset)(int pipe);
- void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe);
-};
-
diff --git a/drivers/staging/gma500/mid_bios.c b/drivers/staging/gma500/mid_bios.c
deleted file mode 100644
index ee3c0368e320..000000000000
--- a/drivers/staging/gma500/mid_bios.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-/* TODO
- * - Split functions by vbt type
- * - Make them all take drm_device
- * - Check ioremap failures
- */
-
-#include
-#include
-#include
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "mid_bios.h"
-#include "mdfld_output.h"
-
-static int panel_id = GCT_DETECT;
-module_param_named(panel_id, panel_id, int, 0600);
-MODULE_PARM_DESC(panel_id, "Panel Identifier");
-
-
-static void mid_get_fuse_settings(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
- uint32_t fuse_value = 0;
- uint32_t fuse_value_tmp = 0;
-
-#define FB_REG06 0xD0810600
-#define FB_MIPI_DISABLE (1 << 11)
-#define FB_REG09 0xD0810900
-#define FB_REG09 0xD0810900
-#define FB_SKU_MASK 0x7000
-#define FB_SKU_SHIFT 12
-#define FB_SKU_100 0
-#define FB_SKU_100L 1
-#define FB_SKU_83 2
- pci_write_config_dword(pci_root, 0xD0, FB_REG06);
- pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-
- /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
- if (IS_MRST(dev))
- dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
-
- DRM_INFO("internal display is %s\n",
- dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
-
- /* Prevent runtime suspend at start*/
- if (dev_priv->iLVDS_enable) {
- dev_priv->is_lvds_on = true;
- dev_priv->is_mipi_on = false;
- } else {
- dev_priv->is_mipi_on = true;
- dev_priv->is_lvds_on = false;
- }
-
- dev_priv->video_device_fuse = fuse_value;
-
- pci_write_config_dword(pci_root, 0xD0, FB_REG09);
- pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-
- dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value);
- fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
-
- dev_priv->fuse_reg_value = fuse_value;
-
- switch (fuse_value_tmp) {
- case FB_SKU_100:
- dev_priv->core_freq = 200;
- break;
- case FB_SKU_100L:
- dev_priv->core_freq = 100;
- break;
- case FB_SKU_83:
- dev_priv->core_freq = 166;
- break;
- default:
- dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
- fuse_value_tmp);
- dev_priv->core_freq = 0;
- }
- dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq);
- pci_dev_put(pci_root);
-}
-
-/*
- * Get the revison ID, B0:D2:F0;0x08
- */
-static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
-{
- uint32_t platform_rev_id = 0;
- struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
- pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
- dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
- pci_dev_put(pci_gfx_root);
- dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n",
- dev_priv->platform_rev_id);
-}
-
-static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
-{
- struct drm_device *dev = dev_priv->dev;
- struct mrst_vbt *vbt = &dev_priv->vbt_data;
- u32 addr;
- u16 new_size;
- u8 *vbt_virtual;
- u8 bpi;
- u8 number_desc = 0;
- struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD;
- struct gct_r10_timing_info ti;
- void *pGCT;
- struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
- /* Get the address of the platform config vbt, B0:D2:F0;0xFC */
- pci_read_config_dword(pci_gfx_root, 0xFC, &addr);
- pci_dev_put(pci_gfx_root);
-
- dev_dbg(dev->dev, "drm platform config address is %x\n", addr);
-
- /* check for platform config address == 0. */
- /* this means fw doesn't support vbt */
-
- if (addr == 0) {
- vbt->size = 0;
- return;
- }
-
- /* get the virtual address of the vbt */
- vbt_virtual = ioremap(addr, sizeof(*vbt));
-
- memcpy(vbt, vbt_virtual, sizeof(*vbt));
- iounmap(vbt_virtual); /* Free virtual address space */
-
- dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision);
-
- switch (vbt->revision) {
- case 0:
- vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
- vbt->size - sizeof(*vbt) + 4);
- pGCT = vbt->mrst_gct;
- bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
- dev_priv->gct_data.bpi = bpi;
- dev_priv->gct_data.pt =
- ((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
- memcpy(&dev_priv->gct_data.DTD,
- &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
- sizeof(struct mrst_timing_info));
- dev_priv->gct_data.Panel_Port_Control =
- ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
- ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
- break;
- case 1:
- vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
- vbt->size - sizeof(*vbt) + 4);
- pGCT = vbt->mrst_gct;
- bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
- dev_priv->gct_data.bpi = bpi;
- dev_priv->gct_data.pt =
- ((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
- memcpy(&dev_priv->gct_data.DTD,
- &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
- sizeof(struct mrst_timing_info));
- dev_priv->gct_data.Panel_Port_Control =
- ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
- ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
- break;
- case 0x10:
- /*header definition changed from rev 01 (v2) to rev 10h. */
- /*so, some values have changed location*/
- new_size = vbt->checksum; /*checksum contains lo size byte*/
- /*LSB of mrst_gct contains hi size byte*/
- new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8;
-
- vbt->checksum = vbt->size; /*size contains the checksum*/
- if (new_size > 0xff)
- vbt->size = 0xff; /*restrict size to 255*/
- else
- vbt->size = new_size;
-
- /* number of descriptors defined in the GCT */
- number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8;
- bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16;
- vbt->mrst_gct = ioremap(addr + GCT_R10_HEADER_SIZE,
- GCT_R10_DISPLAY_DESC_SIZE * number_desc);
- pGCT = vbt->mrst_gct;
- pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
- dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
-
- /*copy the GCT display timings into a temp structure*/
- memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
-
- /*now copy the temp struct into the dev_priv->gct_data*/
- dp_ti->pixel_clock = ti.pixel_clock;
- dp_ti->hactive_hi = ti.hactive_hi;
- dp_ti->hactive_lo = ti.hactive_lo;
- dp_ti->hblank_hi = ti.hblank_hi;
- dp_ti->hblank_lo = ti.hblank_lo;
- dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
- dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
- dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
- dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
- dp_ti->vactive_hi = ti.vactive_hi;
- dp_ti->vactive_lo = ti.vactive_lo;
- dp_ti->vblank_hi = ti.vblank_hi;
- dp_ti->vblank_lo = ti.vblank_lo;
- dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
- dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
- dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
- dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
-
- /* Move the MIPI_Display_Descriptor data from GCT to dev priv */
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
- *((u8 *)pGCT + 0x0d);
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
- (*((u8 *)pGCT + 0x0e)) << 8;
- break;
- default:
- dev_err(dev->dev, "Unknown revision of GCT!\n");
- vbt->size = 0;
- }
- if (IS_MFLD(dev_priv->dev)) {
- if (panel_id == GCT_DETECT) {
- if (dev_priv->gct_data.bpi == 2) {
- dev_info(dev->dev, "[GFX] PYR Panel Detected\n");
- dev_priv->panel_id = PYR_CMD;
- panel_id = PYR_CMD;
- } else if (dev_priv->gct_data.bpi == 0) {
- dev_info(dev->dev, "[GFX] TMD Panel Detected.\n");
- dev_priv->panel_id = TMD_VID;
- panel_id = TMD_VID;
- } else {
- dev_info(dev->dev, "[GFX] Default Panel (TPO)\n");
- dev_priv->panel_id = TPO_CMD;
- panel_id = TPO_CMD;
- }
- } else {
- dev_info(dev->dev, "[GFX] Panel Parameter Passed in through cmd line\n");
- dev_priv->panel_id = panel_id;
- }
- }
-}
-
-int mid_chip_setup(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- mid_get_fuse_settings(dev);
- mid_get_vbt_data(dev_priv);
- mid_get_pci_revID(dev_priv);
- return 0;
-}
diff --git a/drivers/staging/gma500/mid_bios.h b/drivers/staging/gma500/mid_bios.h
deleted file mode 100644
index 00e7d564b7eb..000000000000
--- a/drivers/staging/gma500/mid_bios.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-extern int mid_chip_setup(struct drm_device *dev);
-
diff --git a/drivers/staging/gma500/mmu.c b/drivers/staging/gma500/mmu.c
deleted file mode 100644
index c904d73b1de3..000000000000
--- a/drivers/staging/gma500/mmu.c
+++ /dev/null
@@ -1,858 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-#include
-#include "psb_drv.h"
-#include "psb_reg.h"
-
-/*
- * Code for the SGX MMU:
- */
-
-/*
- * clflush on one processor only:
- * clflush should apparently flush the cache line on all processors in an
- * SMP system.
- */
-
-/*
- * kmap atomic:
- * The usage of the slots must be completely encapsulated within a spinlock, and
- * no other functions that may be using the locks for other purposed may be
- * called from within the locked region.
- * Since the slots are per processor, this will guarantee that we are the only
- * user.
- */
-
-/*
- * TODO: Inserting ptes from an interrupt handler:
- * This may be desirable for some SGX functionality where the GPU can fault in
- * needed pages. For that, we need to make an atomic insert_pages function, that
- * may fail.
- * If it fails, the caller need to insert the page using a workqueue function,
- * but on average it should be fast.
- */
-
-struct psb_mmu_driver {
- /* protects driver- and pd structures. Always take in read mode
- * before taking the page table spinlock.
- */
- struct rw_semaphore sem;
-
- /* protects page tables, directory tables and pt tables.
- * and pt structures.
- */
- spinlock_t lock;
-
- atomic_t needs_tlbflush;
-
- uint8_t __iomem *register_map;
- struct psb_mmu_pd *default_pd;
- /*uint32_t bif_ctrl;*/
- int has_clflush;
- int clflush_add;
- unsigned long clflush_mask;
-
- struct drm_psb_private *dev_priv;
-};
-
-struct psb_mmu_pd;
-
-struct psb_mmu_pt {
- struct psb_mmu_pd *pd;
- uint32_t index;
- uint32_t count;
- struct page *p;
- uint32_t *v;
-};
-
-struct psb_mmu_pd {
- struct psb_mmu_driver *driver;
- int hw_context;
- struct psb_mmu_pt **tables;
- struct page *p;
- struct page *dummy_pt;
- struct page *dummy_page;
- uint32_t pd_mask;
- uint32_t invalid_pde;
- uint32_t invalid_pte;
-};
-
-static inline uint32_t psb_mmu_pt_index(uint32_t offset)
-{
- return (offset >> PSB_PTE_SHIFT) & 0x3FF;
-}
-
-static inline uint32_t psb_mmu_pd_index(uint32_t offset)
-{
- return offset >> PSB_PDE_SHIFT;
-}
-
-static inline void psb_clflush(void *addr)
-{
- __asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory");
-}
-
-static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
- void *addr)
-{
- if (!driver->has_clflush)
- return;
-
- mb();
- psb_clflush(addr);
- mb();
-}
-
-static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page)
-{
- uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT;
- uint32_t clflush_count = PAGE_SIZE / clflush_add;
- int i;
- uint8_t *clf;
-
- clf = kmap_atomic(page, KM_USER0);
- mb();
- for (i = 0; i < clflush_count; ++i) {
- psb_clflush(clf);
- clf += clflush_add;
- }
- mb();
- kunmap_atomic(clf, KM_USER0);
-}
-
-static void psb_pages_clflush(struct psb_mmu_driver *driver,
- struct page *page[], unsigned long num_pages)
-{
- int i;
-
- if (!driver->has_clflush)
- return ;
-
- for (i = 0; i < num_pages; i++)
- psb_page_clflush(driver, *page++);
-}
-
-static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver,
- int force)
-{
- atomic_set(&driver->needs_tlbflush, 0);
-}
-
-static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force)
-{
- down_write(&driver->sem);
- psb_mmu_flush_pd_locked(driver, force);
- up_write(&driver->sem);
-}
-
-void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot)
-{
- if (rc_prot)
- down_write(&driver->sem);
- if (rc_prot)
- up_write(&driver->sem);
-}
-
-void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context)
-{
- /*ttm_tt_cache_flush(&pd->p, 1);*/
- psb_pages_clflush(pd->driver, &pd->p, 1);
- down_write(&pd->driver->sem);
- wmb();
- psb_mmu_flush_pd_locked(pd->driver, 1);
- pd->hw_context = hw_context;
- up_write(&pd->driver->sem);
-
-}
-
-static inline unsigned long psb_pd_addr_end(unsigned long addr,
- unsigned long end)
-{
-
- addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK;
- return (addr < end) ? addr : end;
-}
-
-static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type)
-{
- uint32_t mask = PSB_PTE_VALID;
-
- if (type & PSB_MMU_CACHED_MEMORY)
- mask |= PSB_PTE_CACHED;
- if (type & PSB_MMU_RO_MEMORY)
- mask |= PSB_PTE_RO;
- if (type & PSB_MMU_WO_MEMORY)
- mask |= PSB_PTE_WO;
-
- return (pfn << PAGE_SHIFT) | mask;
-}
-
-struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
- int trap_pagefaults, int invalid_type)
-{
- struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL);
- uint32_t *v;
- int i;
-
- if (!pd)
- return NULL;
-
- pd->p = alloc_page(GFP_DMA32);
- if (!pd->p)
- goto out_err1;
- pd->dummy_pt = alloc_page(GFP_DMA32);
- if (!pd->dummy_pt)
- goto out_err2;
- pd->dummy_page = alloc_page(GFP_DMA32);
- if (!pd->dummy_page)
- goto out_err3;
-
- if (!trap_pagefaults) {
- pd->invalid_pde =
- psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt),
- invalid_type);
- pd->invalid_pte =
- psb_mmu_mask_pte(page_to_pfn(pd->dummy_page),
- invalid_type);
- } else {
- pd->invalid_pde = 0;
- pd->invalid_pte = 0;
- }
-
- v = kmap(pd->dummy_pt);
- for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
- v[i] = pd->invalid_pte;
-
- kunmap(pd->dummy_pt);
-
- v = kmap(pd->p);
- for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
- v[i] = pd->invalid_pde;
-
- kunmap(pd->p);
-
- clear_page(kmap(pd->dummy_page));
- kunmap(pd->dummy_page);
-
- pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024);
- if (!pd->tables)
- goto out_err4;
-
- pd->hw_context = -1;
- pd->pd_mask = PSB_PTE_VALID;
- pd->driver = driver;
-
- return pd;
-
-out_err4:
- __free_page(pd->dummy_page);
-out_err3:
- __free_page(pd->dummy_pt);
-out_err2:
- __free_page(pd->p);
-out_err1:
- kfree(pd);
- return NULL;
-}
-
-void psb_mmu_free_pt(struct psb_mmu_pt *pt)
-{
- __free_page(pt->p);
- kfree(pt);
-}
-
-void psb_mmu_free_pagedir(struct psb_mmu_pd *pd)
-{
- struct psb_mmu_driver *driver = pd->driver;
- struct psb_mmu_pt *pt;
- int i;
-
- down_write(&driver->sem);
- if (pd->hw_context != -1)
- psb_mmu_flush_pd_locked(driver, 1);
-
- /* Should take the spinlock here, but we don't need to do that
- since we have the semaphore in write mode. */
-
- for (i = 0; i < 1024; ++i) {
- pt = pd->tables[i];
- if (pt)
- psb_mmu_free_pt(pt);
- }
-
- vfree(pd->tables);
- __free_page(pd->dummy_page);
- __free_page(pd->dummy_pt);
- __free_page(pd->p);
- kfree(pd);
- up_write(&driver->sem);
-}
-
-static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
-{
- struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL);
- void *v;
- uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT;
- uint32_t clflush_count = PAGE_SIZE / clflush_add;
- spinlock_t *lock = &pd->driver->lock;
- uint8_t *clf;
- uint32_t *ptes;
- int i;
-
- if (!pt)
- return NULL;
-
- pt->p = alloc_page(GFP_DMA32);
- if (!pt->p) {
- kfree(pt);
- return NULL;
- }
-
- spin_lock(lock);
-
- v = kmap_atomic(pt->p, KM_USER0);
- clf = (uint8_t *) v;
- ptes = (uint32_t *) v;
- for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
- *ptes++ = pd->invalid_pte;
-
-
- if (pd->driver->has_clflush && pd->hw_context != -1) {
- mb();
- for (i = 0; i < clflush_count; ++i) {
- psb_clflush(clf);
- clf += clflush_add;
- }
- mb();
- }
-
- kunmap_atomic(v, KM_USER0);
- spin_unlock(lock);
-
- pt->count = 0;
- pt->pd = pd;
- pt->index = 0;
-
- return pt;
-}
-
-struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
- unsigned long addr)
-{
- uint32_t index = psb_mmu_pd_index(addr);
- struct psb_mmu_pt *pt;
- uint32_t *v;
- spinlock_t *lock = &pd->driver->lock;
-
- spin_lock(lock);
- pt = pd->tables[index];
- while (!pt) {
- spin_unlock(lock);
- pt = psb_mmu_alloc_pt(pd);
- if (!pt)
- return NULL;
- spin_lock(lock);
-
- if (pd->tables[index]) {
- spin_unlock(lock);
- psb_mmu_free_pt(pt);
- spin_lock(lock);
- pt = pd->tables[index];
- continue;
- }
-
- v = kmap_atomic(pd->p, KM_USER0);
- pd->tables[index] = pt;
- v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
- pt->index = index;
- kunmap_atomic((void *) v, KM_USER0);
-
- if (pd->hw_context != -1) {
- psb_mmu_clflush(pd->driver, (void *) &v[index]);
- atomic_set(&pd->driver->needs_tlbflush, 1);
- }
- }
- pt->v = kmap_atomic(pt->p, KM_USER0);
- return pt;
-}
-
-static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
- unsigned long addr)
-{
- uint32_t index = psb_mmu_pd_index(addr);
- struct psb_mmu_pt *pt;
- spinlock_t *lock = &pd->driver->lock;
-
- spin_lock(lock);
- pt = pd->tables[index];
- if (!pt) {
- spin_unlock(lock);
- return NULL;
- }
- pt->v = kmap_atomic(pt->p, KM_USER0);
- return pt;
-}
-
-static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
-{
- struct psb_mmu_pd *pd = pt->pd;
- uint32_t *v;
-
- kunmap_atomic(pt->v, KM_USER0);
- if (pt->count == 0) {
- v = kmap_atomic(pd->p, KM_USER0);
- v[pt->index] = pd->invalid_pde;
- pd->tables[pt->index] = NULL;
-
- if (pd->hw_context != -1) {
- psb_mmu_clflush(pd->driver,
- (void *) &v[pt->index]);
- atomic_set(&pd->driver->needs_tlbflush, 1);
- }
- kunmap_atomic(pt->v, KM_USER0);
- spin_unlock(&pd->driver->lock);
- psb_mmu_free_pt(pt);
- return;
- }
- spin_unlock(&pd->driver->lock);
-}
-
-static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt,
- unsigned long addr, uint32_t pte)
-{
- pt->v[psb_mmu_pt_index(addr)] = pte;
-}
-
-static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
- unsigned long addr)
-{
- pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
-}
-
-
-void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
- uint32_t mmu_offset, uint32_t gtt_start,
- uint32_t gtt_pages)
-{
- uint32_t *v;
- uint32_t start = psb_mmu_pd_index(mmu_offset);
- struct psb_mmu_driver *driver = pd->driver;
- int num_pages = gtt_pages;
-
- down_read(&driver->sem);
- spin_lock(&driver->lock);
-
- v = kmap_atomic(pd->p, KM_USER0);
- v += start;
-
- while (gtt_pages--) {
- *v++ = gtt_start | pd->pd_mask;
- gtt_start += PAGE_SIZE;
- }
-
- /*ttm_tt_cache_flush(&pd->p, num_pages);*/
- psb_pages_clflush(pd->driver, &pd->p, num_pages);
- kunmap_atomic(v, KM_USER0);
- spin_unlock(&driver->lock);
-
- if (pd->hw_context != -1)
- atomic_set(&pd->driver->needs_tlbflush, 1);
-
- up_read(&pd->driver->sem);
- psb_mmu_flush_pd(pd->driver, 0);
-}
-
-struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver)
-{
- struct psb_mmu_pd *pd;
-
- /* down_read(&driver->sem); */
- pd = driver->default_pd;
- /* up_read(&driver->sem); */
-
- return pd;
-}
-
-/* Returns the physical address of the PD shared by sgx/msvdx */
-uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver)
-{
- struct psb_mmu_pd *pd;
-
- pd = psb_mmu_get_default_pd(driver);
- return page_to_pfn(pd->p) << PAGE_SHIFT;
-}
-
-void psb_mmu_driver_takedown(struct psb_mmu_driver *driver)
-{
- psb_mmu_free_pagedir(driver->default_pd);
- kfree(driver);
-}
-
-struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
- int trap_pagefaults,
- int invalid_type,
- struct drm_psb_private *dev_priv)
-{
- struct psb_mmu_driver *driver;
-
- driver = kmalloc(sizeof(*driver), GFP_KERNEL);
-
- if (!driver)
- return NULL;
- driver->dev_priv = dev_priv;
-
- driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults,
- invalid_type);
- if (!driver->default_pd)
- goto out_err1;
-
- spin_lock_init(&driver->lock);
- init_rwsem(&driver->sem);
- down_write(&driver->sem);
- driver->register_map = registers;
- atomic_set(&driver->needs_tlbflush, 1);
-
- driver->has_clflush = 0;
-
- if (boot_cpu_has(X86_FEATURE_CLFLSH)) {
- uint32_t tfms, misc, cap0, cap4, clflush_size;
-
- /*
- * clflush size is determined at kernel setup for x86_64
- * but not for i386. We have to do it here.
- */
-
- cpuid(0x00000001, &tfms, &misc, &cap0, &cap4);
- clflush_size = ((misc >> 8) & 0xff) * 8;
- driver->has_clflush = 1;
- driver->clflush_add =
- PAGE_SIZE * clflush_size / sizeof(uint32_t);
- driver->clflush_mask = driver->clflush_add - 1;
- driver->clflush_mask = ~driver->clflush_mask;
- }
-
- up_write(&driver->sem);
- return driver;
-
-out_err1:
- kfree(driver);
- return NULL;
-}
-
-static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
- unsigned long address, uint32_t num_pages,
- uint32_t desired_tile_stride,
- uint32_t hw_tile_stride)
-{
- struct psb_mmu_pt *pt;
- uint32_t rows = 1;
- uint32_t i;
- unsigned long addr;
- unsigned long end;
- unsigned long next;
- unsigned long add;
- unsigned long row_add;
- unsigned long clflush_add = pd->driver->clflush_add;
- unsigned long clflush_mask = pd->driver->clflush_mask;
-
- if (!pd->driver->has_clflush) {
- /*ttm_tt_cache_flush(&pd->p, num_pages);*/
- psb_pages_clflush(pd->driver, &pd->p, num_pages);
- return;
- }
-
- if (hw_tile_stride)
- rows = num_pages / desired_tile_stride;
- else
- desired_tile_stride = num_pages;
-
- add = desired_tile_stride << PAGE_SHIFT;
- row_add = hw_tile_stride << PAGE_SHIFT;
- mb();
- for (i = 0; i < rows; ++i) {
-
- addr = address;
- end = addr + add;
-
- do {
- next = psb_pd_addr_end(addr, end);
- pt = psb_mmu_pt_map_lock(pd, addr);
- if (!pt)
- continue;
- do {
- psb_clflush(&pt->v
- [psb_mmu_pt_index(addr)]);
- } while (addr +=
- clflush_add,
- (addr & clflush_mask) < next);
-
- psb_mmu_pt_unmap_unlock(pt);
- } while (addr = next, next != end);
- address += row_add;
- }
- mb();
-}
-
-void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
- unsigned long address, uint32_t num_pages)
-{
- struct psb_mmu_pt *pt;
- unsigned long addr;
- unsigned long end;
- unsigned long next;
- unsigned long f_address = address;
-
- down_read(&pd->driver->sem);
-
- addr = address;
- end = addr + (num_pages << PAGE_SHIFT);
-
- do {
- next = psb_pd_addr_end(addr, end);
- pt = psb_mmu_pt_alloc_map_lock(pd, addr);
- if (!pt)
- goto out;
- do {
- psb_mmu_invalidate_pte(pt, addr);
- --pt->count;
- } while (addr += PAGE_SIZE, addr < next);
- psb_mmu_pt_unmap_unlock(pt);
-
- } while (addr = next, next != end);
-
-out:
- if (pd->hw_context != -1)
- psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
-
- up_read(&pd->driver->sem);
-
- if (pd->hw_context != -1)
- psb_mmu_flush(pd->driver, 0);
-
- return;
-}
-
-void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
- uint32_t num_pages, uint32_t desired_tile_stride,
- uint32_t hw_tile_stride)
-{
- struct psb_mmu_pt *pt;
- uint32_t rows = 1;
- uint32_t i;
- unsigned long addr;
- unsigned long end;
- unsigned long next;
- unsigned long add;
- unsigned long row_add;
- unsigned long f_address = address;
-
- if (hw_tile_stride)
- rows = num_pages / desired_tile_stride;
- else
- desired_tile_stride = num_pages;
-
- add = desired_tile_stride << PAGE_SHIFT;
- row_add = hw_tile_stride << PAGE_SHIFT;
-
- /* down_read(&pd->driver->sem); */
-
- /* Make sure we only need to flush this processor's cache */
-
- for (i = 0; i < rows; ++i) {
-
- addr = address;
- end = addr + add;
-
- do {
- next = psb_pd_addr_end(addr, end);
- pt = psb_mmu_pt_map_lock(pd, addr);
- if (!pt)
- continue;
- do {
- psb_mmu_invalidate_pte(pt, addr);
- --pt->count;
-
- } while (addr += PAGE_SIZE, addr < next);
- psb_mmu_pt_unmap_unlock(pt);
-
- } while (addr = next, next != end);
- address += row_add;
- }
- if (pd->hw_context != -1)
- psb_mmu_flush_ptes(pd, f_address, num_pages,
- desired_tile_stride, hw_tile_stride);
-
- /* up_read(&pd->driver->sem); */
-
- if (pd->hw_context != -1)
- psb_mmu_flush(pd->driver, 0);
-}
-
-int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn,
- unsigned long address, uint32_t num_pages,
- int type)
-{
- struct psb_mmu_pt *pt;
- uint32_t pte;
- unsigned long addr;
- unsigned long end;
- unsigned long next;
- unsigned long f_address = address;
- int ret = 0;
-
- down_read(&pd->driver->sem);
-
- addr = address;
- end = addr + (num_pages << PAGE_SHIFT);
-
- do {
- next = psb_pd_addr_end(addr, end);
- pt = psb_mmu_pt_alloc_map_lock(pd, addr);
- if (!pt) {
- ret = -ENOMEM;
- goto out;
- }
- do {
- pte = psb_mmu_mask_pte(start_pfn++, type);
- psb_mmu_set_pte(pt, addr, pte);
- pt->count++;
- } while (addr += PAGE_SIZE, addr < next);
- psb_mmu_pt_unmap_unlock(pt);
-
- } while (addr = next, next != end);
-
-out:
- if (pd->hw_context != -1)
- psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
-
- up_read(&pd->driver->sem);
-
- if (pd->hw_context != -1)
- psb_mmu_flush(pd->driver, 1);
-
- return ret;
-}
-
-int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
- unsigned long address, uint32_t num_pages,
- uint32_t desired_tile_stride,
- uint32_t hw_tile_stride, int type)
-{
- struct psb_mmu_pt *pt;
- uint32_t rows = 1;
- uint32_t i;
- uint32_t pte;
- unsigned long addr;
- unsigned long end;
- unsigned long next;
- unsigned long add;
- unsigned long row_add;
- unsigned long f_address = address;
- int ret = 0;
-
- if (hw_tile_stride) {
- if (num_pages % desired_tile_stride != 0)
- return -EINVAL;
- rows = num_pages / desired_tile_stride;
- } else {
- desired_tile_stride = num_pages;
- }
-
- add = desired_tile_stride << PAGE_SHIFT;
- row_add = hw_tile_stride << PAGE_SHIFT;
-
- down_read(&pd->driver->sem);
-
- for (i = 0; i < rows; ++i) {
-
- addr = address;
- end = addr + add;
-
- do {
- next = psb_pd_addr_end(addr, end);
- pt = psb_mmu_pt_alloc_map_lock(pd, addr);
- if (!pt) {
- ret = -ENOMEM;
- goto out;
- }
- do {
- pte =
- psb_mmu_mask_pte(page_to_pfn(*pages++),
- type);
- psb_mmu_set_pte(pt, addr, pte);
- pt->count++;
- } while (addr += PAGE_SIZE, addr < next);
- psb_mmu_pt_unmap_unlock(pt);
-
- } while (addr = next, next != end);
-
- address += row_add;
- }
-out:
- if (pd->hw_context != -1)
- psb_mmu_flush_ptes(pd, f_address, num_pages,
- desired_tile_stride, hw_tile_stride);
-
- up_read(&pd->driver->sem);
-
- if (pd->hw_context != -1)
- psb_mmu_flush(pd->driver, 1);
-
- return ret;
-}
-
-int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
- unsigned long *pfn)
-{
- int ret;
- struct psb_mmu_pt *pt;
- uint32_t tmp;
- spinlock_t *lock = &pd->driver->lock;
-
- down_read(&pd->driver->sem);
- pt = psb_mmu_pt_map_lock(pd, virtual);
- if (!pt) {
- uint32_t *v;
-
- spin_lock(lock);
- v = kmap_atomic(pd->p, KM_USER0);
- tmp = v[psb_mmu_pd_index(virtual)];
- kunmap_atomic(v, KM_USER0);
- spin_unlock(lock);
-
- if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
- !(pd->invalid_pte & PSB_PTE_VALID)) {
- ret = -EINVAL;
- goto out;
- }
- ret = 0;
- *pfn = pd->invalid_pte >> PAGE_SHIFT;
- goto out;
- }
- tmp = pt->v[psb_mmu_pt_index(virtual)];
- if (!(tmp & PSB_PTE_VALID)) {
- ret = -EINVAL;
- } else {
- ret = 0;
- *pfn = tmp >> PAGE_SHIFT;
- }
- psb_mmu_pt_unmap_unlock(pt);
-out:
- up_read(&pd->driver->sem);
- return ret;
-}
diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h
deleted file mode 100644
index b563dbc73104..000000000000
--- a/drivers/staging/gma500/mrst.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-/* MID device specific descriptors */
-
-struct mrst_vbt {
- s8 signature[4]; /*4 bytes,"$GCT" */
- u8 revision;
- u8 size;
- u8 checksum;
- void *mrst_gct;
-} __packed;
-
-struct mrst_timing_info {
- u16 pixel_clock;
- u8 hactive_lo;
- u8 hblank_lo;
- u8 hblank_hi:4;
- u8 hactive_hi:4;
- u8 vactive_lo;
- u8 vblank_lo;
- u8 vblank_hi:4;
- u8 vactive_hi:4;
- u8 hsync_offset_lo;
- u8 hsync_pulse_width_lo;
- u8 vsync_pulse_width_lo:4;
- u8 vsync_offset_lo:4;
- u8 vsync_pulse_width_hi:2;
- u8 vsync_offset_hi:2;
- u8 hsync_pulse_width_hi:2;
- u8 hsync_offset_hi:2;
- u8 width_mm_lo;
- u8 height_mm_lo;
- u8 height_mm_hi:4;
- u8 width_mm_hi:4;
- u8 hborder;
- u8 vborder;
- u8 unknown0:1;
- u8 hsync_positive:1;
- u8 vsync_positive:1;
- u8 separate_sync:2;
- u8 stereo:1;
- u8 unknown6:1;
- u8 interlaced:1;
-} __packed;
-
-struct gct_r10_timing_info {
- u16 pixel_clock;
- u32 hactive_lo:8;
- u32 hactive_hi:4;
- u32 hblank_lo:8;
- u32 hblank_hi:4;
- u32 hsync_offset_lo:8;
- u16 hsync_offset_hi:2;
- u16 hsync_pulse_width_lo:8;
- u16 hsync_pulse_width_hi:2;
- u16 hsync_positive:1;
- u16 rsvd_1:3;
- u8 vactive_lo:8;
- u16 vactive_hi:4;
- u16 vblank_lo:8;
- u16 vblank_hi:4;
- u16 vsync_offset_lo:4;
- u16 vsync_offset_hi:2;
- u16 vsync_pulse_width_lo:4;
- u16 vsync_pulse_width_hi:2;
- u16 vsync_positive:1;
- u16 rsvd_2:3;
-} __packed;
-
-struct mrst_panel_descriptor_v1 {
- u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
- /* 0x61190 if MIPI */
- u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
- u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
- u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */
- /* Register 0x61210 */
- struct mrst_timing_info DTD;/*18 bytes, Standard definition */
- u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */
- /* Bit 0, Frequency, 15 bits,0 - 32767Hz */
- /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */
- u16 Panel_MIPI_Display_Descriptor;
- /*16 bits, Defined as follows: */
- /* if MIPI, 0x0000 if LVDS */
- /* Bit 0, Type, 2 bits, */
- /* 0: Type-1, */
- /* 1: Type-2, */
- /* 2: Type-3, */
- /* 3: Type-4 */
- /* Bit 2, Pixel Format, 4 bits */
- /* Bit0: 16bpp (not supported in LNC), */
- /* Bit1: 18bpp loosely packed, */
- /* Bit2: 18bpp packed, */
- /* Bit3: 24bpp */
- /* Bit 6, Reserved, 2 bits, 00b */
- /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
- /* Bit 14, Reserved, 2 bits, 00b */
-} __packed;
-
-struct mrst_panel_descriptor_v2 {
- u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
- /* 0x61190 if MIPI */
- u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
- u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
- u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */
- /* Register 0x61210 */
- struct mrst_timing_info DTD;/*18 bytes, Standard definition */
- u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/
- /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/
- u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */
- /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/
- u16 Panel_MIPI_Display_Descriptor;
- /*16 bits, Defined as follows: */
- /* if MIPI, 0x0000 if LVDS */
- /* Bit 0, Type, 2 bits, */
- /* 0: Type-1, */
- /* 1: Type-2, */
- /* 2: Type-3, */
- /* 3: Type-4 */
- /* Bit 2, Pixel Format, 4 bits */
- /* Bit0: 16bpp (not supported in LNC), */
- /* Bit1: 18bpp loosely packed, */
- /* Bit2: 18bpp packed, */
- /* Bit3: 24bpp */
- /* Bit 6, Reserved, 2 bits, 00b */
- /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
- /* Bit 14, Reserved, 2 bits, 00b */
-} __packed;
-
-union mrst_panel_rx {
- struct {
- u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/
- /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */
- u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */
- /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/
- u16 SupportedVideoTransferMode:2; /*0: Non-burst only */
- /* 1: Burst and non-burst */
- /* 2/3: Reserved */
- u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/
- u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/
- u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/
- u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */
- u16 Rsvd:5;/*5 bits,00000b */
- } panelrx;
- u16 panel_receiver;
-} __packed;
-
-struct mrst_gct_v1 {
- union { /*8 bits,Defined as follows: */
- struct {
- u8 PanelType:4; /*4 bits, Bit field for panels*/
- /* 0 - 3: 0 = LVDS, 1 = MIPI*/
- /*2 bits,Specifies which of the*/
- u8 BootPanelIndex:2;
- /* 4 panels to use by default*/
- u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
- /* the 4 MIPI DSI receivers to use*/
- } PD;
- u8 PanelDescriptor;
- };
- struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/
- union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __packed;
-
-struct mrst_gct_v2 {
- union { /*8 bits,Defined as follows: */
- struct {
- u8 PanelType:4; /*4 bits, Bit field for panels*/
- /* 0 - 3: 0 = LVDS, 1 = MIPI*/
- /*2 bits,Specifies which of the*/
- u8 BootPanelIndex:2;
- /* 4 panels to use by default*/
- u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
- /* the 4 MIPI DSI receivers to use*/
- } PD;
- u8 PanelDescriptor;
- };
- struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/
- union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __packed;
-
-struct mrst_gct_data {
- u8 bpi; /* boot panel index, number of panel used during boot */
- u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
- struct mrst_timing_info DTD; /* timing info for the selected panel */
- u32 Panel_Port_Control;
- u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/
- u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/
- u32 PP_Cycle_Delay;
- u16 Panel_Backlight_Inverter_Descriptor;
- u16 Panel_MIPI_Display_Descriptor;
-} __packed;
-
-#define MODE_SETTING_IN_CRTC 0x1
-#define MODE_SETTING_IN_ENCODER 0x2
-#define MODE_SETTING_ON_GOING 0x3
-#define MODE_SETTING_IN_DSR 0x4
-#define MODE_SETTING_ENCODER_DONE 0x8
-
-#define GCT_R10_HEADER_SIZE 16
-#define GCT_R10_DISPLAY_DESC_SIZE 28
-
-/*
- * Moorestown HDMI interfaces
- */
-
-struct mrst_hdmi_dev {
- struct pci_dev *dev;
- void __iomem *regs;
- unsigned int mmio, mmio_len;
- int dpms_mode;
- struct hdmi_i2c_dev *i2c_dev;
-
- /* register state */
- u32 saveDPLL_CTRL;
- u32 saveDPLL_DIV_CTRL;
- u32 saveDPLL_ADJUST;
- u32 saveDPLL_UPDATE;
- u32 saveDPLL_CLK_ENABLE;
- u32 savePCH_HTOTAL_B;
- u32 savePCH_HBLANK_B;
- u32 savePCH_HSYNC_B;
- u32 savePCH_VTOTAL_B;
- u32 savePCH_VBLANK_B;
- u32 savePCH_VSYNC_B;
- u32 savePCH_PIPEBCONF;
- u32 savePCH_PIPEBSRC;
-};
-
-extern void mrst_hdmi_setup(struct drm_device *dev);
-extern void mrst_hdmi_teardown(struct drm_device *dev);
-extern int mrst_hdmi_i2c_init(struct pci_dev *dev);
-extern void mrst_hdmi_i2c_exit(struct pci_dev *dev);
-extern void mrst_hdmi_save(struct drm_device *dev);
-extern void mrst_hdmi_restore(struct drm_device *dev);
-extern void mrst_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev);
diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
deleted file mode 100644
index 980837e37d80..000000000000
--- a/drivers/staging/gma500/mrst_crtc.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include