Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
Linus Torvalds [Thu, 8 Oct 2009 19:04:04 +0000 (12:04 -0700)]
* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, timers: Check for pending timers after (device) interrupts
  NOHZ: update idle state also when NOHZ is inactive

147 files changed:
Documentation/cgroups/cgroups.txt
Documentation/isdn/INTERFACE.CAPI
Documentation/networking/pktgen.txt
Documentation/vm/ksm.txt
Documentation/vm/page-types.c
Documentation/vm/pagemap.txt
MAINTAINERS
arch/arm/mach-omap2/clock34xx.c
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/powerdomain.c
arch/arm/plat-omap/include/mach/cpu.h
arch/arm/plat-omap/include/mach/powerdomain.h
arch/arm/plat-omap/iovmm.c
arch/arm/plat-omap/sram.c
arch/parisc/Kconfig
arch/parisc/include/asm/fixmap.h
arch/parisc/include/asm/hardirq.h
arch/parisc/include/asm/ptrace.h
arch/parisc/include/asm/syscall.h [new file with mode: 0644]
arch/parisc/include/asm/thread_info.h
arch/parisc/kernel/asm-offsets.c
arch/parisc/kernel/entry.S
arch/parisc/kernel/irq.c
arch/parisc/kernel/module.c
arch/parisc/kernel/ptrace.c
arch/parisc/kernel/signal.c
arch/parisc/kernel/syscall.S
arch/parisc/kernel/vmlinux.lds.S
arch/parisc/mm/init.c
drivers/char/agp/parisc-agp.c
drivers/connector/cn_proc.c
drivers/edac/amd64_edac.c
drivers/edac/amd64_edac.h
drivers/edac/amd64_edac_inj.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100d.h
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300d.h
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r420d.h
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_clocks.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/rs100d.h [new file with mode: 0644]
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs400d.h [new file with mode: 0644]
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs600d.h [new file with mode: 0644]
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rs690d.h [new file with mode: 0644]
drivers/gpu/drm/radeon/rs690r.h [deleted file]
drivers/gpu/drm/radeon/rv200d.h [new file with mode: 0644]
drivers/gpu/drm/radeon/rv250d.h [new file with mode: 0644]
drivers/gpu/drm/radeon/rv350d.h [new file with mode: 0644]
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/ttm/ttm_global.c
drivers/hwmon/lis3lv02d_spi.c
drivers/ide/ide-probe.c
drivers/ide/sis5513.c
drivers/isdn/capi/capi.c
drivers/isdn/capi/capidrv.c
drivers/isdn/gigaset/asyncdata.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/ev-layer.c
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/isocdata.c
drivers/mmc/core/sdio_cis.c
drivers/net/au1000_eth.c
drivers/net/benet/be_cmds.c
drivers/net/benet/be_cmds.h
drivers/net/benet/be_ethtool.c
drivers/net/benet/be_main.c
drivers/net/e1000e/82571.c
drivers/net/ethoc.c
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/netxen/netxen_nic_main.c
drivers/net/pasemi_mac_ethtool.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_ethtool.c
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/usb/rndis_host.c
drivers/serial/serial_cs.c
drivers/video/da8xx-fb.c
drivers/video/msm/mddi.c
drivers/video/omap/blizzard.c
drivers/video/omap/omapfb_main.c
firmware/Makefile
firmware/WHENCE
firmware/cis/COMpad2.cis.ihex [new file with mode: 0644]
firmware/cis/COMpad4.cis.ihex [new file with mode: 0644]
firmware/cis/DP83903.cis.ihex [new file with mode: 0644]
firmware/cis/NE2K.cis.ihex [new file with mode: 0644]
firmware/cis/tamarack.cis.ihex [new file with mode: 0644]
fs/proc/kcore.c
fs/proc/page.c
include/drm/drm_crtc_helper.h
include/drm/drm_fb_helper.h
include/drm/drm_pciids.h
include/linux/socket.h
mm/Kconfig
mm/ksm.c
mm/vmalloc.c
net/core/net-sysfs.c
net/core/pktgen.c
net/ipv4/devinet.c
sound/drivers/opl3/opl3_midi.c
sound/pci/hda/patch_realtek.c
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1724.c
sound/pci/via82xx.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8940.c
sound/soc/imx/mxc-ssi.c
sound/soc/soc-dapm.c

index 455d4e6..0b33bfe 100644 (file)
@@ -227,7 +227,14 @@ as the path relative to the root of the cgroup file system.
 Each cgroup is represented by a directory in the cgroup file system
 containing the following files describing that cgroup:
 
- - tasks: list of tasks (by pid) attached to that cgroup
+ - tasks: list of tasks (by pid) attached to that cgroup.  This list
+   is not guaranteed to be sorted.  Writing a thread id into this file
+   moves the thread into this cgroup.
+ - cgroup.procs: list of tgids in the cgroup.  This list is not
+   guaranteed to be sorted or free of duplicate tgids, and userspace
+   should sort/uniquify the list if this property is required.
+   Writing a tgid into this file moves all threads with that tgid into
+   this cgroup.
  - notify_on_release flag: run the release agent on exit?
  - release_agent: the path to use for release notifications (this file
    exists in the top cgroup only)
@@ -374,7 +381,7 @@ Now you want to do something with this cgroup.
 
 In this directory you can find several files:
 # ls
-notify_on_release tasks
+cgroup.procs notify_on_release tasks
 (plus whatever files added by the attached subsystems)
 
 Now attach your shell to this cgroup:
index 686e107..5fe8de5 100644 (file)
@@ -60,10 +60,9 @@ open() operation on regular files or character devices.
 
 After a successful return from register_appl(), CAPI messages from the
 application may be passed to the driver for the device via calls to the
-send_message() callback function. The CAPI message to send is stored in the
-data portion of an skb. Conversely, the driver may call Kernel CAPI's
-capi_ctr_handle_message() function to pass a received CAPI message to Kernel
-CAPI for forwarding to an application, specifying its ApplID.
+send_message() callback function. Conversely, the driver may call Kernel
+CAPI's capi_ctr_handle_message() function to pass a received CAPI message to
+Kernel CAPI for forwarding to an application, specifying its ApplID.
 
 Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
 forwarded as calls to the release_appl() callback function, passing the same
@@ -142,6 +141,7 @@ u16  (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
        to accepting or queueing the message. Errors occurring during the
        actual processing of the message should be signaled with an
        appropriate reply message.
+       May be called in process or interrupt context.
        Calls to this function are not serialized by Kernel CAPI, ie. it must
        be prepared to be re-entered.
 
@@ -154,7 +154,8 @@ read_proc_t *ctr_read_proc
        system entry, /proc/capi/controllers/<n>; will be called with a
        pointer to the device's capi_ctr structure as the last (data) argument
 
-Note: Callback functions are never called in interrupt context.
+Note: Callback functions except send_message() are never called in interrupt
+context.
 
 - to be filled in before calling capi_ctr_ready():
 
@@ -171,14 +172,40 @@ u8 serial[CAPI_SERIAL_LEN]
        value to return for CAPI_GET_SERIAL
 
 
-4.3 The _cmsg Structure
+4.3 SKBs
+
+CAPI messages are passed between Kernel CAPI and the driver via send_message()
+and capi_ctr_handle_message(), stored in the data portion of a socket buffer
+(skb).  Each skb contains a single CAPI message coded according to the CAPI 2.0
+standard.
+
+For the data transfer messages, DATA_B3_REQ and DATA_B3_IND, the actual
+payload data immediately follows the CAPI message itself within the same skb.
+The Data and Data64 parameters are not used for processing. The Data64
+parameter may be omitted by setting the length field of the CAPI message to 22
+instead of 30.
+
+
+4.4 The _cmsg Structure
 
 (declared in <linux/isdn/capiutil.h>)
 
 The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
-accessible form. It contains members for all possible CAPI 2.0 parameters, of
-which only those appearing in the message type currently being processed are
-actually used. Unused members should be set to zero.
+accessible form. It contains members for all possible CAPI 2.0 parameters,
+including subparameters of the Additional Info and B Protocol structured
+parameters, with the following exceptions:
+
+* second Calling party number (CONNECT_IND)
+
+* Data64 (DATA_B3_REQ and DATA_B3_IND)
+
+* Sending complete (subparameter of Additional Info, CONNECT_REQ and INFO_REQ)
+
+* Global Configuration (subparameter of B Protocol, CONNECT_REQ, CONNECT_RESP
+  and SELECT_B_PROTOCOL_REQ)
+
+Only those parameters appearing in the message type currently being processed
+are actually used. Unused members should be set to zero.
 
 Members are named after the CAPI 2.0 standard names of the parameters they
 represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
@@ -190,18 +217,19 @@ u16         for CAPI parameters of type 'word'
 
 u32         for CAPI parameters of type 'dword'
 
-_cstruct    for CAPI parameters of type 'struct' not containing any
-           variably-sized (struct) subparameters (eg. 'Called Party Number')
+_cstruct    for CAPI parameters of type 'struct'
            The member is a pointer to a buffer containing the parameter in
            CAPI encoding (length + content). It may also be NULL, which will
            be taken to represent an empty (zero length) parameter.
+           Subparameters are stored in encoded form within the content part.
 
-_cmstruct   for CAPI parameters of type 'struct' containing 'struct'
-           subparameters ('Additional Info' and 'B Protocol')
+_cmstruct   alternative representation for CAPI parameters of type 'struct'
+           (used only for the 'Additional Info' and 'B Protocol' parameters)
            The representation is a single byte containing one of the values:
-           CAPI_DEFAULT: the parameter is empty
-           CAPI_COMPOSE: the values of the subparameters are stored
-           individually in the corresponding _cmsg structure members
+           CAPI_DEFAULT: The parameter is empty/absent.
+           CAPI_COMPOSE: The parameter is present.
+           Subparameter values are stored individually in the corresponding
+           _cmsg structure members.
 
 Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert
 messages between their transport encoding described in the CAPI 2.0 standard
@@ -297,3 +325,26 @@ char *capi_cmd2str(u8 Command, u8 Subcommand)
        be NULL if the command/subcommand is not one of those defined in the
        CAPI 2.0 standard.
 
+
+7. Debugging
+
+The module kernelcapi has a module parameter showcapimsgs controlling some
+debugging output produced by the module. It can only be set when the module is
+loaded, via a parameter "showcapimsgs=<n>" to the modprobe command, either on
+the command line or in the configuration file.
+
+If the lowest bit of showcapimsgs is set, kernelcapi logs controller and
+application up and down events.
+
+In addition, every registered CAPI controller has an associated traceflag
+parameter controlling how CAPI messages sent from and to tha controller are
+logged. The traceflag parameter is initialized with the value of the
+showcapimsgs parameter when the controller is registered, but can later be
+changed via the MANUFACTURER_REQ command KCAPI_CMD_TRACE.
+
+If the value of traceflag is non-zero, CAPI messages are logged.
+DATA_B3 messages are only logged if the value of traceflag is > 2.
+
+If the lowest bit of traceflag is set, only the command/subcommand and message
+length are logged. Otherwise, kernelcapi logs a readable representation of
+the entire message.
index c6cf4a3..61bb645 100644 (file)
@@ -90,6 +90,11 @@ Examples:
  pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
  pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
 
+ pgset "queue_map_min 0" Sets the min value of tx queue interval
+ pgset "queue_map_max 7" Sets the max value of tx queue interval, for multiqueue devices
+                         To select queue 1 of a given device,
+                         use queue_map_min=1 and queue_map_max=1
+
  pgset "src_mac_count 1" Sets the number of MACs we'll range through.  
                          The 'minimum' MAC is what you set with srcmac.
 
@@ -101,6 +106,9 @@ Examples:
                               IPDST_RND, UDPSRC_RND,
                               UDPDST_RND, MACSRC_RND, MACDST_RND 
                               MPLS_RND, VID_RND, SVID_RND
+                              QUEUE_MAP_RND # queue map random
+                              QUEUE_MAP_CPU # queue map mirrors smp_processor_id()
+
 
  pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
                          cycle through the port range.
index 72a22f6..262d8e6 100644 (file)
@@ -52,15 +52,15 @@ The KSM daemon is controlled by sysfs files in /sys/kernel/mm/ksm/,
 readable by all but writable only by root:
 
 max_kernel_pages - set to maximum number of kernel pages that KSM may use
-                   e.g. "echo 2000 > /sys/kernel/mm/ksm/max_kernel_pages"
+                   e.g. "echo 100000 > /sys/kernel/mm/ksm/max_kernel_pages"
                    Value 0 imposes no limit on the kernel pages KSM may use;
                    but note that any process using MADV_MERGEABLE can cause
                    KSM to allocate these pages, unswappable until it exits.
-                   Default: 2000 (chosen for demonstration purposes)
+                   Default: quarter of memory (chosen to not pin too much)
 
 pages_to_scan    - how many present pages to scan before ksmd goes to sleep
-                   e.g. "echo 200 > /sys/kernel/mm/ksm/pages_to_scan"
-                   Default: 200 (chosen for demonstration purposes)
+                   e.g. "echo 100 > /sys/kernel/mm/ksm/pages_to_scan"
+                   Default: 100 (chosen for demonstration purposes)
 
 sleep_millisecs  - how many milliseconds ksmd should sleep before next scan
                    e.g. "echo 20 > /sys/kernel/mm/ksm/sleep_millisecs"
@@ -70,7 +70,8 @@ run              - set 0 to stop ksmd from running but keep merged pages,
                    set 1 to run ksmd e.g. "echo 1 > /sys/kernel/mm/ksm/run",
                    set 2 to stop ksmd and unmerge all pages currently merged,
                          but leave mergeable areas registered for next run
-                   Default: 1 (for immediate use by apps which register)
+                   Default: 0 (must be changed to 1 to activate KSM,
+                               except if CONFIG_SYSFS is disabled)
 
 The effectiveness of KSM and MADV_MERGEABLE is shown in /sys/kernel/mm/ksm/:
 
@@ -86,4 +87,4 @@ pages_volatile embraces several different kinds of activity, but a high
 proportion there would also indicate poor use of madvise MADV_MERGEABLE.
 
 Izik Eidus,
-Hugh Dickins, 30 July 2009
+Hugh Dickins, 24 Sept 2009
index fa1a30d..3ec4f2a 100644 (file)
@@ -2,7 +2,10 @@
  * page-types: Tool for querying page flags
  *
  * Copyright (C) 2009 Intel corporation
- * Copyright (C) 2009 Wu Fengguang <fengguang.wu@intel.com>
+ *
+ * Authors: Wu Fengguang <fengguang.wu@intel.com>
+ *
+ * Released under the General Public License (GPL).
  */
 
 #define _LARGEFILE64_SOURCE
@@ -69,7 +72,9 @@
 #define KPF_COMPOUND_TAIL      16
 #define KPF_HUGE               17
 #define KPF_UNEVICTABLE                18
+#define KPF_HWPOISON           19
 #define KPF_NOPAGE             20
+#define KPF_KSM                        21
 
 /* [32-] kernel hacking assistances */
 #define KPF_RESERVED           32
@@ -116,7 +121,9 @@ static char *page_flag_names[] = {
        [KPF_COMPOUND_TAIL]     = "T:compound_tail",
        [KPF_HUGE]              = "G:huge",
        [KPF_UNEVICTABLE]       = "u:unevictable",
+       [KPF_HWPOISON]          = "X:hwpoison",
        [KPF_NOPAGE]            = "n:nopage",
+       [KPF_KSM]               = "x:ksm",
 
        [KPF_RESERVED]          = "r:reserved",
        [KPF_MLOCKED]           = "m:mlocked",
@@ -152,9 +159,6 @@ static unsigned long        opt_size[MAX_ADDR_RANGES];
 static int             nr_vmas;
 static unsigned long   pg_start[MAX_VMAS];
 static unsigned long   pg_end[MAX_VMAS];
-static unsigned long   voffset;
-
-static int             pagemap_fd;
 
 #define MAX_BIT_FILTERS        64
 static int             nr_bit_filters;
@@ -163,9 +167,16 @@ static uint64_t            opt_bits[MAX_BIT_FILTERS];
 
 static int             page_size;
 
-#define PAGES_BATCH    (64 << 10)      /* 64k pages */
+static int             pagemap_fd;
 static int             kpageflags_fd;
 
+static int             opt_hwpoison;
+static int             opt_unpoison;
+
+static char            *hwpoison_debug_fs = "/debug/hwpoison";
+static int             hwpoison_inject_fd;
+static int             hwpoison_forget_fd;
+
 #define HASH_SHIFT     13
 #define HASH_SIZE      (1 << HASH_SHIFT)
 #define HASH_MASK      (HASH_SIZE - 1)
@@ -207,6 +218,74 @@ static void fatal(const char *x, ...)
        exit(EXIT_FAILURE);
 }
 
+int checked_open(const char *pathname, int flags)
+{
+       int fd = open(pathname, flags);
+
+       if (fd < 0) {
+               perror(pathname);
+               exit(EXIT_FAILURE);
+       }
+
+       return fd;
+}
+
+/*
+ * pagemap/kpageflags routines
+ */
+
+static unsigned long do_u64_read(int fd, char *name,
+                                uint64_t *buf,
+                                unsigned long index,
+                                unsigned long count)
+{
+       long bytes;
+
+       if (index > ULONG_MAX / 8)
+               fatal("index overflow: %lu\n", index);
+
+       if (lseek(fd, index * 8, SEEK_SET) < 0) {
+               perror(name);
+               exit(EXIT_FAILURE);
+       }
+
+       bytes = read(fd, buf, count * 8);
+       if (bytes < 0) {
+               perror(name);
+               exit(EXIT_FAILURE);
+       }
+       if (bytes % 8)
+               fatal("partial read: %lu bytes\n", bytes);
+
+       return bytes / 8;
+}
+
+static unsigned long kpageflags_read(uint64_t *buf,
+                                    unsigned long index,
+                                    unsigned long pages)
+{
+       return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages);
+}
+
+static unsigned long pagemap_read(uint64_t *buf,
+                                 unsigned long index,
+                                 unsigned long pages)
+{
+       return do_u64_read(pagemap_fd, "/proc/pid/pagemap", buf, index, pages);
+}
+
+static unsigned long pagemap_pfn(uint64_t val)
+{
+       unsigned long pfn;
+
+       if (val & PM_PRESENT)
+               pfn = PM_PFRAME(val);
+       else
+               pfn = 0;
+
+       return pfn;
+}
+
 
 /*
  * page flag names
@@ -255,7 +334,8 @@ static char *page_flag_longname(uint64_t flags)
  * page list and summary
  */
 
-static void show_page_range(unsigned long offset, uint64_t flags)
+static void show_page_range(unsigned long voffset,
+                           unsigned long offset, uint64_t flags)
 {
        static uint64_t      flags0;
        static unsigned long voff;
@@ -281,7 +361,8 @@ static void show_page_range(unsigned long offset, uint64_t flags)
        count  = 1;
 }
 
-static void show_page(unsigned long offset, uint64_t flags)
+static void show_page(unsigned long voffset,
+                     unsigned long offset, uint64_t flags)
 {
        if (opt_pid)
                printf("%lx\t", voffset);
@@ -362,6 +443,62 @@ static uint64_t well_known_flags(uint64_t flags)
        return flags;
 }
 
+static uint64_t kpageflags_flags(uint64_t flags)
+{
+       flags = expand_overloaded_flags(flags);
+
+       if (!opt_raw)
+               flags = well_known_flags(flags);
+
+       return flags;
+}
+
+/*
+ * page actions
+ */
+
+static void prepare_hwpoison_fd(void)
+{
+       char buf[100];
+
+       if (opt_hwpoison && !hwpoison_inject_fd) {
+               sprintf(buf, "%s/corrupt-pfn", hwpoison_debug_fs);
+               hwpoison_inject_fd = checked_open(buf, O_WRONLY);
+       }
+
+       if (opt_unpoison && !hwpoison_forget_fd) {
+               sprintf(buf, "%s/renew-pfn", hwpoison_debug_fs);
+               hwpoison_forget_fd = checked_open(buf, O_WRONLY);
+       }
+}
+
+static int hwpoison_page(unsigned long offset)
+{
+       char buf[100];
+       int len;
+
+       len = sprintf(buf, "0x%lx\n", offset);
+       len = write(hwpoison_inject_fd, buf, len);
+       if (len < 0) {
+               perror("hwpoison inject");
+               return len;
+       }
+       return 0;
+}
+
+static int unpoison_page(unsigned long offset)
+{
+       char buf[100];
+       int len;
+
+       len = sprintf(buf, "0x%lx\n", offset);
+       len = write(hwpoison_forget_fd, buf, len);
+       if (len < 0) {
+               perror("hwpoison forget");
+               return len;
+       }
+       return 0;
+}
 
 /*
  * page frame walker
@@ -394,104 +531,83 @@ static int hash_slot(uint64_t flags)
        exit(EXIT_FAILURE);
 }
 
-static void add_page(unsigned long offset, uint64_t flags)
+static void add_page(unsigned long voffset,
+                    unsigned long offset, uint64_t flags)
 {
-       flags = expand_overloaded_flags(flags);
-
-       if (!opt_raw)
-               flags = well_known_flags(flags);
+       flags = kpageflags_flags(flags);
 
        if (!bit_mask_ok(flags))
                return;
 
+       if (opt_hwpoison)
+               hwpoison_page(offset);
+       if (opt_unpoison)
+               unpoison_page(offset);
+
        if (opt_list == 1)
-               show_page_range(offset, flags);
+               show_page_range(voffset, offset, flags);
        else if (opt_list == 2)
-               show_page(offset, flags);
+               show_page(voffset, offset, flags);
 
        nr_pages[hash_slot(flags)]++;
        total_pages++;
 }
 
-static void walk_pfn(unsigned long index, unsigned long count)
+#define KPAGEFLAGS_BATCH       (64 << 10)      /* 64k pages */
+static void walk_pfn(unsigned long voffset,
+                    unsigned long index,
+                    unsigned long count)
 {
+       uint64_t buf[KPAGEFLAGS_BATCH];
        unsigned long batch;
-       unsigned long n;
+       unsigned long pages;
        unsigned long i;
 
-       if (index > ULONG_MAX / KPF_BYTES)
-               fatal("index overflow: %lu\n", index);
-
-       lseek(kpageflags_fd, index * KPF_BYTES, SEEK_SET);
-
        while (count) {
-               uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH];
-
-               batch = min_t(unsigned long, count, PAGES_BATCH);
-               n = read(kpageflags_fd, kpageflags_buf, batch * KPF_BYTES);
-               if (n == 0)
+               batch = min_t(unsigned long, count, KPAGEFLAGS_BATCH);
+               pages = kpageflags_read(buf, index, batch);
+               if (pages == 0)
                        break;
-               if (n < 0) {
-                       perror(PROC_KPAGEFLAGS);
-                       exit(EXIT_FAILURE);
-               }
 
-               if (n % KPF_BYTES != 0)
-                       fatal("partial read: %lu bytes\n", n);
-               n = n / KPF_BYTES;
+               for (i = 0; i < pages; i++)
+                       add_page(voffset + i, index + i, buf[i]);
 
-               for (i = 0; i < n; i++)
-                       add_page(index + i, kpageflags_buf[i]);
-
-               index += batch;
-               count -= batch;
+               index += pages;
+               count -= pages;
        }
 }
 
-
-#define PAGEMAP_BATCH  4096
-static unsigned long task_pfn(unsigned long pgoff)
+#define PAGEMAP_BATCH  (64 << 10)
+static void walk_vma(unsigned long index, unsigned long count)
 {
-       static uint64_t buf[PAGEMAP_BATCH];
-       static unsigned long start;
-       static long count;
-       uint64_t pfn;
+       uint64_t buf[PAGEMAP_BATCH];
+       unsigned long batch;
+       unsigned long pages;
+       unsigned long pfn;
+       unsigned long i;
 
-       if (pgoff < start || pgoff >= start + count) {
-               if (lseek64(pagemap_fd,
-                           (uint64_t)pgoff * PM_ENTRY_BYTES,
-                           SEEK_SET) < 0) {
-                       perror("pagemap seek");
-                       exit(EXIT_FAILURE);
-               }
-               count = read(pagemap_fd, buf, sizeof(buf));
-               if (count == 0)
-                       return 0;
-               if (count < 0) {
-                       perror("pagemap read");
-                       exit(EXIT_FAILURE);
-               }
-               if (count % PM_ENTRY_BYTES) {
-                       fatal("pagemap read not aligned.\n");
-                       exit(EXIT_FAILURE);
-               }
-               count /= PM_ENTRY_BYTES;
-               start = pgoff;
-       }
+       while (count) {
+               batch = min_t(unsigned long, count, PAGEMAP_BATCH);
+               pages = pagemap_read(buf, index, batch);
+               if (pages == 0)
+                       break;
 
-       pfn = buf[pgoff - start];
-       if (pfn & PM_PRESENT)
-               pfn = PM_PFRAME(pfn);
-       else
-               pfn = 0;
+               for (i = 0; i < pages; i++) {
+                       pfn = pagemap_pfn(buf[i]);
+                       if (pfn)
+                               walk_pfn(index + i, pfn, 1);
+               }
 
-       return pfn;
+               index += pages;
+               count -= pages;
+       }
 }
 
 static void walk_task(unsigned long index, unsigned long count)
 {
-       int i = 0;
        const unsigned long end = index + count;
+       unsigned long start;
+       int i = 0;
 
        while (index < end) {
 
@@ -501,15 +617,11 @@ static void walk_task(unsigned long index, unsigned long count)
                if (pg_start[i] >= end)
                        return;
 
-               voffset = max_t(unsigned long, pg_start[i], index);
-               index   = min_t(unsigned long, pg_end[i], end);
+               start = max_t(unsigned long, pg_start[i], index);
+               index = min_t(unsigned long, pg_end[i], end);
 
-               assert(voffset < index);
-               for (; voffset < index; voffset++) {
-                       unsigned long pfn = task_pfn(voffset);
-                       if (pfn)
-                               walk_pfn(pfn, 1);
-               }
+               assert(start < index);
+               walk_vma(start, index - start);
        }
 }
 
@@ -527,18 +639,14 @@ static void walk_addr_ranges(void)
 {
        int i;
 
-       kpageflags_fd = open(PROC_KPAGEFLAGS, O_RDONLY);
-       if (kpageflags_fd < 0) {
-               perror(PROC_KPAGEFLAGS);
-               exit(EXIT_FAILURE);
-       }
+       kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY);
 
        if (!nr_addr_ranges)
                add_addr_range(0, ULONG_MAX);
 
        for (i = 0; i < nr_addr_ranges; i++)
                if (!opt_pid)
-                       walk_pfn(opt_offset[i], opt_size[i]);
+                       walk_pfn(0, opt_offset[i], opt_size[i]);
                else
                        walk_task(opt_offset[i], opt_size[i]);
 
@@ -575,6 +683,8 @@ static void usage(void)
 "            -l|--list                 Show page details in ranges\n"
 "            -L|--list-each            Show page details one by one\n"
 "            -N|--no-summary           Don't show summay info\n"
+"            -X|--hwpoison             hwpoison pages\n"
+"            -x|--unpoison             unpoison pages\n"
 "            -h|--help                 Show this usage message\n"
 "addr-spec:\n"
 "            N                         one page at offset N (unit: pages)\n"
@@ -624,11 +734,7 @@ static void parse_pid(const char *str)
        opt_pid = parse_number(str);
 
        sprintf(buf, "/proc/%d/pagemap", opt_pid);
-       pagemap_fd = open(buf, O_RDONLY);
-       if (pagemap_fd < 0) {
-               perror(buf);
-               exit(EXIT_FAILURE);
-       }
+       pagemap_fd = checked_open(buf, O_RDONLY);
 
        sprintf(buf, "/proc/%d/maps", opt_pid);
        file = fopen(buf, "r");
@@ -788,6 +894,8 @@ static struct option opts[] = {
        { "list"      , 0, NULL, 'l' },
        { "list-each" , 0, NULL, 'L' },
        { "no-summary", 0, NULL, 'N' },
+       { "hwpoison"  , 0, NULL, 'X' },
+       { "unpoison"  , 0, NULL, 'x' },
        { "help"      , 0, NULL, 'h' },
        { NULL        , 0, NULL, 0 }
 };
@@ -799,7 +907,7 @@ int main(int argc, char *argv[])
        page_size = getpagesize();
 
        while ((c = getopt_long(argc, argv,
-                               "rp:f:a:b:lLNh", opts, NULL)) != -1) {
+                               "rp:f:a:b:lLNXxh", opts, NULL)) != -1) {
                switch (c) {
                case 'r':
                        opt_raw = 1;
@@ -825,6 +933,14 @@ int main(int argc, char *argv[])
                case 'N':
                        opt_no_summary = 1;
                        break;
+               case 'X':
+                       opt_hwpoison = 1;
+                       prepare_hwpoison_fd();
+                       break;
+               case 'x':
+                       opt_unpoison = 1;
+                       prepare_hwpoison_fd();
+                       break;
                case 'h':
                        usage();
                        exit(0);
@@ -844,7 +960,7 @@ int main(int argc, char *argv[])
        walk_addr_ranges();
 
        if (opt_list == 1)
-               show_page_range(0, 0);  /* drain the buffer */
+               show_page_range(0, 0, 0);  /* drain the buffer */
 
        if (opt_no_summary)
                return 0;
index 600a304..df09b96 100644 (file)
@@ -57,7 +57,9 @@ There are three components to pagemap:
     16. COMPOUND_TAIL
     16. HUGE
     18. UNEVICTABLE
+    19. HWPOISON
     20. NOPAGE
+    21. KSM
 
 Short descriptions to the page flags:
 
@@ -86,9 +88,15 @@ Short descriptions to the page flags:
 17. HUGE
     this is an integral part of a HugeTLB page
 
+19. HWPOISON
+    hardware detected memory corruption on this page: don't touch the data!
+
 20. NOPAGE
     no page frame exists at the requested address
 
+21. KSM
+    identical memory pages dynamically shared between one or more processes
+
     [IO related page flags]
  1. ERROR     IO error occurred
  3. UPTODATE  page has up-to-date data
index 09a2028..e1da925 100644 (file)
@@ -3643,6 +3643,13 @@ F:       Documentation/blockdev/nbd.txt
 F:     drivers/block/nbd.c
 F:     include/linux/nbd.h
 
+NETWORK DROP MONITOR
+M:     Neil Horman <nhorman@tuxdriver.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+W:     https://fedorahosted.org/dropwatch/
+F:     net/core/drop_monitor.c
+
 NETWORKING [GENERAL]
 M:     "David S. Miller" <davem@davemloft.net>
 L:     netdev@vger.kernel.org
@@ -3973,6 +3980,7 @@ F:        drivers/block/paride/
 PARISC ARCHITECTURE
 M:     Kyle McMartin <kyle@mcmartin.ca>
 M:     Helge Deller <deller@gmx.de>
+M:     "James E.J. Bottomley" <jejb@parisc-linux.org>
 L:     linux-parisc@vger.kernel.org
 W:     http://www.parisc-linux.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
index fafcd32..489556e 100644 (file)
@@ -338,6 +338,13 @@ static struct omap_clk omap34xx_clks[] = {
  */
 #define SDRC_MPURATE_LOOPS             96
 
+/*
+ * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
+ * that are sourced by DPLL5, and both of these require this clock
+ * to be at 120 MHz for proper operation.
+ */
+#define DPLL5_FREQ_FOR_USBHOST         120000000
+
 /**
  * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
  * @clk: struct clk * being enabled
@@ -1056,6 +1063,28 @@ void omap2_clk_prepare_for_reboot(void)
 #endif
 }
 
+static void omap3_clk_lock_dpll5(void)
+{
+       struct clk *dpll5_clk;
+       struct clk *dpll5_m2_clk;
+
+       dpll5_clk = clk_get(NULL, "dpll5_ck");
+       clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
+       clk_enable(dpll5_clk);
+
+       /* Enable autoidle to allow it to enter low power bypass */
+       omap3_dpll_allow_idle(dpll5_clk);
+
+       /* Program dpll5_m2_clk divider for no division */
+       dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+       clk_enable(dpll5_m2_clk);
+       clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
+
+       clk_disable(dpll5_m2_clk);
+       clk_disable(dpll5_clk);
+       return;
+}
+
 /* REVISIT: Move this init stuff out into clock.c */
 
 /*
@@ -1148,6 +1177,12 @@ int __init omap2_clk_init(void)
         */
        clk_enable_init_clocks();
 
+       /*
+        * Lock DPLL5 and put it in autoidle.
+        */
+       if (omap_rev() >= OMAP3430_REV_ES2_0)
+               omap3_clk_lock_dpll5();
+
        /* Avoid sleeping during omap2_clk_prepare_for_reboot() */
        /* REVISIT: not yet ready for 343x */
 #if 0
index 1b4c160..2fc4d6a 100644 (file)
@@ -541,7 +541,7 @@ static int __init pm_dbg_init(void)
                printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
                return -ENODEV;
        }
-               
+
        d = debugfs_create_dir("pm_debug", NULL);
        if (IS_ERR(d))
                return PTR_ERR(d);
@@ -551,7 +551,7 @@ static int __init pm_dbg_init(void)
        (void) debugfs_create_file("time", S_IRUGO,
                d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
 
-       pwrdm_for_each(pwrdms_setup, (void *)d);
+       pwrdm_for_each_nolock(pwrdms_setup, (void *)d);
 
        pm_dbg_dir = debugfs_create_dir("registers", d);
        if (IS_ERR(pm_dbg_dir))
index 0ff5a6c..378c2f6 100644 (file)
@@ -51,97 +51,112 @@ static void (*_omap_sram_idle)(u32 *addr, int save_state);
 
 static struct powerdomain *mpu_pwrdm;
 
-/* PRCM Interrupt Handler for wakeups */
-static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+/*
+ * PRCM Interrupt Handler Helper Function
+ *
+ * The purpose of this function is to clear any wake-up events latched
+ * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
+ * may occur whilst attempting to clear a PM_WKST_x register and thus
+ * set another bit in this register. A while loop is used to ensure
+ * that any peripheral wake-up events occurring while attempting to
+ * clear the PM_WKST_x are detected and cleared.
+ */
+static int prcm_clear_mod_irqs(s16 module, u8 regs)
 {
-       u32 wkst, irqstatus_mpu;
-       u32 fclk, iclk;
-
-       /* WKUP */
-       wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
+       u32 wkst, fclk, iclk, clken;
+       u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
+       u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
+       u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
+       u16 grpsel_off = (regs == 3) ?
+               OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
+       int c = 0;
+
+       wkst = prm_read_mod_reg(module, wkst_off);
+       wkst &= prm_read_mod_reg(module, grpsel_off);
        if (wkst) {
-               iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
-               fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
-               cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN);
-               cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN);
-               prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST);
-               while (prm_read_mod_reg(WKUP_MOD, PM_WKST))
-                       cpu_relax();
-               cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN);
-               cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN);
+               iclk = cm_read_mod_reg(module, iclk_off);
+               fclk = cm_read_mod_reg(module, fclk_off);
+               while (wkst) {
+                       clken = wkst;
+                       cm_set_mod_reg_bits(clken, module, iclk_off);
+                       /*
+                        * For USBHOST, we don't know whether HOST1 or
+                        * HOST2 woke us up, so enable both f-clocks
+                        */
+                       if (module == OMAP3430ES2_USBHOST_MOD)
+                               clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
+                       cm_set_mod_reg_bits(clken, module, fclk_off);
+                       prm_write_mod_reg(wkst, module, wkst_off);
+                       wkst = prm_read_mod_reg(module, wkst_off);
+                       c++;
+               }
+               cm_write_mod_reg(iclk, module, iclk_off);
+               cm_write_mod_reg(fclk, module, fclk_off);
        }
 
-       /* CORE */
-       wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1);
-       if (wkst) {
-               iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
-               fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
-               cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
-               cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
-               prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
-               while (prm_read_mod_reg(CORE_MOD, PM_WKST1))
-                       cpu_relax();
-               cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
-               cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
-       }
-       wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
-       if (wkst) {
-               iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
-               fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
-               cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
-               cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
-               prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
-               while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3))
-                       cpu_relax();
-               cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
-               cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
-       }
+       return c;
+}
 
-       /* PER */
-       wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST);
-       if (wkst) {
-               iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
-               fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
-               cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
-               cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
-               prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
-               while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST))
-                       cpu_relax();
-               cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
-               cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
-       }
+static int _prcm_int_handle_wakeup(void)
+{
+       int c;
 
+       c = prcm_clear_mod_irqs(WKUP_MOD, 1);
+       c += prcm_clear_mod_irqs(CORE_MOD, 1);
+       c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
        if (omap_rev() > OMAP3430_REV_ES1_0) {
-               /* USBHOST */
-               wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST);
-               if (wkst) {
-                       iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-                                              CM_ICLKEN);
-                       fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-                                              CM_FCLKEN);
-                       cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
-                                           CM_ICLKEN);
-                       cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
-                                           CM_FCLKEN);
-                       prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
-                                         PM_WKST);
-                       while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-                                               PM_WKST))
-                               cpu_relax();
-                       cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
-                                        CM_ICLKEN);
-                       cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
-                                        CM_FCLKEN);
-               }
+               c += prcm_clear_mod_irqs(CORE_MOD, 3);
+               c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
        }
 
-       irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
-                                        OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-       prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
-                         OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+       return c;
+}
+
+/*
+ * PRCM Interrupt Handler
+ *
+ * The PRM_IRQSTATUS_MPU register indicates if there are any pending
+ * interrupts from the PRCM for the MPU. These bits must be cleared in
+ * order to clear the PRCM interrupt. The PRCM interrupt handler is
+ * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
+ * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
+ * register indicates that a wake-up event is pending for the MPU and
+ * this bit can only be cleared if the all the wake-up events latched
+ * in the various PM_WKST_x registers have been cleared. The interrupt
+ * handler is implemented using a do-while loop so that if a wake-up
+ * event occurred during the processing of the prcm interrupt handler
+ * (setting a bit in the corresponding PM_WKST_x register and thus
+ * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
+ * this would be handled.
+ */
+static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+{
+       u32 irqstatus_mpu;
+       int c = 0;
+
+       do {
+               irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
+                                       OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+               if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) {
+                       c = _prcm_int_handle_wakeup();
+
+                       /*
+                        * Is the MPU PRCM interrupt handler racing with the
+                        * IVA2 PRCM interrupt handler ?
+                        */
+                       WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
+                            "but no wakeup sources are marked\n");
+               } else {
+                       /* XXX we need to expand our PRCM interrupt handler */
+                       WARN(1, "prcm: WARNING: PRCM interrupt received, but "
+                            "no code to handle it (%08x)\n", irqstatus_mpu);
+               }
+
+               prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
+                                       OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-       while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET))
-               cpu_relax();
+       } while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
 
        return IRQ_HANDLED;
 }
@@ -624,6 +639,16 @@ static void __init prcm_setup_regs(void)
        prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
                          OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 
+       /* Enable GPIO wakeups in PER */
+       prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
+                         OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
+                         OMAP3430_EN_GPIO6, OMAP3430_PER_MOD, PM_WKEN);
+       /* and allow them to wake up MPU */
+       prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
+                         OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
+                         OMAP3430_GRPSEL_GPIO6,
+                         OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
+
        /* Don't attach IVA interrupts */
        prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
        prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
index 2594cbf..f00289a 100644 (file)
@@ -273,35 +273,50 @@ struct powerdomain *pwrdm_lookup(const char *name)
 }
 
 /**
- * pwrdm_for_each - call function on each registered clockdomain
+ * pwrdm_for_each_nolock - call function on each registered clockdomain
  * @fn: callback function *
  *
  * Call the supplied function for each registered powerdomain.  The
  * callback function can return anything but 0 to bail out early from
- * the iterator.  The callback function is called with the pwrdm_rwlock
- * held for reading, so no powerdomain structure manipulation
- * functions should be called from the callback, although hardware
- * powerdomain control functions are fine.  Returns the last return
- * value of the callback function, which should be 0 for success or
- * anything else to indicate failure; or -EINVAL if the function
- * pointer is null.
+ * the iterator.  Returns the last return value of the callback function, which
+ * should be 0 for success or anything else to indicate failure; or -EINVAL if
+ * the function pointer is null.
  */
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
-                       void *user)
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+                               void *user)
 {
        struct powerdomain *temp_pwrdm;
-       unsigned long flags;
        int ret = 0;
 
        if (!fn)
                return -EINVAL;
 
-       read_lock_irqsave(&pwrdm_rwlock, flags);
        list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
                ret = (*fn)(temp_pwrdm, user);
                if (ret)
                        break;
        }
+
+       return ret;
+}
+
+/**
+ * pwrdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * This function is the same as 'pwrdm_for_each_nolock()', but keeps the
+ * &pwrdm_rwlock locked for reading, so no powerdomain structure manipulation
+ * functions should be called from the callback, although hardware powerdomain
+ * control functions are fine.
+ */
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+                       void *user)
+{
+       unsigned long flags;
+       int ret;
+
+       read_lock_irqsave(&pwrdm_rwlock, flags);
+       ret = pwrdm_for_each_nolock(fn, user);
        read_unlock_irqrestore(&pwrdm_rwlock, flags);
 
        return ret;
index 11e73d9..f129efb 100644 (file)
@@ -303,32 +303,21 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define cpu_is_omap2430()              0
 #define cpu_is_omap3430()              0
 
-#if defined(MULTI_OMAP1)
-# if defined(CONFIG_ARCH_OMAP730)
-#  undef  cpu_is_omap730
-#  define cpu_is_omap730()             is_omap730()
-# endif
-# if defined(CONFIG_ARCH_OMAP850)
-#  undef  cpu_is_omap850
-#  define cpu_is_omap850()             is_omap850()
-# endif
-#else
-# if defined(CONFIG_ARCH_OMAP730)
-#  undef  cpu_is_omap730
-#  define cpu_is_omap730()             1
-# endif
-#endif
-#else
-# if defined(CONFIG_ARCH_OMAP850)
-#  undef  cpu_is_omap850
-#  define cpu_is_omap850()             1
-# endif
-#endif
-
 /*
  * Whether we have MULTI_OMAP1 or not, we still need to distinguish
- * between 330 vs. 1510 and 1611B/5912 vs. 1710.
+ * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710.
  */
+
+#if defined(CONFIG_ARCH_OMAP730)
+# undef  cpu_is_omap730
+# define cpu_is_omap730()              is_omap730()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP850)
+# undef  cpu_is_omap850
+# define cpu_is_omap850()              is_omap850()
+#endif
+
 #if defined(CONFIG_ARCH_OMAP15XX)
 # undef  cpu_is_omap310
 # undef  cpu_is_omap1510
@@ -433,3 +422,5 @@ IS_OMAP_TYPE(3430, 0x3430)
 
 int omap_chip_is(struct omap_chip_id oci);
 void omap2_check_revision(void);
+
+#endif
index 6271d85..fa64614 100644 (file)
@@ -135,6 +135,8 @@ struct powerdomain *pwrdm_lookup(const char *name);
 
 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
                        void *user);
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+                       void *user);
 
 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
index 57f7122..dc3fac3 100644 (file)
@@ -47,7 +47,7 @@
  *     'va':   mpu virtual address
  *
  *     'c':    contiguous memory area
- *     'd':    dicontiguous memory area
+ *     'd':    discontiguous memory area
  *     'a':    anonymous memory allocation
  *     '()':   optional feature
  *
@@ -363,8 +363,9 @@ void *da_to_va(struct iommu *obj, u32 da)
                goto out;
        }
        va = area->va;
-       mutex_unlock(&obj->mmap_lock);
 out:
+       mutex_unlock(&obj->mmap_lock);
+
        return va;
 }
 EXPORT_SYMBOL_GPL(da_to_va);
@@ -398,7 +399,7 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
 {
        /*
         * Actually this is not necessary at all, just exists for
-        * consistency of the code readibility.
+        * consistency of the code readability.
         */
        BUG_ON(!sgt);
 }
@@ -434,7 +435,7 @@ static inline void sgtable_drain_kmalloc(struct sg_table *sgt)
 {
        /*
         * Actually this is not necessary at all, just exists for
-        * consistency of the code readibility
+        * consistency of the code readability
         */
        BUG_ON(!sgt);
 }
index 925f647..75d1f26 100644 (file)
@@ -270,7 +270,8 @@ void * omap_sram_push(void * start, unsigned long size)
        omap_sram_ceil -= size;
        omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
        memcpy((void *)omap_sram_ceil, start, size);
-       flush_icache_range((unsigned long)start, (unsigned long)(start + size));
+       flush_icache_range((unsigned long)omap_sram_ceil,
+               (unsigned long)(omap_sram_ceil + size));
 
        return (void *)omap_sram_ceil;
 }
index f388dc6..524d935 100644 (file)
@@ -18,6 +18,7 @@ config PARISC
        select BUG
        select HAVE_PERF_EVENTS
        select GENERIC_ATOMIC64 if !64BIT
+       select HAVE_ARCH_TRACEHOOK
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
          in many of their workstations & servers (HP9000 700 and 800 series,
index de3fe3a..6fec4d4 100644 (file)
@@ -21,9 +21,9 @@
 #define KERNEL_MAP_END         (TMPALIAS_MAP_START)
 
 #ifndef __ASSEMBLY__
-extern void *vmalloc_start;
+extern void *parisc_vmalloc_start;
 #define PCXL_DMA_MAP_SIZE      (8*1024*1024)
-#define VMALLOC_START          ((unsigned long)vmalloc_start)
+#define VMALLOC_START          ((unsigned long)parisc_vmalloc_start)
 #define VMALLOC_END            (KERNEL_MAP_END)
 #endif /*__ASSEMBLY__*/
 
index ce93133..0d68184 100644 (file)
@@ -1,29 +1,11 @@
 /* hardirq.h: PA-RISC hard IRQ support.
  *
  * Copyright (C) 2001 Matthew Wilcox <matthew@wil.cx>
- *
- * The locking is really quite interesting.  There's a cpu-local
- * count of how many interrupts are being handled, and a global
- * lock.  An interrupt can only be serviced if the global lock
- * is free.  You can't be sure no more interrupts are being
- * serviced until you've acquired the lock and then checked
- * all the per-cpu interrupt counts are all zero.  It's a specialised
- * br_lock, and that's exactly how Sparc does it.  We don't because
- * it's more locking for us.  This way is lock-free in the interrupt path.
  */
 
 #ifndef _PARISC_HARDIRQ_H
 #define _PARISC_HARDIRQ_H
 
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-typedef struct {
-       unsigned long __softirq_pending; /* set_bit is used on this */
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
-void ack_bad_irq(unsigned int irq);
+#include <asm-generic/hardirq.h>
 
 #endif /* _PARISC_HARDIRQ_H */
index 302f68d..aead40b 100644 (file)
@@ -59,8 +59,11 @@ void user_enable_block_step(struct task_struct *task);
 #define user_mode(regs)                        (((regs)->iaoq[0] & 3) ? 1 : 0)
 #define user_space(regs)               (((regs)->iasq[1] != 0) ? 1 : 0)
 #define instruction_pointer(regs)      ((regs)->iaoq[0] & ~3)
+#define user_stack_pointer(regs)       ((regs)->gr[30])
 unsigned long profile_pc(struct pt_regs *);
 extern void show_regs(struct pt_regs *);
-#endif
+
+
+#endif /* __KERNEL__ */
 
 #endif
diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..8bdfd2c
--- /dev/null
@@ -0,0 +1,40 @@
+/* syscall.h */
+
+#ifndef _ASM_PARISC_SYSCALL_H_
+#define _ASM_PARISC_SYSCALL_H_
+
+#include <linux/err.h>
+#include <asm/ptrace.h>
+
+static inline long syscall_get_nr(struct task_struct *tsk,
+                                 struct pt_regs *regs)
+{
+       return regs->gr[20];
+}
+
+static inline void syscall_get_arguments(struct task_struct *tsk,
+                                        struct pt_regs *regs, unsigned int i,
+                                        unsigned int n, unsigned long *args)
+{
+       BUG_ON(i);
+
+       switch (n) {
+       case 6:
+               args[5] = regs->gr[21];
+       case 5:
+               args[4] = regs->gr[22];
+       case 4:
+               args[3] = regs->gr[23];
+       case 3:
+               args[2] = regs->gr[24];
+       case 2:
+               args[1] = regs->gr[25];
+       case 1:
+               args[0] = regs->gr[26];
+               break;
+       default:
+               BUG();
+       }
+}
+
+#endif /*_ASM_PARISC_SYSCALL_H_*/
index ac775a7..7ecc103 100644 (file)
@@ -32,6 +32,11 @@ struct thread_info {
 #define init_thread_info        (init_thread_union.thread_info)
 #define init_stack              (init_thread_union.stack)
 
+/* how to get the thread information struct from C */
+#define current_thread_info()  ((struct thread_info *)mfctl(30))
+
+#endif /* !__ASSEMBLY */
+
 /* thread information allocation */
 
 #define THREAD_SIZE_ORDER            2
@@ -40,11 +45,6 @@ struct thread_info {
 #define THREAD_SIZE             (PAGE_SIZE << THREAD_SIZE_ORDER)
 #define THREAD_SHIFT            (PAGE_SHIFT + THREAD_SIZE_ORDER)
 
-/* how to get the thread information struct from C */
-#define current_thread_info()  ((struct thread_info *)mfctl(30))
-
-#endif /* !__ASSEMBLY */
-
 #define PREEMPT_ACTIVE_BIT     28
 #define PREEMPT_ACTIVE         (1 << PREEMPT_ACTIVE_BIT)
 
@@ -60,6 +60,8 @@ struct thread_info {
 #define TIF_RESTORE_SIGMASK    6       /* restore saved signal mask */
 #define TIF_FREEZE             7       /* is freezing for suspend */
 #define TIF_NOTIFY_RESUME      8       /* callback before returning to user */
+#define TIF_SINGLESTEP         9       /* single stepping? */
+#define TIF_BLOCKSTEP          10      /* branch stepping? */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
@@ -69,6 +71,8 @@ struct thread_info {
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
+#define _TIF_BLOCKSTEP         (1 << TIF_BLOCKSTEP)
 
 #define _TIF_USER_WORK_MASK     (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
                                  _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
index 699cf8e..fcd3c70 100644 (file)
@@ -270,8 +270,8 @@ int main(void)
        DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count));
        DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop));
        BLANK();
-       DEFINE(PA_BLOCKSTEP_BIT, 31-PT_BLOCKSTEP_BIT);
-       DEFINE(PA_SINGLESTEP_BIT, 31-PT_SINGLESTEP_BIT);
+       DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP);
+       DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP);
        BLANK();
        DEFINE(ASM_PMD_SHIFT, PMD_SHIFT);
        DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT);
index 8c4712b..3a44f7f 100644 (file)
@@ -2047,12 +2047,13 @@ syscall_do_signal:
        b,n     syscall_check_sig
 
 syscall_restore:
-       /* Are we being ptraced? */
        LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
 
-       ldw     TASK_PTRACE(%r1), %r19
-       bb,<    %r19,31,syscall_restore_rfi
-       nop
+       /* Are we being ptraced? */
+       ldw     TASK_FLAGS(%r1),%r19
+       ldi     (_TIF_SINGLESTEP|_TIF_BLOCKSTEP),%r2
+       and,COND(=)     %r19,%r2,%r0
+       b,n     syscall_restore_rfi
 
        ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
        rest_fp %r19
@@ -2113,16 +2114,16 @@ syscall_restore_rfi:
        ldi     0x0b,%r20                          /* Create new PSW */
        depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
 
-       /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
-        * set in include/linux/ptrace.h and converted to PA bitmap
+       /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
+        * set in thread_info.h and converted to PA bitmap
         * numbers in asm-offsets.c */
 
-       /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
-       extru,= %r19,PA_SINGLESTEP_BIT,1,%r0
+       /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
+       extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
        depi    -1,27,1,%r20                       /* R bit */
 
-       /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
-       extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
+       /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
+       extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
        depi    -1,7,1,%r20                        /* T bit */
 
        STREG   %r20,TASK_PT_PSW(%r1)
index 330f536..2e7610c 100644 (file)
@@ -423,8 +423,3 @@ void __init init_IRQ(void)
         set_eiem(cpu_eiem);    /* EIEM : enable all external intr */
 
 }
-
-void ack_bad_irq(unsigned int irq)
-{
-       printk(KERN_WARNING "unexpected IRQ %d\n", irq);
-}
index 61ee0ee..2120746 100644 (file)
@@ -893,7 +893,7 @@ int module_finalize(const Elf_Ehdr *hdr,
         * ourselves */
        for (i = 1; i < hdr->e_shnum; i++) {
                if(sechdrs[i].sh_type == SHT_SYMTAB
-                  && (sechdrs[i].sh_type & SHF_ALLOC)) {
+                  && (sechdrs[i].sh_flags & SHF_ALLOC)) {
                        int strindex = sechdrs[i].sh_link;
                        /* FIXME: AWFUL HACK
                         * The cast is to drop the const from
index 927db36..c4f49e4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/user.h>
 #include <linux/personality.h>
 #include <linux/security.h>
@@ -35,7 +36,8 @@
  */
 void ptrace_disable(struct task_struct *task)
 {
-       task->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
+       clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+       clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
 
        /* make sure the trap bits are not set */
        pa_psw(task)->r = 0;
@@ -55,8 +57,8 @@ void user_disable_single_step(struct task_struct *task)
 
 void user_enable_single_step(struct task_struct *task)
 {
-       task->ptrace &= ~PT_BLOCKSTEP;
-       task->ptrace |= PT_SINGLESTEP;
+       clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
+       set_tsk_thread_flag(task, TIF_SINGLESTEP);
 
        if (pa_psw(task)->n) {
                struct siginfo si;
@@ -98,8 +100,8 @@ void user_enable_single_step(struct task_struct *task)
 
 void user_enable_block_step(struct task_struct *task)
 {
-       task->ptrace &= ~PT_SINGLESTEP;
-       task->ptrace |= PT_BLOCKSTEP;
+       clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+       set_tsk_thread_flag(task, TIF_BLOCKSTEP);
 
        /* Enable taken branch trap. */
        pa_psw(task)->r = 0;
@@ -263,22 +265,20 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 }
 #endif
 
+long do_syscall_trace_enter(struct pt_regs *regs)
+{
+       if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+           tracehook_report_syscall_entry(regs))
+               return -1L;
+
+       return regs->gr[20];
+}
 
-void syscall_trace(void)
+void do_syscall_trace_exit(struct pt_regs *regs)
 {
-       if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
-       if (!(current->ptrace & PT_PTRACED))
-               return;
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-                                ? 0x80 : 0));
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
+       int stepping = test_thread_flag(TIF_SINGLESTEP) ||
+               test_thread_flag(TIF_BLOCKSTEP);
+
+       if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(regs, stepping);
 }
index 8eb3c63..e8467e4 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/compat.h>
@@ -34,7 +35,6 @@
 #include <asm/asm-offsets.h>
 
 #ifdef CONFIG_COMPAT
-#include <linux/compat.h>
 #include "signal32.h"
 #endif
 
@@ -468,6 +468,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
                sigaddset(&current->blocked,sig);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
+
+       tracehook_signal_handler(sig, info, ka, regs, 0);
+
        return 1;
 }
 
index 59fc1a4..f5f9602 100644 (file)
@@ -288,18 +288,23 @@ tracesys:
        STREG   %r18,PT_GR18(%r2)
        /* Finished saving things for the debugger */
 
-       ldil    L%syscall_trace,%r1
+       copy    %r2,%r26
+       ldil    L%do_syscall_trace_enter,%r1
        ldil    L%tracesys_next,%r2
-       be      R%syscall_trace(%sr7,%r1)
+       be      R%do_syscall_trace_enter(%sr7,%r1)
        ldo     R%tracesys_next(%r2),%r2
        
-tracesys_next: 
+tracesys_next:
+       /* do_syscall_trace_enter either returned the syscallno, or -1L,
+        *  so we skip restoring the PT_GR20 below, since we pulled it from
+        *  task->thread.regs.gr[20] above.
+        */
+       copy    %ret0,%r20
        ldil    L%sys_call_table,%r1
        ldo     R%sys_call_table(%r1), %r19
 
        ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
        LDREG   TI_TASK(%r1), %r1
-       LDREG   TASK_PT_GR20(%r1), %r20
        LDREG   TASK_PT_GR26(%r1), %r26         /* Restore the users args */
        LDREG   TASK_PT_GR25(%r1), %r25
        LDREG   TASK_PT_GR24(%r1), %r24
@@ -336,7 +341,8 @@ tracesys_exit:
 #ifdef CONFIG_64BIT
        ldo     -16(%r30),%r29                  /* Reference param save area */
 #endif
-       bl      syscall_trace, %r2
+       ldo     TASK_REGS(%r1),%r26
+       bl      do_syscall_trace_exit,%r2
        STREG   %r28,TASK_PT_GR28(%r1)          /* save return value now */
        ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
        LDREG   TI_TASK(%r1), %r1
@@ -353,12 +359,12 @@ tracesys_exit:
 
 tracesys_sigexit:
        ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
-       LDREG   0(%r1), %r1
+       LDREG   TI_TASK(%r1), %r1
 #ifdef CONFIG_64BIT
        ldo     -16(%r30),%r29                  /* Reference param save area */
 #endif
-       bl      syscall_trace, %r2
-       nop
+       bl      do_syscall_trace_exit,%r2
+       ldo     TASK_REGS(%r1),%r26
 
        ldil    L%syscall_exit_rfi,%r1
        be,n    R%syscall_exit_rfi(%sr7,%r1)
index 775be27..fda4baa 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
        
 /* ld script to make hppa Linux kernel */
 #ifndef CONFIG_64BIT
@@ -134,6 +135,15 @@ SECTIONS
        __init_begin = .;
        INIT_TEXT_SECTION(16384)
        INIT_DATA_SECTION(16)
+       /* we have to discard exit text and such at runtime, not link time */
+       .exit.text :
+       {
+               EXIT_TEXT
+       }
+       .exit.data :
+       {
+               EXIT_DATA
+       }
 
        PERCPU(PAGE_SIZE)
        . = ALIGN(PAGE_SIZE);
index d5aca31..13b6e3e 100644 (file)
@@ -434,8 +434,8 @@ void mark_rodata_ro(void)
 #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
                                     & ~(VM_MAP_OFFSET-1)))
 
-void *vmalloc_start __read_mostly;
-EXPORT_SYMBOL(vmalloc_start);
+void *parisc_vmalloc_start __read_mostly;
+EXPORT_SYMBOL(parisc_vmalloc_start);
 
 #ifdef CONFIG_PA11
 unsigned long pcxl_dma_start __read_mostly;
@@ -496,13 +496,14 @@ void __init mem_init(void)
 #ifdef CONFIG_PA11
        if (hppa_dma_ops == &pcxl_dma_ops) {
                pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START);
-               vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start + PCXL_DMA_MAP_SIZE);
+               parisc_vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start
+                                               + PCXL_DMA_MAP_SIZE);
        } else {
                pcxl_dma_start = 0;
-               vmalloc_start = SET_MAP_OFFSET(MAP_START);
+               parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
        }
 #else
-       vmalloc_start = SET_MAP_OFFSET(MAP_START);
+       parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
 #endif
 
        printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
index 60ab751..1c12921 100644 (file)
@@ -217,7 +217,7 @@ static const struct agp_bridge_driver parisc_agp_driver = {
        .configure              = parisc_agp_configure,
        .fetch_size             = parisc_agp_fetch_size,
        .tlb_flush              = parisc_agp_tlbflush,
-       .mask_memory            = parisc_agp_page_mask_memory,
+       .mask_memory            = parisc_agp_mask_memory,
        .masks                  = parisc_agp_masks,
        .agp_enable             = parisc_agp_enable,
        .cache_flush            = global_cache_flush,
index abf4a25..6069790 100644 (file)
@@ -227,7 +227,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
  * cn_proc_mcast_ctl
  * @data: message sent from userspace via the connector
  */
-static void cn_proc_mcast_ctl(struct cn_msg *msg)
+static void cn_proc_mcast_ctl(struct cn_msg *msg,
+                             struct netlink_skb_parms *nsp)
 {
        enum proc_cn_mcast_op *mc_op = NULL;
        int err = 0;
index 4e551e6..4f4ac82 100644 (file)
@@ -15,8 +15,8 @@ module_param(ecc_enable_override, int, 0644);
 
 /* Lookup table for all possible MC control instances */
 struct amd64_pvt;
-static struct mem_ctl_info *mci_lookup[MAX_NUMNODES];
-static struct amd64_pvt *pvt_lookup[MAX_NUMNODES];
+static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
+static struct amd64_pvt *pvt_lookup[EDAC_MAX_NUMNODES];
 
 /*
  * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
@@ -189,7 +189,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
 /* Map from a CSROW entry to the mask entry that operates on it */
 static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow)
 {
-       return csrow >> (pvt->num_dcsm >> 3);
+       if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F)
+               return csrow;
+       else
+               return csrow >> 1;
 }
 
 /* return the 'base' address the i'th CS entry of the 'dct' DRAM controller */
@@ -279,29 +282,26 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
        intlv_en = pvt->dram_IntlvEn[0];
 
        if (intlv_en == 0) {
-               for (node_id = 0; ; ) {
+               for (node_id = 0; node_id < DRAM_REG_COUNT; node_id++) {
                        if (amd64_base_limit_match(pvt, sys_addr, node_id))
-                               break;
-
-                       if (++node_id >= DRAM_REG_COUNT)
-                               goto err_no_match;
+                               goto found;
                }
-               goto found;
+               goto err_no_match;
        }
 
-       if (unlikely((intlv_en != (0x01 << 8)) &&
-                    (intlv_en != (0x03 << 8)) &&
-                    (intlv_en != (0x07 << 8)))) {
+       if (unlikely((intlv_en != 0x01) &&
+                    (intlv_en != 0x03) &&
+                    (intlv_en != 0x07))) {
                amd64_printk(KERN_WARNING, "junk value of 0x%x extracted from "
                             "IntlvEn field of DRAM Base Register for node 0: "
-                            "This probably indicates a BIOS bug.\n", intlv_en);
+                            "this probably indicates a BIOS bug.\n", intlv_en);
                return NULL;
        }
 
        bits = (((u32) sys_addr) >> 12) & intlv_en;
 
        for (node_id = 0; ; ) {
-               if ((pvt->dram_limit[node_id] & intlv_en) == bits)
+               if ((pvt->dram_IntlvSel[node_id] & intlv_en) == bits)
                        break;  /* intlv_sel field matches */
 
                if (++node_id >= DRAM_REG_COUNT)
@@ -311,10 +311,10 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
        /* sanity test for sys_addr */
        if (unlikely(!amd64_base_limit_match(pvt, sys_addr, node_id))) {
                amd64_printk(KERN_WARNING,
-                         "%s(): sys_addr 0x%lx falls outside base/limit "
-                         "address range for node %d with node interleaving "
-                         "enabled.\n", __func__, (unsigned long)sys_addr,
-                         node_id);
+                            "%s(): sys_addr 0x%llx falls outside base/limit "
+                            "address range for node %d with node interleaving "
+                            "enabled.\n",
+                            __func__, sys_addr, node_id);
                return NULL;
        }
 
@@ -377,7 +377,7 @@ static int input_addr_to_csrow(struct mem_ctl_info *mci, u64 input_addr)
         * base/mask register pair, test the condition shown near the start of
         * section 3.5.4 (p. 84, BKDG #26094, K8, revA-E).
         */
-       for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) {
+       for (csrow = 0; csrow < pvt->cs_count; csrow++) {
 
                /* This DRAM chip select is disabled on this node */
                if ((pvt->dcsb0[csrow] & K8_DCSB_CS_ENABLE) == 0)
@@ -734,7 +734,7 @@ static void find_csrow_limits(struct mem_ctl_info *mci, int csrow,
        u64 base, mask;
 
        pvt = mci->pvt_info;
-       BUG_ON((csrow < 0) || (csrow >= CHIPSELECT_COUNT));
+       BUG_ON((csrow < 0) || (csrow >= pvt->cs_count));
 
        base = base_from_dct_base(pvt, csrow);
        mask = mask_from_dct_mask(pvt, csrow);
@@ -962,35 +962,27 @@ err_reg:
  */
 static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt)
 {
-       if (pvt->ext_model >= OPTERON_CPU_REV_F) {
+
+       if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F) {
+               pvt->dcsb_base          = REV_E_DCSB_BASE_BITS;
+               pvt->dcsm_mask          = REV_E_DCSM_MASK_BITS;
+               pvt->dcs_mask_notused   = REV_E_DCS_NOTUSED_BITS;
+               pvt->dcs_shift          = REV_E_DCS_SHIFT;
+               pvt->cs_count           = 8;
+               pvt->num_dcsm           = 8;
+       } else {
                pvt->dcsb_base          = REV_F_F1Xh_DCSB_BASE_BITS;
                pvt->dcsm_mask          = REV_F_F1Xh_DCSM_MASK_BITS;
                pvt->dcs_mask_notused   = REV_F_F1Xh_DCS_NOTUSED_BITS;
                pvt->dcs_shift          = REV_F_F1Xh_DCS_SHIFT;
 
-               switch (boot_cpu_data.x86) {
-               case 0xf:
-                       pvt->num_dcsm = REV_F_DCSM_COUNT;
-                       break;
-
-               case 0x10:
-                       pvt->num_dcsm = F10_DCSM_COUNT;
-                       break;
-
-               case 0x11:
-                       pvt->num_dcsm = F11_DCSM_COUNT;
-                       break;
-
-               default:
-                       amd64_printk(KERN_ERR, "Unsupported family!\n");
-                       break;
+               if (boot_cpu_data.x86 == 0x11) {
+                       pvt->cs_count = 4;
+                       pvt->num_dcsm = 2;
+               } else {
+                       pvt->cs_count = 8;
+                       pvt->num_dcsm = 4;
                }
-       } else {
-               pvt->dcsb_base          = REV_E_DCSB_BASE_BITS;
-               pvt->dcsm_mask          = REV_E_DCSM_MASK_BITS;
-               pvt->dcs_mask_notused   = REV_E_DCS_NOTUSED_BITS;
-               pvt->dcs_shift          = REV_E_DCS_SHIFT;
-               pvt->num_dcsm           = REV_E_DCSM_COUNT;
        }
 }
 
@@ -1003,7 +995,7 @@ static void amd64_read_dct_base_mask(struct amd64_pvt *pvt)
 
        amd64_set_dct_base_and_mask(pvt);
 
-       for (cs = 0; cs < CHIPSELECT_COUNT; cs++) {
+       for (cs = 0; cs < pvt->cs_count; cs++) {
                reg = K8_DCSB0 + (cs * 4);
                err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
                                                &pvt->dcsb0[cs]);
@@ -1130,7 +1122,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
                debugf0("Reading K8_DRAM_BASE_LOW failed\n");
 
        /* Extract parts into separate data entries */
-       pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
+       pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 24;
        pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
        pvt->dram_rw_en[dram] = (low & 0x3);
 
@@ -1143,7 +1135,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
         * Extract parts into separate data entries. Limit is the HIGHEST memory
         * location of the region, so lower 24 bits need to be all ones
         */
-       pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF;
+       pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 24) | 0x00FFFFFF;
        pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
        pvt->dram_DstNode[dram] = (low & 0x7);
 }
@@ -1193,7 +1185,7 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
         * different from the node that detected the error.
         */
        src_mci = find_mc_by_sys_addr(mci, SystemAddress);
-       if (src_mci) {
+       if (!src_mci) {
                amd64_mc_printk(mci, KERN_ERR,
                             "failed to map error address 0x%lx to a node\n",
                             (unsigned long)SystemAddress);
@@ -1376,8 +1368,8 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
 
        pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
 
-       pvt->dram_base[dram] = (((((u64) high_base & 0x000000FF) << 32) |
-                               ((u64) low_base & 0xFFFF0000))) << 8;
+       pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
+                              (((u64)low_base  & 0xFFFF0000) << 24);
 
        low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
        high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
@@ -1398,9 +1390,9 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
         * Extract address values and form a LIMIT address. Limit is the HIGHEST
         * memory location of the region, so low 24 bits need to be all ones.
         */
-       low_limit |= 0x0000FFFF;
-       pvt->dram_limit[dram] =
-               ((((u64) high_limit << 32) + (u64) low_limit) << 8) | (0xFF);
+       pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
+                               (((u64) low_limit & 0xFFFF0000) << 24) |
+                               0x00FFFFFF;
 }
 
 static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
@@ -1566,7 +1558,7 @@ static int f10_lookup_addr_in_dct(u32 in_addr, u32 nid, u32 cs)
 
        debugf1("InputAddr=0x%x  channelselect=%d\n", in_addr, cs);
 
-       for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) {
+       for (csrow = 0; csrow < pvt->cs_count; csrow++) {
 
                cs_base = amd64_get_dct_base(pvt, cs, csrow);
                if (!(cs_base & K8_DCSB_CS_ENABLE))
@@ -2497,7 +2489,7 @@ err_reg:
  * NOTE: CPU Revision Dependent code
  *
  * Input:
- *     @csrow_nr ChipSelect Row Number (0..CHIPSELECT_COUNT-1)
+ *     @csrow_nr ChipSelect Row Number (0..pvt->cs_count-1)
  *     k8 private pointer to -->
  *                     DRAM Bank Address mapping register
  *                     node_id
@@ -2577,7 +2569,7 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
                (pvt->nbcfg & K8_NBCFG_ECC_ENABLE) ? "Enabled" : "Disabled"
                );
 
-       for (i = 0; i < CHIPSELECT_COUNT; i++) {
+       for (i = 0; i < pvt->cs_count; i++) {
                csrow = &mci->csrows[i];
 
                if ((pvt->dcsb0[i] & K8_DCSB_CS_ENABLE) == 0) {
@@ -2988,7 +2980,7 @@ static int amd64_init_2nd_stage(struct amd64_pvt *pvt)
                goto err_exit;
 
        ret = -ENOMEM;
-       mci = edac_mc_alloc(0, CHIPSELECT_COUNT, pvt->channel_count, node_id);
+       mci = edac_mc_alloc(0, pvt->cs_count, pvt->channel_count, node_id);
        if (!mci)
                goto err_exit;
 
index 8ea07e2..c6f359a 100644 (file)
 #define EDAC_AMD64_VERSION             " Ver: 3.2.0 " __DATE__
 #define EDAC_MOD_STR                   "amd64_edac"
 
+#define EDAC_MAX_NUMNODES              8
+
 /* Extended Model from CPUID, for CPU Revision numbers */
 #define OPTERON_CPU_LE_REV_C           0
 #define OPTERON_CPU_REV_D              1
 #define OPTERON_CPU_REV_FA             5
 
 /* Hardware limit on ChipSelect rows per MC and processors per system */
-#define CHIPSELECT_COUNT               8
+#define MAX_CS_COUNT                   8
 #define DRAM_REG_COUNT                 8
 
 
  */
 #define REV_E_DCSB_BASE_BITS           (0xFFE0FE00ULL)
 #define REV_E_DCS_SHIFT                        4
-#define REV_E_DCSM_COUNT               8
 
 #define REV_F_F1Xh_DCSB_BASE_BITS      (0x1FF83FE0ULL)
 #define REV_F_F1Xh_DCS_SHIFT           8
  */
 #define REV_F_DCSB_BASE_BITS           (0x1FF83FE0ULL)
 #define REV_F_DCS_SHIFT                        8
-#define REV_F_DCSM_COUNT               4
-#define F10_DCSM_COUNT                 4
-#define F11_DCSM_COUNT                 2
 
 /* DRAM CS Mask Registers */
 #define K8_DCSM0                       0x60
@@ -374,13 +372,11 @@ enum {
 
 #define SET_NB_DRAM_INJECTION_WRITE(word, bits)  \
                                        (BIT(((word) & 0xF) + 20) | \
-                                       BIT(17) |  \
-                                       ((bits) & 0xF))
+                                       BIT(17) | bits)
 
 #define SET_NB_DRAM_INJECTION_READ(word, bits)  \
                                        (BIT(((word) & 0xF) + 20) | \
-                                       BIT(16) |  \
-                                       ((bits) & 0xF))
+                                       BIT(16) |  bits)
 
 #define K8_NBCAP                       0xE8
 #define K8_NBCAP_CORES                 (BIT(12)|BIT(13))
@@ -445,12 +441,12 @@ struct amd64_pvt {
        u32 dbam1;              /* DRAM Base Address Mapping reg for DCT1 */
 
        /* DRAM CS Base Address Registers F2x[1,0][5C:40] */
-       u32 dcsb0[CHIPSELECT_COUNT];
-       u32 dcsb1[CHIPSELECT_COUNT];
+       u32 dcsb0[MAX_CS_COUNT];
+       u32 dcsb1[MAX_CS_COUNT];
 
        /* DRAM CS Mask Registers F2x[1,0][6C:60] */
-       u32 dcsm0[CHIPSELECT_COUNT];
-       u32 dcsm1[CHIPSELECT_COUNT];
+       u32 dcsm0[MAX_CS_COUNT];
+       u32 dcsm1[MAX_CS_COUNT];
 
        /*
         * Decoded parts of DRAM BASE and LIMIT Registers
@@ -470,6 +466,7 @@ struct amd64_pvt {
         */
        u32 dcsb_base;          /* DCSB base bits */
        u32 dcsm_mask;          /* DCSM mask bits */
+       u32 cs_count;           /* num chip selects (== num DCSB registers) */
        u32 num_dcsm;           /* Number of DCSM registers */
        u32 dcs_mask_notused;   /* DCSM notused mask bits */
        u32 dcs_shift;          /* DCSB and DCSM shift value */
index d3675b7..29f1f7a 100644 (file)
@@ -1,5 +1,11 @@
 #include "amd64_edac.h"
 
+static ssize_t amd64_inject_section_show(struct mem_ctl_info *mci, char *buf)
+{
+       struct amd64_pvt *pvt = mci->pvt_info;
+       return sprintf(buf, "0x%x\n", pvt->injection.section);
+}
+
 /*
  * store error injection section value which refers to one of 4 16-byte sections
  * within a 64-byte cacheline
@@ -15,12 +21,26 @@ static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
 
        ret = strict_strtoul(data, 10, &value);
        if (ret != -EINVAL) {
+
+               if (value > 3) {
+                       amd64_printk(KERN_WARNING,
+                                    "%s: invalid section 0x%lx\n",
+                                    __func__, value);
+                       return -EINVAL;
+               }
+
                pvt->injection.section = (u32) value;
                return count;
        }
        return ret;
 }
 
+static ssize_t amd64_inject_word_show(struct mem_ctl_info *mci, char *buf)
+{
+       struct amd64_pvt *pvt = mci->pvt_info;
+       return sprintf(buf, "0x%x\n", pvt->injection.word);
+}
+
 /*
  * store error injection word value which refers to one of 9 16-bit word of the
  * 16-byte (128-bit + ECC bits) section
@@ -37,14 +57,25 @@ static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
        ret = strict_strtoul(data, 10, &value);
        if (ret != -EINVAL) {
 
-               value = (value <= 8) ? value : 0;
-               pvt->injection.word = (u32) value;
+               if (value > 8) {
+                       amd64_printk(KERN_WARNING,
+                                    "%s: invalid word 0x%lx\n",
+                                    __func__, value);
+                       return -EINVAL;
+               }
 
+               pvt->injection.word = (u32) value;
                return count;
        }
        return ret;
 }
 
+static ssize_t amd64_inject_ecc_vector_show(struct mem_ctl_info *mci, char *buf)
+{
+       struct amd64_pvt *pvt = mci->pvt_info;
+       return sprintf(buf, "0x%x\n", pvt->injection.bit_map);
+}
+
 /*
  * store 16 bit error injection vector which enables injecting errors to the
  * corresponding bit within the error injection word above. When used during a
@@ -60,8 +91,14 @@ static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
        ret = strict_strtoul(data, 16, &value);
        if (ret != -EINVAL) {
 
-               pvt->injection.bit_map = (u32) value & 0xFFFF;
+               if (value & 0xFFFF0000) {
+                       amd64_printk(KERN_WARNING,
+                                    "%s: invalid EccVector: 0x%lx\n",
+                                    __func__, value);
+                       return -EINVAL;
+               }
 
+               pvt->injection.bit_map = (u32) value;
                return count;
        }
        return ret;
@@ -147,7 +184,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
                        .name = "inject_section",
                        .mode = (S_IRUGO | S_IWUSR)
                },
-               .show = NULL,
+               .show = amd64_inject_section_show,
                .store = amd64_inject_section_store,
        },
        {
@@ -155,7 +192,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
                        .name = "inject_word",
                        .mode = (S_IRUGO | S_IWUSR)
                },
-               .show = NULL,
+               .show = amd64_inject_word_show,
                .store = amd64_inject_word_store,
        },
        {
@@ -163,7 +200,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
                        .name = "inject_ecc_vector",
                        .mode = (S_IRUGO | S_IWUSR)
                },
-               .show = NULL,
+               .show = amd64_inject_ecc_vector_show,
                .store = amd64_inject_ecc_vector_store,
        },
        {
index 8e7b0eb..5cae0b3 100644 (file)
@@ -1556,8 +1556,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
        struct drm_crtc *crtc;
        int ret = 0;
 
-       DRM_DEBUG_KMS("\n");
-
        if (!req->flags) {
                DRM_ERROR("no operation set\n");
                return -EINVAL;
index 819ddcb..23dc9c1 100644 (file)
@@ -454,6 +454,96 @@ out_free:
 }
 EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
 
+static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
+                    u16 blue, u16 regno, struct fb_info *info)
+{
+       struct drm_fb_helper *fb_helper = info->par;
+       struct drm_framebuffer *fb = fb_helper->fb;
+       int pindex;
+
+       pindex = regno;
+
+       if (fb->bits_per_pixel == 16) {
+               pindex = regno << 3;
+
+               if (fb->depth == 16 && regno > 63)
+                       return;
+               if (fb->depth == 15 && regno > 31)
+                       return;
+
+               if (fb->depth == 16) {
+                       u16 r, g, b;
+                       int i;
+                       if (regno < 32) {
+                               for (i = 0; i < 8; i++)
+                                       fb_helper->funcs->gamma_set(crtc, red,
+                                               green, blue, pindex + i);
+                       }
+
+                       fb_helper->funcs->gamma_get(crtc, &r,
+                                                   &g, &b,
+                                                   pindex >> 1);
+
+                       for (i = 0; i < 4; i++)
+                               fb_helper->funcs->gamma_set(crtc, r,
+                                                           green, b,
+                                                           (pindex >> 1) + i);
+               }
+       }
+
+       if (fb->depth != 16)
+               fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
+
+       if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+               ((u32 *) fb->pseudo_palette)[regno] =
+                       (regno << info->var.red.offset) |
+                       (regno << info->var.green.offset) |
+                       (regno << info->var.blue.offset);
+       }
+}
+
+int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+       struct drm_fb_helper *fb_helper = info->par;
+       struct drm_device *dev = fb_helper->dev;
+       u16 *red, *green, *blue, *transp;
+       struct drm_crtc *crtc;
+       int i, rc = 0;
+       int start;
+
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+               for (i = 0; i < fb_helper->crtc_count; i++) {
+                       if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
+                               break;
+               }
+               if (i == fb_helper->crtc_count)
+                       continue;
+
+               red = cmap->red;
+               green = cmap->green;
+               blue = cmap->blue;
+               transp = cmap->transp;
+               start = cmap->start;
+
+               for (i = 0; i < cmap->len; i++) {
+                       u16 hred, hgreen, hblue, htransp = 0xffff;
+
+                       hred = *red++;
+                       hgreen = *green++;
+                       hblue = *blue++;
+
+                       if (transp)
+                               htransp = *transp++;
+
+                       setcolreg(crtc, hred, hgreen, hblue, start++, info);
+               }
+               crtc_funcs->load_lut(crtc);
+       }
+       return rc;
+}
+EXPORT_SYMBOL(drm_fb_helper_setcmap);
+
 int drm_fb_helper_setcolreg(unsigned regno,
                            unsigned red,
                            unsigned green,
@@ -466,9 +556,11 @@ int drm_fb_helper_setcolreg(unsigned regno,
        struct drm_crtc *crtc;
        int i;
 
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-               struct drm_framebuffer *fb = fb_helper->fb;
+       if (regno > 255)
+               return 1;
 
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
                for (i = 0; i < fb_helper->crtc_count; i++) {
                        if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
                                break;
@@ -476,35 +568,9 @@ int drm_fb_helper_setcolreg(unsigned regno,
                if (i == fb_helper->crtc_count)
                        continue;
 
-               if (regno > 255)
-                       return 1;
-
-               if (fb->depth == 8) {
-                       fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
-                       return 0;
-               }
 
-               if (regno < 16) {
-                       switch (fb->depth) {
-                       case 15:
-                               fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
-                                       ((green & 0xf800) >>  6) |
-                                       ((blue & 0xf800) >> 11);
-                               break;
-                       case 16:
-                               fb->pseudo_palette[regno] = (red & 0xf800) |
-                                       ((green & 0xfc00) >>  5) |
-                                       ((blue  & 0xf800) >> 11);
-                               break;
-                       case 24:
-                       case 32:
-                               fb->pseudo_palette[regno] =
-                                       (((red >> 8) & 0xff) << info->var.red.offset) |
-                                       (((green >> 8) & 0xff) << info->var.green.offset) |
-                                       (((blue >> 8) & 0xff) << info->var.blue.offset);
-                               break;
-                       }
-               }
+               setcolreg(crtc, red, green, blue, regno, info);
+               crtc_funcs->load_lut(crtc);
        }
        return 0;
 }
@@ -674,6 +740,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
 EXPORT_SYMBOL(drm_fb_helper_pan_display);
 
 int drm_fb_helper_single_fb_probe(struct drm_device *dev,
+                                 int preferred_bpp,
                                  int (*fb_create)(struct drm_device *dev,
                                                   uint32_t fb_width,
                                                   uint32_t fb_height,
@@ -696,6 +763,11 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
        struct drm_fb_helper *fb_helper;
        uint32_t surface_depth = 24, surface_bpp = 32;
 
+       /* if driver picks 8 or 16 by default use that
+          for both depth/bpp */
+       if (preferred_bpp != surface_bpp) {
+               surface_depth = surface_bpp = preferred_bpp;
+       }
        /* first up get a count of crtcs now in use and new min/maxes width/heights */
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
@@ -851,10 +923,12 @@ void drm_fb_helper_free(struct drm_fb_helper *helper)
 }
 EXPORT_SYMBOL(drm_fb_helper_free);
 
-void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
+void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
+                           uint32_t depth)
 {
        info->fix.type = FB_TYPE_PACKED_PIXELS;
-       info->fix.visual = FB_VISUAL_TRUECOLOR;
+       info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
+               FB_VISUAL_DIRECTCOLOR;
        info->fix.type_aux = 0;
        info->fix.xpanstep = 1; /* doing it in hw */
        info->fix.ypanstep = 1; /* doing it in hw */
index 93ff6c0..ffa3967 100644 (file)
@@ -3244,6 +3244,16 @@ void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
        intel_crtc->lut_b[regno] = blue >> 8;
 }
 
+void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+                            u16 *blue, int regno)
+{
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+       *red = intel_crtc->lut_r[regno] << 8;
+       *green = intel_crtc->lut_g[regno] << 8;
+       *blue = intel_crtc->lut_b[regno] << 8;
+}
+
 static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
                                 u16 *blue, uint32_t size)
 {
@@ -3835,6 +3845,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
        .mode_set_base = intel_pipe_set_base,
        .prepare = intel_crtc_prepare,
        .commit = intel_crtc_commit,
+       .load_lut = intel_crtc_load_lut,
 };
 
 static const struct drm_crtc_funcs intel_crtc_funcs = {
index 8aa4b7f..ef61fe9 100644 (file)
@@ -175,6 +175,8 @@ extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc);
 extern void intelfb_restore(void);
 extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
                                    u16 blue, int regno);
+extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+                                   u16 *blue, int regno);
 
 extern int intel_framebuffer_create(struct drm_device *dev,
                                    struct drm_mode_fb_cmd *mode_cmd,
index e85d7e9..2b0fe54 100644 (file)
@@ -60,10 +60,12 @@ static struct fb_ops intelfb_ops = {
        .fb_imageblit = cfb_imageblit,
        .fb_pan_display = drm_fb_helper_pan_display,
        .fb_blank = drm_fb_helper_blank,
+       .fb_setcmap = drm_fb_helper_setcmap,
 };
 
 static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
        .gamma_set = intel_crtc_fb_gamma_set,
+       .gamma_get = intel_crtc_fb_gamma_get,
 };
 
 
@@ -123,6 +125,10 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
        struct device *device = &dev->pdev->dev;
        int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1;
 
+       /* we don't do packed 24bpp */
+       if (surface_bpp == 24)
+               surface_bpp = 32;
+
        mode_cmd.width = surface_width;
        mode_cmd.height = surface_height;
 
@@ -206,7 +212,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
 
 //     memset(info->screen_base, 0, size);
 
-       drm_fb_helper_fill_fix(info, fb->pitch);
+       drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
        drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
 
        /* FIXME: we really shouldn't expose mmio space at all */
@@ -244,7 +250,7 @@ int intelfb_probe(struct drm_device *dev)
        int ret;
 
        DRM_DEBUG("\n");
-       ret = drm_fb_helper_single_fb_probe(dev, intelfb_create);
+       ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create);
        return ret;
 }
 EXPORT_SYMBOL(intelfb_probe);
index 6a01592..14fa970 100644 (file)
@@ -733,6 +733,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
        .mode_set_base = atombios_crtc_set_base,
        .prepare = atombios_crtc_prepare,
        .commit = atombios_crtc_commit,
+       .load_lut = radeon_crtc_load_lut,
 };
 
 void radeon_atombios_init_crtc(struct drm_device *dev,
index e6cce24..161094c 100644 (file)
@@ -32,6 +32,9 @@
 #include "radeon_reg.h"
 #include "radeon.h"
 #include "r100d.h"
+#include "rs100d.h"
+#include "rv200d.h"
+#include "rv250d.h"
 
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
@@ -60,18 +63,7 @@ MODULE_FIRMWARE(FIRMWARE_R520);
 
 /* This files gather functions specifics to:
  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
- *
- * Some of these functions might be used by newer ASICs.
  */
-int r200_init(struct radeon_device *rdev);
-void r100_hdp_reset(struct radeon_device *rdev);
-void r100_gpu_init(struct radeon_device *rdev);
-int r100_gui_wait_for_idle(struct radeon_device *rdev);
-int r100_mc_wait_for_idle(struct radeon_device *rdev);
-void r100_gpu_wait_for_vsync(struct radeon_device *rdev);
-void r100_gpu_wait_for_vsync2(struct radeon_device *rdev);
-int r100_debugfs_mc_info_init(struct radeon_device *rdev);
-
 
 /*
  * PCI GART
@@ -152,136 +144,6 @@ void r100_pci_gart_fini(struct radeon_device *rdev)
        radeon_gart_fini(rdev);
 }
 
-
-/*
- * MC
- */
-void r100_mc_disable_clients(struct radeon_device *rdev)
-{
-       uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl;
-
-       /* FIXME: is this function correct for rs100,rs200,rs300 ? */
-       if (r100_gui_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "Failed to wait GUI idle while "
-                      "programming pipes. Bad things might happen.\n");
-       }
-
-       /* stop display and memory access */
-       ov0_scale_cntl = RREG32(RADEON_OV0_SCALE_CNTL);
-       WREG32(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
-       crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
-       WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
-       crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
-
-       r100_gpu_wait_for_vsync(rdev);
-
-       WREG32(RADEON_CRTC_GEN_CNTL,
-              (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) |
-              RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
-
-       if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
-               crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
-
-               r100_gpu_wait_for_vsync2(rdev);
-               WREG32(RADEON_CRTC2_GEN_CNTL,
-                      (crtc2_gen_cntl &
-                       ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) |
-                      RADEON_CRTC2_DISP_REQ_EN_B);
-       }
-
-       udelay(500);
-}
-
-void r100_mc_setup(struct radeon_device *rdev)
-{
-       uint32_t tmp;
-       int r;
-
-       r = r100_debugfs_mc_info_init(rdev);
-       if (r) {
-               DRM_ERROR("Failed to register debugfs file for R100 MC !\n");
-       }
-       /* Write VRAM size in case we are limiting it */
-       WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
-       /* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM,
-        * if the aperture is 64MB but we have 32MB VRAM
-        * we report only 32MB VRAM but we have to set MC_FB_LOCATION
-        * to 64MB, otherwise the gpu accidentially dies */
-       tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-       tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
-       tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
-       WREG32(RADEON_MC_FB_LOCATION, tmp);
-
-       /* Enable bus mastering */
-       tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
-       WREG32(RADEON_BUS_CNTL, tmp);
-
-       if (rdev->flags & RADEON_IS_AGP) {
-               tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-               tmp = REG_SET(RADEON_MC_AGP_TOP, tmp >> 16);
-               tmp |= REG_SET(RADEON_MC_AGP_START, rdev->mc.gtt_location >> 16);
-               WREG32(RADEON_MC_AGP_LOCATION, tmp);
-               WREG32(RADEON_AGP_BASE, rdev->mc.agp_base);
-       } else {
-               WREG32(RADEON_MC_AGP_LOCATION, 0x0FFFFFFF);
-               WREG32(RADEON_AGP_BASE, 0);
-       }
-
-       tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
-       tmp |= (7 << 28);
-       WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
-       (void)RREG32(RADEON_HOST_PATH_CNTL);
-       WREG32(RADEON_HOST_PATH_CNTL, tmp);
-       (void)RREG32(RADEON_HOST_PATH_CNTL);
-}
-
-int r100_mc_init(struct radeon_device *rdev)
-{
-       int r;
-
-       if (r100_debugfs_rbbm_init(rdev)) {
-               DRM_ERROR("Failed to register debugfs file for RBBM !\n");
-       }
-
-       r100_gpu_init(rdev);
-       /* Disable gart which also disable out of gart access */
-       r100_pci_gart_disable(rdev);
-
-       /* Setup GPU memory space */
-       rdev->mc.gtt_location = 0xFFFFFFFFUL;
-       if (rdev->flags & RADEON_IS_AGP) {
-               r = radeon_agp_init(rdev);
-               if (r) {
-                       printk(KERN_WARNING "[drm] Disabling AGP\n");
-                       rdev->flags &= ~RADEON_IS_AGP;
-                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-               } else {
-                       rdev->mc.gtt_location = rdev->mc.agp_base;
-               }
-       }
-       r = radeon_mc_setup(rdev);
-       if (r) {
-               return r;
-       }
-
-       r100_mc_disable_clients(rdev);
-       if (r100_mc_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "Failed to wait MC idle while "
-                      "programming pipes. Bad things might happen.\n");
-       }
-
-       r100_mc_setup(rdev);
-       return 0;
-}
-
-void r100_mc_fini(struct radeon_device *rdev)
-{
-}
-
-
-/*
- * Interrupts
- */
 int r100_irq_set(struct radeon_device *rdev)
 {
        uint32_t tmp = 0;
@@ -358,10 +220,6 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc)
                return RREG32(RADEON_CRTC2_CRNT_FRAME);
 }
 
-
-/*
- * Fence emission
- */
 void r100_fence_ring_emit(struct radeon_device *rdev,
                          struct radeon_fence *fence)
 {
@@ -377,10 +235,6 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
        radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
 }
 
-
-/*
- * Writeback
- */
 int r100_wb_init(struct radeon_device *rdev)
 {
        int r;
@@ -504,10 +358,6 @@ int r100_copy_blit(struct radeon_device *rdev,
        return r;
 }
 
-
-/*
- * CP
- */
 static int r100_cp_wait_for_idle(struct radeon_device *rdev)
 {
        unsigned i;
@@ -612,6 +462,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
        }
        return err;
 }
+
 static void r100_cp_load_microcode(struct radeon_device *rdev)
 {
        const __be32 *fw_data;
@@ -978,7 +829,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
 
        header = radeon_get_ib_value(p, h_idx);
        crtc_id = radeon_get_ib_value(p, h_idx + 5);
-       reg = header >> 2;
+       reg = CP_PACKET0_GET_REG(header);
        mutex_lock(&p->rdev->ddev->mode_config.mutex);
        obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
        if (!obj) {
@@ -1990,7 +1841,7 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
        r100_pll_errata_after_data(rdev);
 }
 
-int r100_init(struct radeon_device *rdev)
+void r100_set_safe_registers(struct radeon_device *rdev)
 {
        if (ASIC_IS_RN50(rdev)) {
                rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
@@ -1999,9 +1850,8 @@ int r100_init(struct radeon_device *rdev)
                rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
                rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
        } else {
-               return r200_init(rdev);
+               r200_set_safe_registers(rdev);
        }
-       return 0;
 }
 
 /*
@@ -2299,9 +2149,11 @@ void r100_bandwidth_update(struct radeon_device *rdev)
                mode1 = &rdev->mode_info.crtcs[0]->base.mode;
                pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
        }
-       if (rdev->mode_info.crtcs[1]->base.enabled) {
-               mode2 = &rdev->mode_info.crtcs[1]->base.mode;
-               pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
+       if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
+               if (rdev->mode_info.crtcs[1]->base.enabled) {
+                       mode2 = &rdev->mode_info.crtcs[1]->base.mode;
+                       pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
+               }
        }
 
        min_mem_eff.full = rfixed_const_8(0);
@@ -3114,7 +2966,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
        WREG32(R_000740_CP_CSQ_CNTL, 0);
 
        /* Save few CRTC registers */
-       save->GENMO_WT = RREG32(R_0003C0_GENMO_WT);
+       save->GENMO_WT = RREG8(R_0003C2_GENMO_WT);
        save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL);
        save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL);
        save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET);
@@ -3124,7 +2976,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
        }
 
        /* Disable VGA aperture access */
-       WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT);
+       WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT);
        /* Disable cursor, overlay, crtc */
        WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1));
        WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL |
@@ -3156,10 +3008,264 @@ void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
                                rdev->mc.vram_location);
        }
        /* Restore CRTC registers */
-       WREG32(R_0003C0_GENMO_WT, save->GENMO_WT);
+       WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
        WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL);
        WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL);
        if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
                WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL);
        }
 }
+
+void r100_vga_render_disable(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       tmp = RREG8(R_0003C2_GENMO_WT);
+       WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp);
+}
+
+static void r100_debugfs(struct radeon_device *rdev)
+{
+       int r;
+
+       r = r100_debugfs_mc_info_init(rdev);
+       if (r)
+               dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n");
+}
+
+static void r100_mc_program(struct radeon_device *rdev)
+{
+       struct r100_mc_save save;
+
+       /* Stops all mc clients */
+       r100_mc_stop(rdev, &save);
+       if (rdev->flags & RADEON_IS_AGP) {
+               WREG32(R_00014C_MC_AGP_LOCATION,
+                       S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
+                       S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
+               WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
+               if (rdev->family > CHIP_RV200)
+                       WREG32(R_00015C_AGP_BASE_2,
+                               upper_32_bits(rdev->mc.agp_base) & 0xff);
+       } else {
+               WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF);
+               WREG32(R_000170_AGP_BASE, 0);
+               if (rdev->family > CHIP_RV200)
+                       WREG32(R_00015C_AGP_BASE_2, 0);
+       }
+       /* Wait for mc idle */
+       if (r100_mc_wait_for_idle(rdev))
+               dev_warn(rdev->dev, "Wait for MC idle timeout.\n");
+       /* Program MC, should be a 32bits limited address space */
+       WREG32(R_000148_MC_FB_LOCATION,
+               S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
+               S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
+       r100_mc_resume(rdev, &save);
+}
+
+void r100_clock_startup(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       if (radeon_dynclks != -1 && radeon_dynclks)
+               radeon_legacy_set_clock_gating(rdev, 1);
+       /* We need to force on some of the block */
+       tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
+       tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
+       if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280))
+               tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1);
+       WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
+}
+
+static int r100_startup(struct radeon_device *rdev)
+{
+       int r;
+
+       r100_mc_program(rdev);
+       /* Resume clock */
+       r100_clock_startup(rdev);
+       /* Initialize GPU configuration (# pipes, ...) */
+       r100_gpu_init(rdev);
+       /* Initialize GART (initialize after TTM so we can allocate
+        * memory through TTM but finalize after TTM) */
+       if (rdev->flags & RADEON_IS_PCI) {
+               r = r100_pci_gart_enable(rdev);
+               if (r)
+                       return r;
+       }
+       /* Enable IRQ */
+       rdev->irq.sw_int = true;
+       r100_irq_set(rdev);
+       /* 1M ring buffer */
+       r = r100_cp_init(rdev, 1024 * 1024);
+       if (r) {
+               dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+               return r;
+       }
+       r = r100_wb_init(rdev);
+       if (r)
+               dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+       r = r100_ib_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+               return r;
+       }
+       return 0;
+}
+
+int r100_resume(struct radeon_device *rdev)
+{
+       /* Make sur GART are not working */
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_disable(rdev);
+       /* Resume clock before doing reset */
+       r100_clock_startup(rdev);
+       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+       if (radeon_gpu_reset(rdev)) {
+               dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+                       RREG32(R_000E40_RBBM_STATUS),
+                       RREG32(R_0007C0_CP_STAT));
+       }
+       /* post */
+       radeon_combios_asic_init(rdev->ddev);
+       /* Resume clock after posting */
+       r100_clock_startup(rdev);
+       return r100_startup(rdev);
+}
+
+int r100_suspend(struct radeon_device *rdev)
+{
+       r100_cp_disable(rdev);
+       r100_wb_disable(rdev);
+       r100_irq_disable(rdev);
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_disable(rdev);
+       return 0;
+}
+
+void r100_fini(struct radeon_device *rdev)
+{
+       r100_suspend(rdev);
+       r100_cp_fini(rdev);
+       r100_wb_fini(rdev);
+       r100_ib_fini(rdev);
+       radeon_gem_fini(rdev);
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_fini(rdev);
+       radeon_irq_kms_fini(rdev);
+       radeon_fence_driver_fini(rdev);
+       radeon_object_fini(rdev);
+       radeon_atombios_fini(rdev);
+       kfree(rdev->bios);
+       rdev->bios = NULL;
+}
+
+int r100_mc_init(struct radeon_device *rdev)
+{
+       int r;
+       u32 tmp;
+
+       /* Setup GPU memory space */
+       rdev->mc.vram_location = 0xFFFFFFFFUL;
+       rdev->mc.gtt_location = 0xFFFFFFFFUL;
+       if (rdev->flags & RADEON_IS_IGP) {
+               tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
+               rdev->mc.vram_location = tmp << 16;
+       }
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       printk(KERN_WARNING "[drm] Disabling AGP\n");
+                       rdev->flags &= ~RADEON_IS_AGP;
+                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+               } else {
+                       rdev->mc.gtt_location = rdev->mc.agp_base;
+               }
+       }
+       r = radeon_mc_setup(rdev);
+       if (r)
+               return r;
+       return 0;
+}
+
+int r100_init(struct radeon_device *rdev)
+{
+       int r;
+
+       /* Register debugfs file specific to this group of asics */
+       r100_debugfs(rdev);
+       /* Disable VGA */
+       r100_vga_render_disable(rdev);
+       /* Initialize scratch registers */
+       radeon_scratch_init(rdev);
+       /* Initialize surface registers */
+       radeon_surface_init(rdev);
+       /* TODO: disable VGA need to use VGA request */
+       /* BIOS*/
+       if (!radeon_get_bios(rdev)) {
+               if (ASIC_IS_AVIVO(rdev))
+                       return -EINVAL;
+       }
+       if (rdev->is_atom_bios) {
+               dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
+               return -EINVAL;
+       } else {
+               r = radeon_combios_init(rdev);
+               if (r)
+                       return r;
+       }
+       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+       if (radeon_gpu_reset(rdev)) {
+               dev_warn(rdev->dev,
+                       "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+                       RREG32(R_000E40_RBBM_STATUS),
+                       RREG32(R_0007C0_CP_STAT));
+       }
+       /* check if cards are posted or not */
+       if (!radeon_card_posted(rdev) && rdev->bios) {
+               DRM_INFO("GPU not posted. posting now...\n");
+               radeon_combios_asic_init(rdev->ddev);
+       }
+       /* Set asic errata */
+       r100_errata(rdev);
+       /* Initialize clocks */
+       radeon_get_clock_info(rdev->ddev);
+       /* Get vram informations */
+       r100_vram_info(rdev);
+       /* Initialize memory controller (also test AGP) */
+       r = r100_mc_init(rdev);
+       if (r)
+               return r;
+       /* Fence driver */
+       r = radeon_fence_driver_init(rdev);
+       if (r)
+               return r;
+       r = radeon_irq_kms_init(rdev);
+       if (r)
+               return r;
+       /* Memory manager */
+       r = radeon_object_init(rdev);
+       if (r)
+               return r;
+       if (rdev->flags & RADEON_IS_PCI) {
+               r = r100_pci_gart_init(rdev);
+               if (r)
+                       return r;
+       }
+       r100_set_safe_registers(rdev);
+       rdev->accel_working = true;
+       r = r100_startup(rdev);
+       if (r) {
+               /* Somethings want wront with the accel init stop accel */
+               dev_err(rdev->dev, "Disabling GPU acceleration\n");
+               r100_suspend(rdev);
+               r100_cp_fini(rdev);
+               r100_wb_fini(rdev);
+               r100_ib_fini(rdev);
+               if (rdev->flags & RADEON_IS_PCI)
+                       r100_pci_gart_fini(rdev);
+               radeon_irq_kms_fini(rdev);
+               rdev->accel_working = false;
+       }
+       return 0;
+}
index c4b257e..df29a63 100644 (file)
 #define   S_000054_VCRTC_IDX_MASTER(x)                 (((x) & 0x7F) << 24)
 #define   G_000054_VCRTC_IDX_MASTER(x)                 (((x) >> 24) & 0x7F)
 #define   C_000054_VCRTC_IDX_MASTER                    0x80FFFFFF
+#define R_000148_MC_FB_LOCATION                      0x000148
+#define   S_000148_MC_FB_START(x)                      (((x) & 0xFFFF) << 0)
+#define   G_000148_MC_FB_START(x)                      (((x) >> 0) & 0xFFFF)
+#define   C_000148_MC_FB_START                         0xFFFF0000
+#define   S_000148_MC_FB_TOP(x)                        (((x) & 0xFFFF) << 16)
+#define   G_000148_MC_FB_TOP(x)                        (((x) >> 16) & 0xFFFF)
+#define   C_000148_MC_FB_TOP                           0x0000FFFF
+#define R_00014C_MC_AGP_LOCATION                     0x00014C
+#define   S_00014C_MC_AGP_START(x)                     (((x) & 0xFFFF) << 0)
+#define   G_00014C_MC_AGP_START(x)                     (((x) >> 0) & 0xFFFF)
+#define   C_00014C_MC_AGP_START                        0xFFFF0000
+#define   S_00014C_MC_AGP_TOP(x)                       (((x) & 0xFFFF) << 16)
+#define   G_00014C_MC_AGP_TOP(x)                       (((x) >> 16) & 0xFFFF)
+#define   C_00014C_MC_AGP_TOP                          0x0000FFFF
+#define R_000170_AGP_BASE                            0x000170
+#define   S_000170_AGP_BASE_ADDR(x)                    (((x) & 0xFFFFFFFF) << 0)
+#define   G_000170_AGP_BASE_ADDR(x)                    (((x) >> 0) & 0xFFFFFFFF)
+#define   C_000170_AGP_BASE_ADDR                       0x00000000
 #define R_00023C_DISPLAY_BASE_ADDR                   0x00023C
 #define   S_00023C_DISPLAY_BASE_ADDR(x)                (((x) & 0xFFFFFFFF) << 0)
 #define   G_00023C_DISPLAY_BASE_ADDR(x)                (((x) >> 0) & 0xFFFFFFFF)
 #define   S_000360_CUR2_LOCK(x)                        (((x) & 0x1) << 31)
 #define   G_000360_CUR2_LOCK(x)                        (((x) >> 31) & 0x1)
 #define   C_000360_CUR2_LOCK                           0x7FFFFFFF
-#define R_0003C0_GENMO_WT                            0x0003C0
-#define   S_0003C0_GENMO_MONO_ADDRESS_B(x)             (((x) & 0x1) << 0)
-#define   G_0003C0_GENMO_MONO_ADDRESS_B(x)             (((x) >> 0) & 0x1)
-#define   C_0003C0_GENMO_MONO_ADDRESS_B                0xFFFFFFFE
-#define   S_0003C0_VGA_RAM_EN(x)                       (((x) & 0x1) << 1)
-#define   G_0003C0_VGA_RAM_EN(x)                       (((x) >> 1) & 0x1)
-#define   C_0003C0_VGA_RAM_EN                          0xFFFFFFFD
-#define   S_0003C0_VGA_CKSEL(x)                        (((x) & 0x3) << 2)
-#define   G_0003C0_VGA_CKSEL(x)                        (((x) >> 2) & 0x3)
-#define   C_0003C0_VGA_CKSEL                           0xFFFFFFF3
-#define   S_0003C0_ODD_EVEN_MD_PGSEL(x)                (((x) & 0x1) << 5)
-#define   G_0003C0_ODD_EVEN_MD_PGSEL(x)                (((x) >> 5) & 0x1)
-#define   C_0003C0_ODD_EVEN_MD_PGSEL                   0xFFFFFFDF
-#define   S_0003C0_VGA_HSYNC_POL(x)                    (((x) & 0x1) << 6)
-#define   G_0003C0_VGA_HSYNC_POL(x)                    (((x) >> 6) & 0x1)
-#define   C_0003C0_VGA_HSYNC_POL                       0xFFFFFFBF
-#define   S_0003C0_VGA_VSYNC_POL(x)                    (((x) & 0x1) << 7)
-#define   G_0003C0_VGA_VSYNC_POL(x)                    (((x) >> 7) & 0x1)
-#define   C_0003C0_VGA_VSYNC_POL                       0xFFFFFF7F
+#define R_0003C2_GENMO_WT                            0x0003C0
+#define   S_0003C2_GENMO_MONO_ADDRESS_B(x)             (((x) & 0x1) << 0)
+#define   G_0003C2_GENMO_MONO_ADDRESS_B(x)             (((x) >> 0) & 0x1)
+#define   C_0003C2_GENMO_MONO_ADDRESS_B                0xFE
+#define   S_0003C2_VGA_RAM_EN(x)                       (((x) & 0x1) << 1)
+#define   G_0003C2_VGA_RAM_EN(x)                       (((x) >> 1) & 0x1)
+#define   C_0003C2_VGA_RAM_EN                          0xFD
+#define   S_0003C2_VGA_CKSEL(x)                        (((x) & 0x3) << 2)
+#define   G_0003C2_VGA_CKSEL(x)                        (((x) >> 2) & 0x3)
+#define   C_0003C2_VGA_CKSEL                           0xF3
+#define   S_0003C2_ODD_EVEN_MD_PGSEL(x)                (((x) & 0x1) << 5)
+#define   G_0003C2_ODD_EVEN_MD_PGSEL(x)                (((x) >> 5) & 0x1)
+#define   C_0003C2_ODD_EVEN_MD_PGSEL                   0xDF
+#define   S_0003C2_VGA_HSYNC_POL(x)                    (((x) & 0x1) << 6)
+#define   G_0003C2_VGA_HSYNC_POL(x)                    (((x) >> 6) & 0x1)
+#define   C_0003C2_VGA_HSYNC_POL                       0xBF
+#define   S_0003C2_VGA_VSYNC_POL(x)                    (((x) & 0x1) << 7)
+#define   G_0003C2_VGA_VSYNC_POL(x)                    (((x) >> 7) & 0x1)
+#define   C_0003C2_VGA_VSYNC_POL                       0x7F
 #define R_0003F8_CRTC2_GEN_CNTL                      0x0003F8
 #define   S_0003F8_CRTC2_DBL_SCAN_EN(x)                (((x) & 0x1) << 0)
 #define   G_0003F8_CRTC2_DBL_SCAN_EN(x)                (((x) >> 0) & 0x1)
 #define   S_000774_SCRATCH_ADDR(x)                     (((x) & 0x7FFFFFF) << 5)
 #define   G_000774_SCRATCH_ADDR(x)                     (((x) >> 5) & 0x7FFFFFF)
 #define   C_000774_SCRATCH_ADDR                        0x0000001F
+#define R_0007C0_CP_STAT                             0x0007C0
+#define   S_0007C0_MRU_BUSY(x)                         (((x) & 0x1) << 0)
+#define   G_0007C0_MRU_BUSY(x)                         (((x) >> 0) & 0x1)
+#define   C_0007C0_MRU_BUSY                            0xFFFFFFFE
+#define   S_0007C0_MWU_BUSY(x)                         (((x) & 0x1) << 1)
+#define   G_0007C0_MWU_BUSY(x)                         (((x) >> 1) & 0x1)
+#define   C_0007C0_MWU_BUSY                            0xFFFFFFFD
+#define   S_0007C0_RSIU_BUSY(x)                        (((x) & 0x1) << 2)
+#define   G_0007C0_RSIU_BUSY(x)                        (((x) >> 2) & 0x1)
+#define   C_0007C0_RSIU_BUSY                           0xFFFFFFFB
+#define   S_0007C0_RCIU_BUSY(x)                        (((x) & 0x1) << 3)
+#define   G_0007C0_RCIU_BUSY(x)                        (((x) >> 3) & 0x1)
+#define   C_0007C0_RCIU_BUSY                           0xFFFFFFF7
+#define   S_0007C0_CSF_PRIMARY_BUSY(x)                 (((x) & 0x1) << 9)
+#define   G_0007C0_CSF_PRIMARY_BUSY(x)                 (((x) >> 9) & 0x1)
+#define   C_0007C0_CSF_PRIMARY_BUSY                    0xFFFFFDFF
+#define   S_0007C0_CSF_INDIRECT_BUSY(x)                (((x) & 0x1) << 10)
+#define   G_0007C0_CSF_INDIRECT_BUSY(x)                (((x) >> 10) & 0x1)
+#define   C_0007C0_CSF_INDIRECT_BUSY                   0xFFFFFBFF
+#define   S_0007C0_CSQ_PRIMARY_BUSY(x)                 (((x) & 0x1) << 11)
+#define   G_0007C0_CSQ_PRIMARY_BUSY(x)                 (((x) >> 11) & 0x1)
+#define   C_0007C0_CSQ_PRIMARY_BUSY                    0xFFFFF7FF
+#define   S_0007C0_CSQ_INDIRECT_BUSY(x)                (((x) & 0x1) << 12)
+#define   G_0007C0_CSQ_INDIRECT_BUSY(x)                (((x) >> 12) & 0x1)
+#define   C_0007C0_CSQ_INDIRECT_BUSY                   0xFFFFEFFF
+#define   S_0007C0_CSI_BUSY(x)                         (((x) & 0x1) << 13)
+#define   G_0007C0_CSI_BUSY(x)                         (((x) >> 13) & 0x1)
+#define   C_0007C0_CSI_BUSY                            0xFFFFDFFF
+#define   S_0007C0_GUIDMA_BUSY(x)                      (((x) & 0x1) << 28)
+#define   G_0007C0_GUIDMA_BUSY(x)                      (((x) >> 28) & 0x1)
+#define   C_0007C0_GUIDMA_BUSY                         0xEFFFFFFF
+#define   S_0007C0_VIDDMA_BUSY(x)                      (((x) & 0x1) << 29)
+#define   G_0007C0_VIDDMA_BUSY(x)                      (((x) >> 29) & 0x1)
+#define   C_0007C0_VIDDMA_BUSY                         0xDFFFFFFF
+#define   S_0007C0_CMDSTRM_BUSY(x)                     (((x) & 0x1) << 30)
+#define   G_0007C0_CMDSTRM_BUSY(x)                     (((x) >> 30) & 0x1)
+#define   C_0007C0_CMDSTRM_BUSY                        0xBFFFFFFF
+#define   S_0007C0_CP_BUSY(x)                          (((x) & 0x1) << 31)
+#define   G_0007C0_CP_BUSY(x)                          (((x) >> 31) & 0x1)
+#define   C_0007C0_CP_BUSY                             0x7FFFFFFF
 #define R_000E40_RBBM_STATUS                         0x000E40
 #define   S_000E40_CMDFIFO_AVAIL(x)                    (((x) & 0x7F) << 0)
 #define   G_000E40_CMDFIFO_AVAIL(x)                    (((x) >> 0) & 0x7F)
 #define   G_000E40_GUI_ACTIVE(x)                       (((x) >> 31) & 0x1)
 #define   C_000E40_GUI_ACTIVE                          0x7FFFFFFF
 
+
+#define R_00000D_SCLK_CNTL                           0x00000D
+#define   S_00000D_SCLK_SRC_SEL(x)                     (((x) & 0x7) << 0)
+#define   G_00000D_SCLK_SRC_SEL(x)                     (((x) >> 0) & 0x7)
+#define   C_00000D_SCLK_SRC_SEL                        0xFFFFFFF8
+#define   S_00000D_TCLK_SRC_SEL(x)                     (((x) & 0x7) << 8)
+#define   G_00000D_TCLK_SRC_SEL(x)                     (((x) >> 8) & 0x7)
+#define   C_00000D_TCLK_SRC_SEL                        0xFFFFF8FF
+#define   S_00000D_FORCE_CP(x)                         (((x) & 0x1) << 16)
+#define   G_00000D_FORCE_CP(x)                         (((x) >> 16) & 0x1)
+#define   C_00000D_FORCE_CP                            0xFFFEFFFF
+#define   S_00000D_FORCE_HDP(x)                        (((x) & 0x1) << 17)
+#define   G_00000D_FORCE_HDP(x)                        (((x) >> 17) & 0x1)
+#define   C_00000D_FORCE_HDP                           0xFFFDFFFF
+#define   S_00000D_FORCE_DISP(x)                       (((x) & 0x1) << 18)
+#define   G_00000D_FORCE_DISP(x)                       (((x) >> 18) & 0x1)
+#define   C_00000D_FORCE_DISP                          0xFFFBFFFF
+#define   S_00000D_FORCE_TOP(x)                        (((x) & 0x1) << 19)
+#define   G_00000D_FORCE_TOP(x)                        (((x) >> 19) & 0x1)
+#define   C_00000D_FORCE_TOP                           0xFFF7FFFF
+#define   S_00000D_FORCE_E2(x)                         (((x) & 0x1) << 20)
+#define   G_00000D_FORCE_E2(x)                         (((x) >> 20) & 0x1)
+#define   C_00000D_FORCE_E2                            0xFFEFFFFF
+#define   S_00000D_FORCE_SE(x)                         (((x) & 0x1) << 21)
+#define   G_00000D_FORCE_SE(x)                         (((x) >> 21) & 0x1)
+#define   C_00000D_FORCE_SE                            0xFFDFFFFF
+#define   S_00000D_FORCE_IDCT(x)                       (((x) & 0x1) << 22)
+#define   G_00000D_FORCE_IDCT(x)                       (((x) >> 22) & 0x1)
+#define   C_00000D_FORCE_IDCT                          0xFFBFFFFF
+#define   S_00000D_FORCE_VIP(x)                        (((x) & 0x1) << 23)
+#define   G_00000D_FORCE_VIP(x)                        (((x) >> 23) & 0x1)
+#define   C_00000D_FORCE_VIP                           0xFF7FFFFF
+#define   S_00000D_FORCE_RE(x)                         (((x) & 0x1) << 24)
+#define   G_00000D_FORCE_RE(x)                         (((x) >> 24) & 0x1)
+#define   C_00000D_FORCE_RE                            0xFEFFFFFF
+#define   S_00000D_FORCE_PB(x)                         (((x) & 0x1) << 25)
+#define   G_00000D_FORCE_PB(x)                         (((x) >> 25) & 0x1)
+#define   C_00000D_FORCE_PB                            0xFDFFFFFF
+#define   S_00000D_FORCE_TAM(x)                        (((x) & 0x1) << 26)
+#define   G_00000D_FORCE_TAM(x)                        (((x) >> 26) & 0x1)
+#define   C_00000D_FORCE_TAM                           0xFBFFFFFF
+#define   S_00000D_FORCE_TDM(x)                        (((x) & 0x1) << 27)
+#define   G_00000D_FORCE_TDM(x)                        (((x) >> 27) & 0x1)
+#define   C_00000D_FORCE_TDM                           0xF7FFFFFF
+#define   S_00000D_FORCE_RB(x)                         (((x) & 0x1) << 28)
+#define   G_00000D_FORCE_RB(x)                         (((x) >> 28) & 0x1)
+#define   C_00000D_FORCE_RB                            0xEFFFFFFF
+
+
 #endif
index cf7fea5..eb740fc 100644 (file)
@@ -447,9 +447,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
        return 0;
 }
 
-int r200_init(struct radeon_device *rdev)
+void r200_set_safe_registers(struct radeon_device *rdev)
 {
        rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
        rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
-       return 0;
 }
index 1ebea8c..e08c4a8 100644 (file)
 #include "radeon_drm.h"
 #include "r100_track.h"
 #include "r300d.h"
-
+#include "rv350d.h"
 #include "r300_reg_safe.h"
 
-/* r300,r350,rv350,rv370,rv380 depends on : */
-void r100_hdp_reset(struct radeon_device *rdev);
-int r100_cp_reset(struct radeon_device *rdev);
-int r100_rb2d_reset(struct radeon_device *rdev);
-int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-int r100_pci_gart_enable(struct radeon_device *rdev);
-void r100_mc_setup(struct radeon_device *rdev);
-void r100_mc_disable_clients(struct radeon_device *rdev);
-int r100_gui_wait_for_idle(struct radeon_device *rdev);
-int r100_cs_packet_parse(struct radeon_cs_parser *p,
-                        struct radeon_cs_packet *pkt,
-                        unsigned idx);
-int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
-int r100_cs_parse_packet0(struct radeon_cs_parser *p,
-                         struct radeon_cs_packet *pkt,
-                         const unsigned *auth, unsigned n,
-                         radeon_packet0_check_t check);
-int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
-                                        struct radeon_cs_packet *pkt,
-                                        struct radeon_object *robj);
-
-/* This files gather functions specifics to:
- * r300,r350,rv350,rv370,rv380
- *
- * Some of these functions might be used by newer ASICs.
- */
-void r300_gpu_init(struct radeon_device *rdev);
-int r300_mc_wait_for_idle(struct radeon_device *rdev);
-int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
-
+/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 */
 
 /*
  * rv370,rv380 PCIE GART
  */
+static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
+
 void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
 {
        uint32_t tmp;
@@ -182,59 +155,6 @@ void rv370_pcie_gart_fini(struct radeon_device *rdev)
        radeon_gart_fini(rdev);
 }
 
-/*
- * MC
- */
-int r300_mc_init(struct radeon_device *rdev)
-{
-       int r;
-
-       if (r100_debugfs_rbbm_init(rdev)) {
-               DRM_ERROR("Failed to register debugfs file for RBBM !\n");
-       }
-
-       r300_gpu_init(rdev);
-       r100_pci_gart_disable(rdev);
-       if (rdev->flags & RADEON_IS_PCIE) {
-               rv370_pcie_gart_disable(rdev);
-       }
-
-       /* Setup GPU memory space */
-       rdev->mc.vram_location = 0xFFFFFFFFUL;
-       rdev->mc.gtt_location = 0xFFFFFFFFUL;
-       if (rdev->flags & RADEON_IS_AGP) {
-               r = radeon_agp_init(rdev);
-               if (r) {
-                       printk(KERN_WARNING "[drm] Disabling AGP\n");
-                       rdev->flags &= ~RADEON_IS_AGP;
-                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-               } else {
-                       rdev->mc.gtt_location = rdev->mc.agp_base;
-               }
-       }
-       r = radeon_mc_setup(rdev);
-       if (r) {
-               return r;
-       }
-
-       /* Program GPU memory space */
-       r100_mc_disable_clients(rdev);
-       if (r300_mc_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "Failed to wait MC idle while "
-                      "programming pipes. Bad things might happen.\n");
-       }
-       r100_mc_setup(rdev);
-       return 0;
-}
-
-void r300_mc_fini(struct radeon_device *rdev)
-{
-}
-
-
-/*
- * Fence emission
- */
 void r300_fence_ring_emit(struct radeon_device *rdev,
                          struct radeon_fence *fence)
 {
@@ -260,10 +180,6 @@ void r300_fence_ring_emit(struct radeon_device *rdev,
        radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
 }
 
-
-/*
- * Global GPU functions
- */
 int r300_copy_dma(struct radeon_device *rdev,
                  uint64_t src_offset,
                  uint64_t dst_offset,
@@ -582,11 +498,6 @@ void r300_vram_info(struct radeon_device *rdev)
        r100_vram_init_sizes(rdev);
 }
 
-
-/*
- * PCIE Lanes
- */
-
 void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
 {
        uint32_t link_width_cntl, mask;
@@ -646,10 +557,6 @@ void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
 
 }
 
-
-/*
- * Debugfs info
- */
 #if defined(CONFIG_DEBUG_FS)
 static int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data)
 {
@@ -680,7 +587,7 @@ static struct drm_info_list rv370_pcie_gart_info_list[] = {
 };
 #endif
 
-int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
+static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
        return radeon_debugfs_add_files(rdev, rv370_pcie_gart_info_list, 1);
@@ -689,10 +596,6 @@ int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
 #endif
 }
 
-
-/*
- * CS functions
- */
 static int r300_packet0_check(struct radeon_cs_parser *p,
                struct radeon_cs_packet *pkt,
                unsigned idx, unsigned reg)
@@ -1226,12 +1129,6 @@ void r300_set_reg_safe(struct radeon_device *rdev)
        rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm);
 }
 
-int r300_init(struct radeon_device *rdev)
-{
-       r300_set_reg_safe(rdev);
-       return 0;
-}
-
 void r300_mc_program(struct radeon_device *rdev)
 {
        struct r100_mc_save save;
@@ -1265,3 +1162,198 @@ void r300_mc_program(struct radeon_device *rdev)
                S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
        r100_mc_resume(rdev, &save);
 }
+
+void r300_clock_startup(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       if (radeon_dynclks != -1 && radeon_dynclks)
+               radeon_legacy_set_clock_gating(rdev, 1);
+       /* We need to force on some of the block */
+       tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
+       tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
+       if ((rdev->family == CHIP_RV350) || (rdev->family == CHIP_RV380))
+               tmp |= S_00000D_FORCE_VAP(1);
+       WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
+}
+
+static int r300_startup(struct radeon_device *rdev)
+{
+       int r;
+
+       r300_mc_program(rdev);
+       /* Resume clock */
+       r300_clock_startup(rdev);
+       /* Initialize GPU configuration (# pipes, ...) */
+       r300_gpu_init(rdev);
+       /* Initialize GART (initialize after TTM so we can allocate
+        * memory through TTM but finalize after TTM) */
+       if (rdev->flags & RADEON_IS_PCIE) {
+               r = rv370_pcie_gart_enable(rdev);
+               if (r)
+                       return r;
+       }
+       if (rdev->flags & RADEON_IS_PCI) {
+               r = r100_pci_gart_enable(rdev);
+               if (r)
+                       return r;
+       }
+       /* Enable IRQ */
+       rdev->irq.sw_int = true;
+       r100_irq_set(rdev);
+       /* 1M ring buffer */
+       r = r100_cp_init(rdev, 1024 * 1024);
+       if (r) {
+               dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+               return r;
+       }
+       r = r100_wb_init(rdev);
+       if (r)
+               dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+       r = r100_ib_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+               return r;
+       }
+       return 0;
+}
+
+int r300_resume(struct radeon_device *rdev)
+{
+       /* Make sur GART are not working */
+       if (rdev->flags & RADEON_IS_PCIE)
+               rv370_pcie_gart_disable(rdev);
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_disable(rdev);
+       /* Resume clock before doing reset */
+       r300_clock_startup(rdev);
+       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+       if (radeon_gpu_reset(rdev)) {
+               dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+                       RREG32(R_000E40_RBBM_STATUS),
+                       RREG32(R_0007C0_CP_STAT));
+       }
+       /* post */
+       radeon_combios_asic_init(rdev->ddev);
+       /* Resume clock after posting */
+       r300_clock_startup(rdev);
+       return r300_startup(rdev);
+}
+
+int r300_suspend(struct radeon_device *rdev)
+{
+       r100_cp_disable(rdev);
+       r100_wb_disable(rdev);
+       r100_irq_disable(rdev);
+       if (rdev->flags & RADEON_IS_PCIE)
+               rv370_pcie_gart_disable(rdev);
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_disable(rdev);
+       return 0;
+}
+
+void r300_fini(struct radeon_device *rdev)
+{
+       r300_suspend(rdev);
+       r100_cp_fini(rdev);
+       r100_wb_fini(rdev);
+       r100_ib_fini(rdev);
+       radeon_gem_fini(rdev);
+       if (rdev->flags & RADEON_IS_PCIE)
+               rv370_pcie_gart_fini(rdev);
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_fini(rdev);
+       radeon_irq_kms_fini(rdev);
+       radeon_fence_driver_fini(rdev);
+       radeon_object_fini(rdev);
+       radeon_atombios_fini(rdev);
+       kfree(rdev->bios);
+       rdev->bios = NULL;
+}
+
+int r300_init(struct radeon_device *rdev)
+{
+       int r;
+
+       /* Disable VGA */
+       r100_vga_render_disable(rdev);
+       /* Initialize scratch registers */
+       radeon_scratch_init(rdev);
+       /* Initialize surface registers */
+       radeon_surface_init(rdev);
+       /* TODO: disable VGA need to use VGA request */
+       /* BIOS*/
+       if (!radeon_get_bios(rdev)) {
+               if (ASIC_IS_AVIVO(rdev))
+                       return -EINVAL;
+       }
+       if (rdev->is_atom_bios) {
+               dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
+               return -EINVAL;
+       } else {
+               r = radeon_combios_init(rdev);
+               if (r)
+                       return r;
+       }
+       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+       if (radeon_gpu_reset(rdev)) {
+               dev_warn(rdev->dev,
+                       "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+                       RREG32(R_000E40_RBBM_STATUS),
+                       RREG32(R_0007C0_CP_STAT));
+       }
+       /* check if cards are posted or not */
+       if (!radeon_card_posted(rdev) && rdev->bios) {
+               DRM_INFO("GPU not posted. posting now...\n");
+               radeon_combios_asic_init(rdev->ddev);
+       }
+       /* Set asic errata */
+       r300_errata(rdev);
+       /* Initialize clocks */
+       radeon_get_clock_info(rdev->ddev);
+       /* Get vram informations */
+       r300_vram_info(rdev);
+       /* Initialize memory controller (also test AGP) */
+       r = r420_mc_init(rdev);
+       if (r)
+               return r;
+       /* Fence driver */
+       r = radeon_fence_driver_init(rdev);
+       if (r)
+               return r;
+       r = radeon_irq_kms_init(rdev);
+       if (r)
+               return r;
+       /* Memory manager */
+       r = radeon_object_init(rdev);
+       if (r)
+               return r;
+       if (rdev->flags & RADEON_IS_PCIE) {
+               r = rv370_pcie_gart_init(rdev);
+               if (r)
+                       return r;
+       }
+       if (rdev->flags & RADEON_IS_PCI) {
+               r = r100_pci_gart_init(rdev);
+               if (r)
+                       return r;
+       }
+       r300_set_reg_safe(rdev);
+       rdev->accel_working = true;
+       r = r300_startup(rdev);
+       if (r) {
+               /* Somethings want wront with the accel init stop accel */
+               dev_err(rdev->dev, "Disabling GPU acceleration\n");
+               r300_suspend(rdev);
+               r100_cp_fini(rdev);
+               r100_wb_fini(rdev);
+               r100_ib_fini(rdev);
+               if (rdev->flags & RADEON_IS_PCIE)
+                       rv370_pcie_gart_fini(rdev);
+               if (rdev->flags & RADEON_IS_PCI)
+                       r100_pci_gart_fini(rdev);
+               radeon_irq_kms_fini(rdev);
+               rdev->accel_working = false;
+       }
+       return 0;
+}
index d4fa3eb..4c73114 100644 (file)
 #define   S_000170_AGP_BASE_ADDR(x)                    (((x) & 0xFFFFFFFF) << 0)
 #define   G_000170_AGP_BASE_ADDR(x)                    (((x) >> 0) & 0xFFFFFFFF)
 #define   C_000170_AGP_BASE_ADDR                       0x00000000
+#define R_0007C0_CP_STAT                             0x0007C0
+#define   S_0007C0_MRU_BUSY(x)                         (((x) & 0x1) << 0)
+#define   G_0007C0_MRU_BUSY(x)                         (((x) >> 0) & 0x1)
+#define   C_0007C0_MRU_BUSY                            0xFFFFFFFE
+#define   S_0007C0_MWU_BUSY(x)                         (((x) & 0x1) << 1)
+#define   G_0007C0_MWU_BUSY(x)                         (((x) >> 1) & 0x1)
+#define   C_0007C0_MWU_BUSY                            0xFFFFFFFD
+#define   S_0007C0_RSIU_BUSY(x)                        (((x) & 0x1) << 2)
+#define   G_0007C0_RSIU_BUSY(x)                        (((x) >> 2) & 0x1)
+#define   C_0007C0_RSIU_BUSY                           0xFFFFFFFB
+#define   S_0007C0_RCIU_BUSY(x)                        (((x) & 0x1) << 3)
+#define   G_0007C0_RCIU_BUSY(x)                        (((x) >> 3) & 0x1)
+#define   C_0007C0_RCIU_BUSY                           0xFFFFFFF7
+#define   S_0007C0_CSF_PRIMARY_BUSY(x)                 (((x) & 0x1) << 9)
+#define   G_0007C0_CSF_PRIMARY_BUSY(x)                 (((x) >> 9) & 0x1)
+#define   C_0007C0_CSF_PRIMARY_BUSY                    0xFFFFFDFF
+#define   S_0007C0_CSF_INDIRECT_BUSY(x)                (((x) & 0x1) << 10)
+#define   G_0007C0_CSF_INDIRECT_BUSY(x)                (((x) >> 10) & 0x1)
+#define   C_0007C0_CSF_INDIRECT_BUSY                   0xFFFFFBFF
+#define   S_0007C0_CSQ_PRIMARY_BUSY(x)                 (((x) & 0x1) << 11)
+#define   G_0007C0_CSQ_PRIMARY_BUSY(x)                 (((x) >> 11) & 0x1)
+#define   C_0007C0_CSQ_PRIMARY_BUSY                    0xFFFFF7FF
+#define   S_0007C0_CSQ_INDIRECT_BUSY(x)                (((x) & 0x1) << 12)
+#define   G_0007C0_CSQ_INDIRECT_BUSY(x)                (((x) >> 12) & 0x1)
+#define   C_0007C0_CSQ_INDIRECT_BUSY                   0xFFFFEFFF
+#define   S_0007C0_CSI_BUSY(x)                         (((x) & 0x1) << 13)
+#define   G_0007C0_CSI_BUSY(x)                         (((x) >> 13) & 0x1)
+#define   C_0007C0_CSI_BUSY                            0xFFFFDFFF
+#define   S_0007C0_CSF_INDIRECT2_BUSY(x)               (((x) & 0x1) << 14)
+#define   G_0007C0_CSF_INDIRECT2_BUSY(x)               (((x) >> 14) & 0x1)
+#define   C_0007C0_CSF_INDIRECT2_BUSY                  0xFFFFBFFF
+#define   S_0007C0_CSQ_INDIRECT2_BUSY(x)               (((x) & 0x1) << 15)
+#define   G_0007C0_CSQ_INDIRECT2_BUSY(x)               (((x) >> 15) & 0x1)
+#define   C_0007C0_CSQ_INDIRECT2_BUSY                  0xFFFF7FFF
+#define   S_0007C0_GUIDMA_BUSY(x)                      (((x) & 0x1) << 28)
+#define   G_0007C0_GUIDMA_BUSY(x)                      (((x) >> 28) & 0x1)
+#define   C_0007C0_GUIDMA_BUSY                         0xEFFFFFFF
+#define   S_0007C0_VIDDMA_BUSY(x)                      (((x) & 0x1) << 29)
+#define   G_0007C0_VIDDMA_BUSY(x)                      (((x) >> 29) & 0x1)
+#define   C_0007C0_VIDDMA_BUSY                         0xDFFFFFFF
+#define   S_0007C0_CMDSTRM_BUSY(x)                     (((x) & 0x1) << 30)
+#define   G_0007C0_CMDSTRM_BUSY(x)                     (((x) >> 30) & 0x1)
+#define   C_0007C0_CMDSTRM_BUSY                        0xBFFFFFFF
+#define   S_0007C0_CP_BUSY(x)                          (((x) & 0x1) << 31)
+#define   G_0007C0_CP_BUSY(x)                          (((x) >> 31) & 0x1)
+#define   C_0007C0_CP_BUSY                             0x7FFFFFFF
+#define R_000E40_RBBM_STATUS                         0x000E40
+#define   S_000E40_CMDFIFO_AVAIL(x)                    (((x) & 0x7F) << 0)
+#define   G_000E40_CMDFIFO_AVAIL(x)                    (((x) >> 0) & 0x7F)
+#define   C_000E40_CMDFIFO_AVAIL                       0xFFFFFF80
+#define   S_000E40_HIRQ_ON_RBB(x)                      (((x) & 0x1) << 8)
+#define   G_000E40_HIRQ_ON_RBB(x)                      (((x) >> 8) & 0x1)
+#define   C_000E40_HIRQ_ON_RBB                         0xFFFFFEFF
+#define   S_000E40_CPRQ_ON_RBB(x)                      (((x) & 0x1) << 9)
+#define   G_000E40_CPRQ_ON_RBB(x)                      (((x) >> 9) & 0x1)
+#define   C_000E40_CPRQ_ON_RBB                         0xFFFFFDFF
+#define   S_000E40_CFRQ_ON_RBB(x)                      (((x) & 0x1) << 10)
+#define   G_000E40_CFRQ_ON_RBB(x)                      (((x) >> 10) & 0x1)
+#define   C_000E40_CFRQ_ON_RBB                         0xFFFFFBFF
+#define   S_000E40_HIRQ_IN_RTBUF(x)                    (((x) & 0x1) << 11)
+#define   G_000E40_HIRQ_IN_RTBUF(x)                    (((x) >> 11) & 0x1)
+#define   C_000E40_HIRQ_IN_RTBUF                       0xFFFFF7FF
+#define   S_000E40_CPRQ_IN_RTBUF(x)                    (((x) & 0x1) << 12)
+#define   G_000E40_CPRQ_IN_RTBUF(x)                    (((x) >> 12) & 0x1)
+#define   C_000E40_CPRQ_IN_RTBUF                       0xFFFFEFFF
+#define   S_000E40_CFRQ_IN_RTBUF(x)                    (((x) & 0x1) << 13)
+#define   G_000E40_CFRQ_IN_RTBUF(x)                    (((x) >> 13) & 0x1)
+#define   C_000E40_CFRQ_IN_RTBUF                       0xFFFFDFFF
+#define   S_000E40_CF_PIPE_BUSY(x)                     (((x) & 0x1) << 14)
+#define   G_000E40_CF_PIPE_BUSY(x)                     (((x) >> 14) & 0x1)
+#define   C_000E40_CF_PIPE_BUSY                        0xFFFFBFFF
+#define   S_000E40_ENG_EV_BUSY(x)                      (((x) & 0x1) << 15)
+#define   G_000E40_ENG_EV_BUSY(x)                      (((x) >> 15) & 0x1)
+#define   C_000E40_ENG_EV_BUSY                         0xFFFF7FFF
+#define   S_000E40_CP_CMDSTRM_BUSY(x)                  (((x) & 0x1) << 16)
+#define   G_000E40_CP_CMDSTRM_BUSY(x)                  (((x) >> 16) & 0x1)
+#define   C_000E40_CP_CMDSTRM_BUSY                     0xFFFEFFFF
+#define   S_000E40_E2_BUSY(x)                          (((x) & 0x1) << 17)
+#define   G_000E40_E2_BUSY(x)                          (((x) >> 17) & 0x1)
+#define   C_000E40_E2_BUSY                             0xFFFDFFFF
+#define   S_000E40_RB2D_BUSY(x)                        (((x) & 0x1) << 18)
+#define   G_000E40_RB2D_BUSY(x)                        (((x) >> 18) & 0x1)
+#define   C_000E40_RB2D_BUSY                           0xFFFBFFFF
+#define   S_000E40_RB3D_BUSY(x)                        (((x) & 0x1) << 19)
+#define   G_000E40_RB3D_BUSY(x)                        (((x) >> 19) & 0x1)
+#define   C_000E40_RB3D_BUSY                           0xFFF7FFFF
+#define   S_000E40_VAP_BUSY(x)                         (((x) & 0x1) << 20)
+#define   G_000E40_VAP_BUSY(x)                         (((x) >> 20) & 0x1)
+#define   C_000E40_VAP_BUSY                            0xFFEFFFFF
+#define   S_000E40_RE_BUSY(x)                          (((x) & 0x1) << 21)
+#define   G_000E40_RE_BUSY(x)                          (((x) >> 21) & 0x1)
+#define   C_000E40_RE_BUSY                             0xFFDFFFFF
+#define   S_000E40_TAM_BUSY(x)                         (((x) & 0x1) << 22)
+#define   G_000E40_TAM_BUSY(x)                         (((x) >> 22) & 0x1)
+#define   C_000E40_TAM_BUSY                            0xFFBFFFFF
+#define   S_000E40_TDM_BUSY(x)                         (((x) & 0x1) << 23)
+#define   G_000E40_TDM_BUSY(x)                         (((x) >> 23) & 0x1)
+#define   C_000E40_TDM_BUSY                            0xFF7FFFFF
+#define   S_000E40_PB_BUSY(x)                          (((x) & 0x1) << 24)
+#define   G_000E40_PB_BUSY(x)                          (((x) >> 24) & 0x1)
+#define   C_000E40_PB_BUSY                             0xFEFFFFFF
+#define   S_000E40_TIM_BUSY(x)                         (((x) & 0x1) << 25)
+#define   G_000E40_TIM_BUSY(x)                         (((x) >> 25) & 0x1)
+#define   C_000E40_TIM_BUSY                            0xFDFFFFFF
+#define   S_000E40_GA_BUSY(x)                          (((x) & 0x1) << 26)
+#define   G_000E40_GA_BUSY(x)                          (((x) >> 26) & 0x1)
+#define   C_000E40_GA_BUSY                             0xFBFFFFFF
+#define   S_000E40_CBA2D_BUSY(x)                       (((x) & 0x1) << 27)
+#define   G_000E40_CBA2D_BUSY(x)                       (((x) >> 27) & 0x1)
+#define   C_000E40_CBA2D_BUSY                          0xF7FFFFFF
+#define   S_000E40_GUI_ACTIVE(x)                       (((x) & 0x1) << 31)
+#define   G_000E40_GUI_ACTIVE(x)                       (((x) >> 31) & 0x1)
+#define   C_000E40_GUI_ACTIVE                          0x7FFFFFFF
 
 
+#define R_00000D_SCLK_CNTL                           0x00000D
+#define   S_00000D_SCLK_SRC_SEL(x)                     (((x) & 0x7) << 0)
+#define   G_00000D_SCLK_SRC_SEL(x)                     (((x) >> 0) & 0x7)
+#define   C_00000D_SCLK_SRC_SEL                        0xFFFFFFF8
+#define   S_00000D_CP_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 3)
+#define   G_00000D_CP_MAX_DYN_STOP_LAT(x)              (((x) >> 3) & 0x1)
+#define   C_00000D_CP_MAX_DYN_STOP_LAT                 0xFFFFFFF7
+#define   S_00000D_HDP_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 4)
+#define   G_00000D_HDP_MAX_DYN_STOP_LAT(x)             (((x) >> 4) & 0x1)
+#define   C_00000D_HDP_MAX_DYN_STOP_LAT                0xFFFFFFEF
+#define   S_00000D_TV_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 5)
+#define   G_00000D_TV_MAX_DYN_STOP_LAT(x)              (((x) >> 5) & 0x1)
+#define   C_00000D_TV_MAX_DYN_STOP_LAT                 0xFFFFFFDF
+#define   S_00000D_E2_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 6)
+#define   G_00000D_E2_MAX_DYN_STOP_LAT(x)              (((x) >> 6) & 0x1)
+#define   C_00000D_E2_MAX_DYN_STOP_LAT                 0xFFFFFFBF
+#define   S_00000D_SE_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 7)
+#define   G_00000D_SE_MAX_DYN_STOP_LAT(x)              (((x) >> 7) & 0x1)
+#define   C_00000D_SE_MAX_DYN_STOP_LAT                 0xFFFFFF7F
+#define   S_00000D_IDCT_MAX_DYN_STOP_LAT(x)            (((x) & 0x1) << 8)
+#define   G_00000D_IDCT_MAX_DYN_STOP_LAT(x)            (((x) >> 8) & 0x1)
+#define   C_00000D_IDCT_MAX_DYN_STOP_LAT               0xFFFFFEFF
+#define   S_00000D_VIP_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 9)
+#define   G_00000D_VIP_MAX_DYN_STOP_LAT(x)             (((x) >> 9) & 0x1)
+#define   C_00000D_VIP_MAX_DYN_STOP_LAT                0xFFFFFDFF
+#define   S_00000D_RE_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 10)
+#define   G_00000D_RE_MAX_DYN_STOP_LAT(x)              (((x) >> 10) & 0x1)
+#define   C_00000D_RE_MAX_DYN_STOP_LAT                 0xFFFFFBFF
+#define   S_00000D_PB_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 11)
+#define   G_00000D_PB_MAX_DYN_STOP_LAT(x)              (((x) >> 11) & 0x1)
+#define   C_00000D_PB_MAX_DYN_STOP_LAT                 0xFFFFF7FF
+#define   S_00000D_TAM_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 12)
+#define   G_00000D_TAM_MAX_DYN_STOP_LAT(x)             (((x) >> 12) & 0x1)
+#define   C_00000D_TAM_MAX_DYN_STOP_LAT                0xFFFFEFFF
+#define   S_00000D_TDM_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 13)
+#define   G_00000D_TDM_MAX_DYN_STOP_LAT(x)             (((x) >> 13) & 0x1)
+#define   C_00000D_TDM_MAX_DYN_STOP_LAT                0xFFFFDFFF
+#define   S_00000D_RB_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 14)
+#define   G_00000D_RB_MAX_DYN_STOP_LAT(x)              (((x) >> 14) & 0x1)
+#define   C_00000D_RB_MAX_DYN_STOP_LAT                 0xFFFFBFFF
+#define   S_00000D_FORCE_DISP2(x)                      (((x) & 0x1) << 15)
+#define   G_00000D_FORCE_DISP2(x)                      (((x) >> 15) & 0x1)
+#define   C_00000D_FORCE_DISP2                         0xFFFF7FFF
+#define   S_00000D_FORCE_CP(x)                         (((x) & 0x1) << 16)
+#define   G_00000D_FORCE_CP(x)                         (((x) >> 16) & 0x1)
+#define   C_00000D_FORCE_CP                            0xFFFEFFFF
+#define   S_00000D_FORCE_HDP(x)                        (((x) & 0x1) << 17)
+#define   G_00000D_FORCE_HDP(x)                        (((x) >> 17) & 0x1)
+#define   C_00000D_FORCE_HDP                           0xFFFDFFFF
+#define   S_00000D_FORCE_DISP1(x)                      (((x) & 0x1) << 18)
+#define   G_00000D_FORCE_DISP1(x)                      (((x) >> 18) & 0x1)
+#define   C_00000D_FORCE_DISP1                         0xFFFBFFFF
+#define   S_00000D_FORCE_TOP(x)                        (((x) & 0x1) << 19)
+#define   G_00000D_FORCE_TOP(x)                        (((x) >> 19) & 0x1)
+#define   C_00000D_FORCE_TOP                           0xFFF7FFFF
+#define   S_00000D_FORCE_E2(x)                         (((x) & 0x1) << 20)
+#define   G_00000D_FORCE_E2(x)                         (((x) >> 20) & 0x1)
+#define   C_00000D_FORCE_E2                            0xFFEFFFFF
+#define   S_00000D_FORCE_SE(x)                         (((x) & 0x1) << 21)
+#define   G_00000D_FORCE_SE(x)                         (((x) >> 21) & 0x1)
+#define   C_00000D_FORCE_SE                            0xFFDFFFFF
+#define   S_00000D_FORCE_IDCT(x)                       (((x) & 0x1) << 22)
+#define   G_00000D_FORCE_IDCT(x)                       (((x) >> 22) & 0x1)
+#define   C_00000D_FORCE_IDCT                          0xFFBFFFFF
+#define   S_00000D_FORCE_VIP(x)                        (((x) & 0x1) << 23)
+#define   G_00000D_FORCE_VIP(x)                        (((x) >> 23) & 0x1)
+#define   C_00000D_FORCE_VIP                           0xFF7FFFFF
+#define   S_00000D_FORCE_RE(x)                         (((x) & 0x1) << 24)
+#define   G_00000D_FORCE_RE(x)                         (((x) >> 24) & 0x1)
+#define   C_00000D_FORCE_RE                            0xFEFFFFFF
+#define   S_00000D_FORCE_PB(x)                         (((x) & 0x1) << 25)
+#define   G_00000D_FORCE_PB(x)                         (((x) >> 25) & 0x1)
+#define   C_00000D_FORCE_PB                            0xFDFFFFFF
+#define   S_00000D_FORCE_TAM(x)                        (((x) & 0x1) << 26)
+#define   G_00000D_FORCE_TAM(x)                        (((x) >> 26) & 0x1)
+#define   C_00000D_FORCE_TAM                           0xFBFFFFFF
+#define   S_00000D_FORCE_TDM(x)                        (((x) & 0x1) << 27)
+#define   G_00000D_FORCE_TDM(x)                        (((x) >> 27) & 0x1)
+#define   C_00000D_FORCE_TDM                           0xF7FFFFFF
+#define   S_00000D_FORCE_RB(x)                         (((x) & 0x1) << 28)
+#define   G_00000D_FORCE_RB(x)                         (((x) >> 28) & 0x1)
+#define   C_00000D_FORCE_RB                            0xEFFFFFFF
+#define   S_00000D_FORCE_TV_SCLK(x)                    (((x) & 0x1) << 29)
+#define   G_00000D_FORCE_TV_SCLK(x)                    (((x) >> 29) & 0x1)
+#define   C_00000D_FORCE_TV_SCLK                       0xDFFFFFFF
+#define   S_00000D_FORCE_SUBPIC(x)                     (((x) & 0x1) << 30)
+#define   G_00000D_FORCE_SUBPIC(x)                     (((x) >> 30) & 0x1)
+#define   C_00000D_FORCE_SUBPIC                        0xBFFFFFFF
+#define   S_00000D_FORCE_OV0(x)                        (((x) & 0x1) << 31)
+#define   G_00000D_FORCE_OV0(x)                        (((x) >> 31) & 0x1)
+#define   C_00000D_FORCE_OV0                           0x7FFFFFFF
+
 #endif
index 49a2fdc..5c7fe52 100644 (file)
@@ -155,6 +155,9 @@ static void r420_debugfs(struct radeon_device *rdev)
 static void r420_clock_resume(struct radeon_device *rdev)
 {
        u32 sclk_cntl;
+
+       if (radeon_dynclks != -1 && radeon_dynclks)
+               radeon_atom_set_clock_gating(rdev, 1);
        sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL);
        sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
        if (rdev->family == CHIP_R420)
@@ -167,6 +170,8 @@ static int r420_startup(struct radeon_device *rdev)
        int r;
 
        r300_mc_program(rdev);
+       /* Resume clock */
+       r420_clock_resume(rdev);
        /* Initialize GART (initialize after TTM so we can allocate
         * memory through TTM but finalize after TTM) */
        if (rdev->flags & RADEON_IS_PCIE) {
@@ -267,7 +272,6 @@ int r420_init(struct radeon_device *rdev)
 {
        int r;
 
-       rdev->new_init_path = true;
        /* Initialize scratch registers */
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
index a48a7db..fc78d31 100644 (file)
 #define   S_00000D_FORCE_E2(x)                         (((x) & 0x1) << 20)
 #define   G_00000D_FORCE_E2(x)                         (((x) >> 20) & 0x1)
 #define   C_00000D_FORCE_E2                            0xFFEFFFFF
-#define   S_00000D_FORCE_SE(x)                         (((x) & 0x1) << 21)
-#define   G_00000D_FORCE_SE(x)                         (((x) >> 21) & 0x1)
-#define   C_00000D_FORCE_SE                            0xFFDFFFFF
+#define   S_00000D_FORCE_VAP(x)                        (((x) & 0x1) << 21)
+#define   G_00000D_FORCE_VAP(x)                        (((x) >> 21) & 0x1)
+#define   C_00000D_FORCE_VAP                           0xFFDFFFFF
 #define   S_00000D_FORCE_IDCT(x)                       (((x) & 0x1) << 22)
 #define   G_00000D_FORCE_IDCT(x)                       (((x) >> 22) & 0x1)
 #define   C_00000D_FORCE_IDCT                          0xFFBFFFFF
 #define   S_00000D_FORCE_RE(x)                         (((x) & 0x1) << 24)
 #define   G_00000D_FORCE_RE(x)                         (((x) >> 24) & 0x1)
 #define   C_00000D_FORCE_RE                            0xFEFFFFFF
-#define   S_00000D_FORCE_PB(x)                         (((x) & 0x1) << 25)
-#define   G_00000D_FORCE_PB(x)                         (((x) >> 25) & 0x1)
-#define   C_00000D_FORCE_PB                            0xFDFFFFFF
+#define   S_00000D_FORCE_SR(x)                         (((x) & 0x1) << 25)
+#define   G_00000D_FORCE_SR(x)                         (((x) >> 25) & 0x1)
+#define   C_00000D_FORCE_SR                            0xFDFFFFFF
 #define   S_00000D_FORCE_PX(x)                         (((x) & 0x1) << 26)
 #define   G_00000D_FORCE_PX(x)                         (((x) >> 26) & 0x1)
 #define   C_00000D_FORCE_PX                            0xFBFFFFFF
 #define   S_00000D_FORCE_TX(x)                         (((x) & 0x1) << 27)
 #define   G_00000D_FORCE_TX(x)                         (((x) >> 27) & 0x1)
 #define   C_00000D_FORCE_TX                            0xF7FFFFFF
-#define   S_00000D_FORCE_RB(x)                         (((x) & 0x1) << 28)
-#define   G_00000D_FORCE_RB(x)                         (((x) >> 28) & 0x1)
-#define   C_00000D_FORCE_RB                            0xEFFFFFFF
+#define   S_00000D_FORCE_US(x)                         (((x) & 0x1) << 28)
+#define   G_00000D_FORCE_US(x)                         (((x) >> 28) & 0x1)
+#define   C_00000D_FORCE_US                            0xEFFFFFFF
 #define   S_00000D_FORCE_TV_SCLK(x)                    (((x) & 0x1) << 29)
 #define   G_00000D_FORCE_TV_SCLK(x)                    (((x) >> 29) & 0x1)
 #define   C_00000D_FORCE_TV_SCLK                       0xDFFFFFFF
-#define   S_00000D_FORCE_SUBPIC(x)                     (((x) & 0x1) << 30)
-#define   G_00000D_FORCE_SUBPIC(x)                     (((x) >> 30) & 0x1)
-#define   C_00000D_FORCE_SUBPIC                        0xBFFFFFFF
+#define   S_00000D_FORCE_SU(x)                         (((x) & 0x1) << 30)
+#define   G_00000D_FORCE_SU(x)                         (((x) >> 30) & 0x1)
+#define   C_00000D_FORCE_SU                            0xBFFFFFFF
 #define   S_00000D_FORCE_OV0(x)                        (((x) & 0x1) << 31)
 #define   G_00000D_FORCE_OV0(x)                        (((x) >> 31) & 0x1)
 #define   C_00000D_FORCE_OV0                           0x7FFFFFFF
index 0bf13fc..a555b7b 100644 (file)
@@ -186,7 +186,7 @@ static int r520_startup(struct radeon_device *rdev)
        }
        /* Enable IRQ */
        rdev->irq.sw_int = true;
-       r100_irq_set(rdev);
+       rs600_irq_set(rdev);
        /* 1M ring buffer */
        r = r100_cp_init(rdev, 1024 * 1024);
        if (r) {
@@ -228,7 +228,6 @@ int r520_init(struct radeon_device *rdev)
 {
        int r;
 
-       rdev->new_init_path = true;
        /* Initialize scratch registers */
        radeon_scratch_init(rdev);
        /* Initialize surface registers */
index 2e4e60e..6097194 100644 (file)
@@ -65,16 +65,11 @@ MODULE_FIRMWARE("radeon/RV710_me.bin");
 
 int r600_debugfs_mc_info_init(struct radeon_device *rdev);
 
-/* This files gather functions specifics to:
- * r600,rv610,rv630,rv620,rv635,rv670
- *
- * Some of these functions might be used by newer ASICs.
- */
+/* r600,rv610,rv630,rv620,rv635,rv670 */
 int r600_mc_wait_for_idle(struct radeon_device *rdev);
 void r600_gpu_init(struct radeon_device *rdev);
 void r600_fini(struct radeon_device *rdev);
 
-
 /*
  * R600 PCIE GART
  */
@@ -168,7 +163,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
@@ -225,6 +220,40 @@ void r600_pcie_gart_fini(struct radeon_device *rdev)
        radeon_gart_fini(rdev);
 }
 
+void r600_agp_enable(struct radeon_device *rdev)
+{
+       u32 tmp;
+       int i;
+
+       /* Setup L2 cache */
+       WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+                               ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+                               EFFECTIVE_L2_QUEUE_SIZE(7));
+       WREG32(VM_L2_CNTL2, 0);
+       WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
+       /* Setup TLB control */
+       tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+               SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+               EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
+               ENABLE_WAIT_L2_QUERY;
+       WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
+       WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+       WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+       for (i = 0; i < 7; i++)
+               WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+}
+
 int r600_mc_wait_for_idle(struct radeon_device *rdev)
 {
        unsigned i;
@@ -240,14 +269,9 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
        return -1;
 }
 
-static void r600_mc_resume(struct radeon_device *rdev)
+static void r600_mc_program(struct radeon_device *rdev)
 {
-       u32 d1vga_control, d2vga_control;
-       u32 vga_render_control, vga_hdp_control;
-       u32 d1crtc_control, d2crtc_control;
-       u32 new_d1grph_primary, new_d1grph_secondary;
-       u32 new_d2grph_primary, new_d2grph_secondary;
-       u64 old_vram_start;
+       struct rv515_mc_save save;
        u32 tmp;
        int i, j;
 
@@ -261,85 +285,51 @@ static void r600_mc_resume(struct radeon_device *rdev)
        }
        WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
 
-       d1vga_control = RREG32(D1VGA_CONTROL);
-       d2vga_control = RREG32(D2VGA_CONTROL);
-       vga_render_control = RREG32(VGA_RENDER_CONTROL);
-       vga_hdp_control = RREG32(VGA_HDP_CONTROL);
-       d1crtc_control = RREG32(D1CRTC_CONTROL);
-       d2crtc_control = RREG32(D2CRTC_CONTROL);
-       old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
-       new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
-       new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
-       new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
-       new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
-       new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
-       new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
-       new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
-       new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
-
-       /* Stop all video */
-       WREG32(D1VGA_CONTROL, 0);
-       WREG32(D2VGA_CONTROL, 0);
-       WREG32(VGA_RENDER_CONTROL, 0);
-       WREG32(D1CRTC_UPDATE_LOCK, 1);
-       WREG32(D2CRTC_UPDATE_LOCK, 1);
-       WREG32(D1CRTC_CONTROL, 0);
-       WREG32(D2CRTC_CONTROL, 0);
-       WREG32(D1CRTC_UPDATE_LOCK, 0);
-       WREG32(D2CRTC_UPDATE_LOCK, 0);
-
-       mdelay(1);
+       rv515_mc_stop(rdev, &save);
        if (r600_mc_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "[drm] MC not idle !\n");
+               dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
-
-       /* Lockout access through VGA aperture*/
+       /* Lockout access through VGA aperture (doesn't exist before R600) */
        WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
-
        /* Update configuration */
-       WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
-       WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
+       if (rdev->flags & RADEON_IS_AGP) {
+               if (rdev->mc.vram_start < rdev->mc.gtt_start) {
+                       /* VRAM before AGP */
+                       WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+                               rdev->mc.vram_start >> 12);
+                       WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+                               rdev->mc.gtt_end >> 12);
+               } else {
+                       /* VRAM after AGP */
+                       WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+                               rdev->mc.gtt_start >> 12);
+                       WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+                               rdev->mc.vram_end >> 12);
+               }
+       } else {
+               WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
+               WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);
+       }
        WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
-       tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
+       tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
        tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
        WREG32(MC_VM_FB_LOCATION, tmp);
        WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
        WREG32(HDP_NONSURFACE_INFO, (2 << 7));
-       WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
+       WREG32(HDP_NONSURFACE_SIZE, rdev->mc.mc_vram_size | 0x3FF);
        if (rdev->flags & RADEON_IS_AGP) {
-               WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
-               WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
+               WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22);
+               WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22);
                WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
        } else {
                WREG32(MC_VM_AGP_BASE, 0);
                WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
                WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
        }
-       WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
-       WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
-       WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
-       WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
-       WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
-
-       /* Unlock host access */
-       WREG32(VGA_HDP_CONTROL, vga_hdp_control);
-
-       mdelay(1);
        if (r600_mc_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "[drm] MC not idle !\n");
+               dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
-
-       /* Restore video state */
-       WREG32(D1CRTC_UPDATE_LOCK, 1);
-       WREG32(D2CRTC_UPDATE_LOCK, 1);
-       WREG32(D1CRTC_CONTROL, d1crtc_control);
-       WREG32(D2CRTC_CONTROL, d2crtc_control);
-       WREG32(D1CRTC_UPDATE_LOCK, 0);
-       WREG32(D2CRTC_UPDATE_LOCK, 0);
-       WREG32(D1VGA_CONTROL, d1vga_control);
-       WREG32(D2VGA_CONTROL, d2vga_control);
-       WREG32(VGA_RENDER_CONTROL, vga_render_control);
-
+       rv515_mc_resume(rdev, &save);
        /* we need to own VRAM, so turn off the VGA renderer here
         * to stop it overwriting our objects */
        rv515_vga_render_disable(rdev);
@@ -445,9 +435,9 @@ int r600_mc_init(struct radeon_device *rdev)
                }
        }
        rdev->mc.vram_start = rdev->mc.vram_location;
-       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
        rdev->mc.gtt_start = rdev->mc.gtt_location;
-       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
+       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
         */
@@ -463,6 +453,7 @@ int r600_mc_init(struct radeon_device *rdev)
  */
 int r600_gpu_soft_reset(struct radeon_device *rdev)
 {
+       struct rv515_mc_save save;
        u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
                                S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
                                S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
@@ -480,13 +471,25 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
                        S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
                        S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
        u32 srbm_reset = 0;
+       u32 tmp;
 
+       dev_info(rdev->dev, "GPU softreset \n");
+       dev_info(rdev->dev, "  R_008010_GRBM_STATUS=0x%08X\n",
+               RREG32(R_008010_GRBM_STATUS));
+       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2=0x%08X\n",
+               RREG32(R_008014_GRBM_STATUS2));
+       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS=0x%08X\n",
+               RREG32(R_000E50_SRBM_STATUS));
+       rv515_mc_stop(rdev, &save);
+       if (r600_mc_wait_for_idle(rdev)) {
+               dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+       }
        /* Disable CP parsing/prefetching */
        WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
        /* Check if any of the rendering block is busy and reset it */
        if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
            (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
-               WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) |
+               tmp = S_008020_SOFT_RESET_CR(1) |
                        S_008020_SOFT_RESET_DB(1) |
                        S_008020_SOFT_RESET_CB(1) |
                        S_008020_SOFT_RESET_PA(1) |
@@ -498,14 +501,18 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
                        S_008020_SOFT_RESET_TC(1) |
                        S_008020_SOFT_RESET_TA(1) |
                        S_008020_SOFT_RESET_VC(1) |
-                       S_008020_SOFT_RESET_VGT(1));
+                       S_008020_SOFT_RESET_VGT(1);
+               dev_info(rdev->dev, "  R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
+               WREG32(R_008020_GRBM_SOFT_RESET, tmp);
                (void)RREG32(R_008020_GRBM_SOFT_RESET);
                udelay(50);
                WREG32(R_008020_GRBM_SOFT_RESET, 0);
                (void)RREG32(R_008020_GRBM_SOFT_RESET);
        }
        /* Reset CP (we always reset CP) */
-       WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1));
+       tmp = S_008020_SOFT_RESET_CP(1);
+       dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
+       WREG32(R_008020_GRBM_SOFT_RESET, tmp);
        (void)RREG32(R_008020_GRBM_SOFT_RESET);
        udelay(50);
        WREG32(R_008020_GRBM_SOFT_RESET, 0);
@@ -533,6 +540,14 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
                srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
        if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
                srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
+       if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+               srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
+       dev_info(rdev->dev, "  R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
+       WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
+       (void)RREG32(R_000E60_SRBM_SOFT_RESET);
+       udelay(50);
+       WREG32(R_000E60_SRBM_SOFT_RESET, 0);
+       (void)RREG32(R_000E60_SRBM_SOFT_RESET);
        WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
        (void)RREG32(R_000E60_SRBM_SOFT_RESET);
        udelay(50);
@@ -540,6 +555,17 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
        (void)RREG32(R_000E60_SRBM_SOFT_RESET);
        /* Wait a little for things to settle down */
        udelay(50);
+       dev_info(rdev->dev, "  R_008010_GRBM_STATUS=0x%08X\n",
+               RREG32(R_008010_GRBM_STATUS));
+       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2=0x%08X\n",
+               RREG32(R_008014_GRBM_STATUS2));
+       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS=0x%08X\n",
+               RREG32(R_000E50_SRBM_STATUS));
+       /* After reset we need to reinit the asic as GPU often endup in an
+        * incoherent state.
+        */
+       atom_asic_init(rdev->mode_info.atom_context);
+       rv515_mc_resume(rdev, &save);
        return 0;
 }
 
@@ -1350,32 +1376,47 @@ int r600_ring_test(struct radeon_device *rdev)
        return r;
 }
 
-/*
- * Writeback
- */
-int r600_wb_init(struct radeon_device *rdev)
+void r600_wb_disable(struct radeon_device *rdev)
+{
+       WREG32(SCRATCH_UMSK, 0);
+       if (rdev->wb.wb_obj) {
+               radeon_object_kunmap(rdev->wb.wb_obj);
+               radeon_object_unpin(rdev->wb.wb_obj);
+       }
+}
+
+void r600_wb_fini(struct radeon_device *rdev)
+{
+       r600_wb_disable(rdev);
+       if (rdev->wb.wb_obj) {
+               radeon_object_unref(&rdev->wb.wb_obj);
+               rdev->wb.wb = NULL;
+               rdev->wb.wb_obj = NULL;
+       }
+}
+
+int r600_wb_enable(struct radeon_device *rdev)
 {
        int r;
 
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_object_create(rdev, NULL, 4096,
-                                        true,
-                                        RADEON_GEM_DOMAIN_GTT,
-                                        false, &rdev->wb.wb_obj);
+               r = radeon_object_create(rdev, NULL, 4096, true,
+                               RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
                if (r) {
-                       DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
+                       dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
                        return r;
                }
-               r = radeon_object_pin(rdev->wb.wb_obj,
-                                     RADEON_GEM_DOMAIN_GTT,
-                                     &rdev->wb.gpu_addr);
+               r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
+                               &rdev->wb.gpu_addr);
                if (r) {
-                       DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
+                       dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r);
+                       r600_wb_fini(rdev);
                        return r;
                }
                r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
                if (r) {
-                       DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
+                       dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r);
+                       r600_wb_fini(rdev);
                        return r;
                }
        }
@@ -1386,21 +1427,6 @@ int r600_wb_init(struct radeon_device *rdev)
        return 0;
 }
 
-void r600_wb_fini(struct radeon_device *rdev)
-{
-       if (rdev->wb.wb_obj) {
-               radeon_object_kunmap(rdev->wb.wb_obj);
-               radeon_object_unpin(rdev->wb.wb_obj);
-               radeon_object_unref(&rdev->wb.wb_obj);
-               rdev->wb.wb = NULL;
-               rdev->wb.wb_obj = NULL;
-       }
-}
-
-
-/*
- * CS
- */
 void r600_fence_ring_emit(struct radeon_device *rdev,
                          struct radeon_fence *fence)
 {
@@ -1477,11 +1503,14 @@ int r600_startup(struct radeon_device *rdev)
 {
        int r;
 
-       r600_gpu_reset(rdev);
-       r600_mc_resume(rdev);
-       r = r600_pcie_gart_enable(rdev);
-       if (r)
-               return r;
+       r600_mc_program(rdev);
+       if (rdev->flags & RADEON_IS_AGP) {
+               r600_agp_enable(rdev);
+       } else {
+               r = r600_pcie_gart_enable(rdev);
+               if (r)
+                       return r;
+       }
        r600_gpu_init(rdev);
 
        r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
@@ -1500,9 +1529,8 @@ int r600_startup(struct radeon_device *rdev)
        r = r600_cp_resume(rdev);
        if (r)
                return r;
-       r = r600_wb_init(rdev);
-       if (r)
-               return r;
+       /* write back buffer are not vital so don't worry about failure */
+       r600_wb_enable(rdev);
        return 0;
 }
 
@@ -1524,15 +1552,12 @@ int r600_resume(struct radeon_device *rdev)
 {
        int r;
 
-       if (radeon_gpu_reset(rdev)) {
-               /* FIXME: what do we want to do here ? */
-       }
+       /* Do not reset GPU before posting, on r600 hw unlike on r500 hw,
+        * posting will perform necessary task to bring back GPU into good
+        * shape.
+        */
        /* post card */
-       if (rdev->is_atom_bios) {
-               atom_asic_init(rdev->mode_info.atom_context);
-       } else {
-               radeon_combios_asic_init(rdev->ddev);
-       }
+       atom_asic_init(rdev->mode_info.atom_context);
        /* Initialize clocks */
        r = radeon_clocks_init(rdev);
        if (r) {
@@ -1545,7 +1570,7 @@ int r600_resume(struct radeon_device *rdev)
                return r;
        }
 
-       r = radeon_ib_test(rdev);
+       r = r600_ib_test(rdev);
        if (r) {
                DRM_ERROR("radeon: failled testing IB (%d).\n", r);
                return r;
@@ -1553,13 +1578,12 @@ int r600_resume(struct radeon_device *rdev)
        return r;
 }
 
-
 int r600_suspend(struct radeon_device *rdev)
 {
        /* FIXME: we should wait for ring to be empty */
        r600_cp_stop(rdev);
        rdev->cp.ready = false;
-
+       r600_wb_disable(rdev);
        r600_pcie_gart_disable(rdev);
        /* unpin shaders bo */
        radeon_object_unpin(rdev->r600_blit.shader_obj);
@@ -1576,7 +1600,6 @@ int r600_init(struct radeon_device *rdev)
 {
        int r;
 
-       rdev->new_init_path = true;
        r = radeon_dummy_page_init(rdev);
        if (r)
                return r;
@@ -1593,8 +1616,10 @@ int r600_init(struct radeon_device *rdev)
                        return -EINVAL;
        }
        /* Must be an ATOMBIOS */
-       if (!rdev->is_atom_bios)
+       if (!rdev->is_atom_bios) {
+               dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
                return -EINVAL;
+       }
        r = radeon_atombios_init(rdev);
        if (r)
                return r;
@@ -1616,15 +1641,8 @@ int r600_init(struct radeon_device *rdev)
        if (r)
                return r;
        r = r600_mc_init(rdev);
-       if (r) {
-               if (rdev->flags & RADEON_IS_AGP) {
-                       /* Retry with disabling AGP */
-                       r600_fini(rdev);
-                       rdev->flags &= ~RADEON_IS_AGP;
-                       return r600_init(rdev);
-               }
+       if (r)
                return r;
-       }
        /* Memory manager */
        r = radeon_object_init(rdev);
        if (r)
@@ -1653,12 +1671,10 @@ int r600_init(struct radeon_device *rdev)
 
        r = r600_startup(rdev);
        if (r) {
-               if (rdev->flags & RADEON_IS_AGP) {
-                       /* Retry with disabling AGP */
-                       r600_fini(rdev);
-                       rdev->flags &= ~RADEON_IS_AGP;
-                       return r600_init(rdev);
-               }
+               r600_suspend(rdev);
+               r600_wb_fini(rdev);
+               radeon_ring_fini(rdev);
+               r600_pcie_gart_fini(rdev);
                rdev->accel_working = false;
        }
        if (rdev->accel_working) {
@@ -1667,7 +1683,7 @@ int r600_init(struct radeon_device *rdev)
                        DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
                        rdev->accel_working = false;
                }
-               r = radeon_ib_test(rdev);
+               r = r600_ib_test(rdev);
                if (r) {
                        DRM_ERROR("radeon: failled testing IB (%d).\n", r);
                        rdev->accel_working = false;
@@ -1683,19 +1699,15 @@ void r600_fini(struct radeon_device *rdev)
 
        r600_blit_fini(rdev);
        radeon_ring_fini(rdev);
+       r600_wb_fini(rdev);
        r600_pcie_gart_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
        radeon_clocks_fini(rdev);
-#if __OS_HAS_AGP
        if (rdev->flags & RADEON_IS_AGP)
                radeon_agp_fini(rdev);
-#endif
        radeon_object_fini(rdev);
-       if (rdev->is_atom_bios)
-               radeon_atombios_fini(rdev);
-       else
-               radeon_combios_fini(rdev);
+       radeon_atombios_fini(rdev);
        kfree(rdev->bios);
        rdev->bios = NULL;
        radeon_dummy_page_fini(rdev);
index d988eec..dec5010 100644 (file)
@@ -582,8 +582,6 @@ r600_blit_copy(struct drm_device *dev,
        u64 vb_addr;
        u32 *vb;
 
-       vb = r600_nomm_get_vb_ptr(dev);
-
        if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
                max_bytes = 8192;
 
@@ -619,8 +617,8 @@ r600_blit_copy(struct drm_device *dev,
                                if (!dev_priv->blit_vb)
                                        return;
                                set_shaders(dev);
-                               vb = r600_nomm_get_vb_ptr(dev);
                        }
+                       vb = r600_nomm_get_vb_ptr(dev);
 
                        vb[0] = i2f(dst_x);
                        vb[1] = 0;
@@ -708,8 +706,8 @@ r600_blit_copy(struct drm_device *dev,
                                        return;
 
                                set_shaders(dev);
-                               vb = r600_nomm_get_vb_ptr(dev);
                        }
+                       vb = r600_nomm_get_vb_ptr(dev);
 
                        vb[0] = i2f(dst_x / 4);
                        vb[1] = 0;
@@ -777,8 +775,6 @@ r600_blit_swap(struct drm_device *dev,
        u64 vb_addr;
        u32 *vb;
 
-       vb = r600_nomm_get_vb_ptr(dev);
-
        if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
 
                r600_nomm_put_vb(dev);
@@ -787,8 +783,8 @@ r600_blit_swap(struct drm_device *dev,
                        return;
 
                set_shaders(dev);
-               vb = r600_nomm_get_vb_ptr(dev);
        }
+       vb = r600_nomm_get_vb_ptr(dev);
 
        if (cpp == 4) {
                cb_format = COLOR_8_8_8_8;
index acae33e..93108bb 100644 (file)
@@ -610,7 +610,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
 
        DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
                  size_bytes, rdev->r600_blit.vb_used);
-       vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
        if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
                max_bytes = 8192;
 
@@ -653,6 +652,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
                                vb = r600_nomm_get_vb_ptr(dev);
 #endif
                        }
+                       vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
 
                        vb[0] = i2f(dst_x);
                        vb[1] = 0;
@@ -747,6 +747,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
                                vb = r600_nomm_get_vb_ptr(dev);
                        }
 #endif
+                       vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
 
                        vb[0] = i2f(dst_x / 4);
                        vb[1] = 0;
index d28970d..17e4219 100644 (file)
@@ -252,7 +252,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p)
 
        header = radeon_get_ib_value(p, h_idx);
        crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
-       reg = header >> 2;
+       reg = CP_PACKET0_GET_REG(header);
        mutex_lock(&p->rdev->ddev->mode_config.mutex);
        obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
        if (!obj) {
index 4a9028a..9b64d47 100644 (file)
 #define                G_000E50_MCDW_BUSY(x)                   (((x) >> 13) & 1)
 #define                G_000E50_SEM_BUSY(x)                    (((x) >> 14) & 1)
 #define                G_000E50_RLC_BUSY(x)                    (((x) >> 15) & 1)
+#define                G_000E50_BIF_BUSY(x)                    (((x) >> 29) & 1)
 #define        R_000E60_SRBM_SOFT_RESET                        0x0E60
 #define                S_000E60_SOFT_RESET_BIF(x)              (((x) & 1) << 1)
 #define                S_000E60_SOFT_RESET_CG(x)               (((x) & 1) << 2)
index 950b346..5ab35b8 100644 (file)
@@ -590,18 +590,8 @@ struct radeon_asic {
        void (*fini)(struct radeon_device *rdev);
        int (*resume)(struct radeon_device *rdev);
        int (*suspend)(struct radeon_device *rdev);
-       void (*errata)(struct radeon_device *rdev);
-       void (*vram_info)(struct radeon_device *rdev);
        void (*vga_set_state)(struct radeon_device *rdev, bool state);
        int (*gpu_reset)(struct radeon_device *rdev);
-       int (*mc_init)(struct radeon_device *rdev);
-       void (*mc_fini)(struct radeon_device *rdev);
-       int (*wb_init)(struct radeon_device *rdev);
-       void (*wb_fini)(struct radeon_device *rdev);
-       int (*gart_init)(struct radeon_device *rdev);
-       void (*gart_fini)(struct radeon_device *rdev);
-       int (*gart_enable)(struct radeon_device *rdev);
-       void (*gart_disable)(struct radeon_device *rdev);
        void (*gart_tlb_flush)(struct radeon_device *rdev);
        int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr);
        int (*cp_init)(struct radeon_device *rdev, unsigned ring_size);
@@ -611,7 +601,6 @@ struct radeon_asic {
        void (*ring_start)(struct radeon_device *rdev);
        int (*ring_test)(struct radeon_device *rdev);
        void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
-       int (*ib_test)(struct radeon_device *rdev);
        int (*irq_set)(struct radeon_device *rdev);
        int (*irq_process)(struct radeon_device *rdev);
        u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
@@ -789,7 +778,6 @@ struct radeon_device {
        bool                            shutdown;
        bool                            suspend;
        bool                            need_dma32;
-       bool                            new_init_path;
        bool                            accel_working;
        struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
        const struct firmware *me_fw;   /* all family ME firmware */
@@ -949,28 +937,14 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
 #define radeon_resume(rdev) (rdev)->asic->resume((rdev))
 #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
 #define radeon_cs_parse(p) rdev->asic->cs_parse((p))
-#define radeon_errata(rdev) (rdev)->asic->errata((rdev))
-#define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
 #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
 #define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
-#define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
-#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
-#define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev))
-#define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev))
-#define radeon_gpu_gart_init(rdev) (rdev)->asic->gart_init((rdev))
-#define radeon_gpu_gart_fini(rdev) (rdev)->asic->gart_fini((rdev))
-#define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev))
-#define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev))
 #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev))
 #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p))
-#define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize))
-#define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev))
-#define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev))
 #define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev))
 #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev))
 #define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev))
 #define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib))
-#define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev))
 #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev))
 #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
 #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
@@ -996,6 +970,7 @@ extern void radeon_clocks_fini(struct radeon_device *rdev);
 extern void radeon_scratch_init(struct radeon_device *rdev);
 extern void radeon_surface_init(struct radeon_device *rdev);
 extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
+extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
 extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
 
 /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
@@ -1031,11 +1006,27 @@ extern int r100_wb_init(struct radeon_device *rdev);
 extern void r100_hdp_reset(struct radeon_device *rdev);
 extern int r100_rb2d_reset(struct radeon_device *rdev);
 extern int r100_cp_reset(struct radeon_device *rdev);
+extern void r100_vga_render_disable(struct radeon_device *rdev);
+extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
+                                               struct radeon_cs_packet *pkt,
+                                               struct radeon_object *robj);
+extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
+                               struct radeon_cs_packet *pkt,
+                               const unsigned *auth, unsigned n,
+                               radeon_packet0_check_t check);
+extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
+                               struct radeon_cs_packet *pkt,
+                               unsigned idx);
+
+/* rv200,rv250,rv280 */
+extern void r200_set_safe_registers(struct radeon_device *rdev);
 
 /* r300,r350,rv350,rv370,rv380 */
 extern void r300_set_reg_safe(struct radeon_device *rdev);
 extern void r300_mc_program(struct radeon_device *rdev);
 extern void r300_vram_info(struct radeon_device *rdev);
+extern void r300_clock_startup(struct radeon_device *rdev);
+extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
 extern int rv370_pcie_gart_init(struct radeon_device *rdev);
 extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
 extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
@@ -1066,6 +1057,18 @@ extern void rv515_clock_startup(struct radeon_device *rdev);
 extern void rv515_debugfs(struct radeon_device *rdev);
 extern int rv515_suspend(struct radeon_device *rdev);
 
+/* rs400 */
+extern int rs400_gart_init(struct radeon_device *rdev);
+extern int rs400_gart_enable(struct radeon_device *rdev);
+extern void rs400_gart_adjust_size(struct radeon_device *rdev);
+extern void rs400_gart_disable(struct radeon_device *rdev);
+extern void rs400_gart_fini(struct radeon_device *rdev);
+
+/* rs600 */
+extern void rs600_set_safe_registers(struct radeon_device *rdev);
+extern int rs600_irq_set(struct radeon_device *rdev);
+extern void rs600_irq_disable(struct radeon_device *rdev);
+
 /* rs690, rs740 */
 extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
                                        struct drm_display_mode *mode1,
@@ -1083,8 +1086,9 @@ extern int r600_pcie_gart_init(struct radeon_device *rdev);
 extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
 extern int r600_ib_test(struct radeon_device *rdev);
 extern int r600_ring_test(struct radeon_device *rdev);
-extern int r600_wb_init(struct radeon_device *rdev);
 extern void r600_wb_fini(struct radeon_device *rdev);
+extern int r600_wb_enable(struct radeon_device *rdev);
+extern void r600_wb_disable(struct radeon_device *rdev);
 extern void r600_scratch_init(struct radeon_device *rdev);
 extern int r600_blit_init(struct radeon_device *rdev);
 extern void r600_blit_fini(struct radeon_device *rdev);
index c8a4e7b..c3532c7 100644 (file)
@@ -41,28 +41,17 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
 /*
  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
  */
-int r100_init(struct radeon_device *rdev);
-int r200_init(struct radeon_device *rdev);
+extern int r100_init(struct radeon_device *rdev);
+extern void r100_fini(struct radeon_device *rdev);
+extern int r100_suspend(struct radeon_device *rdev);
+extern int r100_resume(struct radeon_device *rdev);
 uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
 void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
-void r100_errata(struct radeon_device *rdev);
-void r100_vram_info(struct radeon_device *rdev);
 void r100_vga_set_state(struct radeon_device *rdev, bool state);
 int r100_gpu_reset(struct radeon_device *rdev);
-int r100_mc_init(struct radeon_device *rdev);
-void r100_mc_fini(struct radeon_device *rdev);
 u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
-int r100_wb_init(struct radeon_device *rdev);
-void r100_wb_fini(struct radeon_device *rdev);
-int r100_pci_gart_init(struct radeon_device *rdev);
-void r100_pci_gart_fini(struct radeon_device *rdev);
-int r100_pci_gart_enable(struct radeon_device *rdev);
-void r100_pci_gart_disable(struct radeon_device *rdev);
 void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
 int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
-int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-void r100_cp_fini(struct radeon_device *rdev);
-void r100_cp_disable(struct radeon_device *rdev);
 void r100_cp_commit(struct radeon_device *rdev);
 void r100_ring_start(struct radeon_device *rdev);
 int r100_irq_set(struct radeon_device *rdev);
@@ -83,33 +72,21 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
 int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r100_bandwidth_update(struct radeon_device *rdev);
 void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
-int r100_ib_test(struct radeon_device *rdev);
 int r100_ring_test(struct radeon_device *rdev);
 
 static struct radeon_asic r100_asic = {
        .init = &r100_init,
-       .errata = &r100_errata,
-       .vram_info = &r100_vram_info,
+       .fini = &r100_fini,
+       .suspend = &r100_suspend,
+       .resume = &r100_resume,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r100_gpu_reset,
-       .mc_init = &r100_mc_init,
-       .mc_fini = &r100_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &r100_pci_gart_init,
-       .gart_fini = &r100_pci_gart_fini,
-       .gart_enable = &r100_pci_gart_enable,
-       .gart_disable = &r100_pci_gart_disable,
        .gart_tlb_flush = &r100_pci_gart_tlb_flush,
        .gart_set_page = &r100_pci_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r100_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
@@ -131,55 +108,38 @@ static struct radeon_asic r100_asic = {
 /*
  * r300,r350,rv350,rv380
  */
-int r300_init(struct radeon_device *rdev);
-void r300_errata(struct radeon_device *rdev);
-void r300_vram_info(struct radeon_device *rdev);
-int r300_gpu_reset(struct radeon_device *rdev);
-int r300_mc_init(struct radeon_device *rdev);
-void r300_mc_fini(struct radeon_device *rdev);
-void r300_ring_start(struct radeon_device *rdev);
-void r300_fence_ring_emit(struct radeon_device *rdev,
-                         struct radeon_fence *fence);
-int r300_cs_parse(struct radeon_cs_parser *p);
-int rv370_pcie_gart_init(struct radeon_device *rdev);
-void rv370_pcie_gart_fini(struct radeon_device *rdev);
-int rv370_pcie_gart_enable(struct radeon_device *rdev);
-void rv370_pcie_gart_disable(struct radeon_device *rdev);
-void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
-int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
-uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
-void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
-void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
-int r300_copy_dma(struct radeon_device *rdev,
-                 uint64_t src_offset,
-                 uint64_t dst_offset,
-                 unsigned num_pages,
-                 struct radeon_fence *fence);
-
+extern int r300_init(struct radeon_device *rdev);
+extern void r300_fini(struct radeon_device *rdev);
+extern int r300_suspend(struct radeon_device *rdev);
+extern int r300_resume(struct radeon_device *rdev);
+extern int r300_gpu_reset(struct radeon_device *rdev);
+extern void r300_ring_start(struct radeon_device *rdev);
+extern void r300_fence_ring_emit(struct radeon_device *rdev,
+                               struct radeon_fence *fence);
+extern int r300_cs_parse(struct radeon_cs_parser *p);
+extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
+extern int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
+extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
+extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
+extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
+extern int r300_copy_dma(struct radeon_device *rdev,
+                       uint64_t src_offset,
+                       uint64_t dst_offset,
+                       unsigned num_pages,
+                       struct radeon_fence *fence);
 static struct radeon_asic r300_asic = {
        .init = &r300_init,
-       .errata = &r300_errata,
-       .vram_info = &r300_vram_info,
+       .fini = &r300_fini,
+       .suspend = &r300_suspend,
+       .resume = &r300_resume,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &r300_mc_init,
-       .mc_fini = &r300_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &r100_pci_gart_init,
-       .gart_fini = &r100_pci_gart_fini,
-       .gart_enable = &r100_pci_gart_enable,
-       .gart_disable = &r100_pci_gart_disable,
        .gart_tlb_flush = &r100_pci_gart_tlb_flush,
        .gart_set_page = &r100_pci_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
@@ -209,26 +169,14 @@ static struct radeon_asic r420_asic = {
        .fini = &r420_fini,
        .suspend = &r420_suspend,
        .resume = &r420_resume,
-       .errata = NULL,
-       .vram_info = NULL,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = NULL,
-       .wb_fini = NULL,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = NULL,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
@@ -250,42 +198,27 @@ static struct radeon_asic r420_asic = {
 /*
  * rs400,rs480
  */
-void rs400_errata(struct radeon_device *rdev);
-void rs400_vram_info(struct radeon_device *rdev);
-int rs400_mc_init(struct radeon_device *rdev);
-void rs400_mc_fini(struct radeon_device *rdev);
-int rs400_gart_init(struct radeon_device *rdev);
-void rs400_gart_fini(struct radeon_device *rdev);
-int rs400_gart_enable(struct radeon_device *rdev);
-void rs400_gart_disable(struct radeon_device *rdev);
+extern int rs400_init(struct radeon_device *rdev);
+extern void rs400_fini(struct radeon_device *rdev);
+extern int rs400_suspend(struct radeon_device *rdev);
+extern int rs400_resume(struct radeon_device *rdev);
 void rs400_gart_tlb_flush(struct radeon_device *rdev);
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
 uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 static struct radeon_asic rs400_asic = {
-       .init = &r300_init,
-       .errata = &rs400_errata,
-       .vram_info = &rs400_vram_info,
+       .init = &rs400_init,
+       .fini = &rs400_fini,
+       .suspend = &rs400_suspend,
+       .resume = &rs400_resume,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &rs400_mc_init,
-       .mc_fini = &rs400_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &rs400_gart_init,
-       .gart_fini = &rs400_gart_fini,
-       .gart_enable = &rs400_gart_enable,
-       .gart_disable = &rs400_gart_disable,
        .gart_tlb_flush = &rs400_gart_tlb_flush,
        .gart_set_page = &rs400_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
@@ -307,18 +240,13 @@ static struct radeon_asic rs400_asic = {
 /*
  * rs600.
  */
-int rs600_init(struct radeon_device *rdev);
-void rs600_errata(struct radeon_device *rdev);
-void rs600_vram_info(struct radeon_device *rdev);
-int rs600_mc_init(struct radeon_device *rdev);
-void rs600_mc_fini(struct radeon_device *rdev);
+extern int rs600_init(struct radeon_device *rdev);
+extern void rs600_fini(struct radeon_device *rdev);
+extern int rs600_suspend(struct radeon_device *rdev);
+extern int rs600_resume(struct radeon_device *rdev);
 int rs600_irq_set(struct radeon_device *rdev);
 int rs600_irq_process(struct radeon_device *rdev);
 u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
-int rs600_gart_init(struct radeon_device *rdev);
-void rs600_gart_fini(struct radeon_device *rdev);
-int rs600_gart_enable(struct radeon_device *rdev);
-void rs600_gart_disable(struct radeon_device *rdev);
 void rs600_gart_tlb_flush(struct radeon_device *rdev);
 int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
 uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
@@ -326,28 +254,17 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs600_bandwidth_update(struct radeon_device *rdev);
 static struct radeon_asic rs600_asic = {
        .init = &rs600_init,
-       .errata = &rs600_errata,
-       .vram_info = &rs600_vram_info,
+       .fini = &rs600_fini,
+       .suspend = &rs600_suspend,
+       .resume = &rs600_resume,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &rs600_mc_init,
-       .mc_fini = &rs600_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &rs600_gart_init,
-       .gart_fini = &rs600_gart_fini,
-       .gart_enable = &rs600_gart_enable,
-       .gart_disable = &rs600_gart_disable,
        .gart_tlb_flush = &rs600_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
@@ -367,37 +284,26 @@ static struct radeon_asic rs600_asic = {
 /*
  * rs690,rs740
  */
-void rs690_errata(struct radeon_device *rdev);
-void rs690_vram_info(struct radeon_device *rdev);
-int rs690_mc_init(struct radeon_device *rdev);
-void rs690_mc_fini(struct radeon_device *rdev);
+int rs690_init(struct radeon_device *rdev);
+void rs690_fini(struct radeon_device *rdev);
+int rs690_resume(struct radeon_device *rdev);
+int rs690_suspend(struct radeon_device *rdev);
 uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs690_bandwidth_update(struct radeon_device *rdev);
 static struct radeon_asic rs690_asic = {
-       .init = &rs600_init,
-       .errata = &rs690_errata,
-       .vram_info = &rs690_vram_info,
+       .init = &rs690_init,
+       .fini = &rs690_fini,
+       .suspend = &rs690_suspend,
+       .resume = &rs690_resume,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &rs690_mc_init,
-       .mc_fini = &rs690_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &rs400_gart_init,
-       .gart_fini = &rs400_gart_fini,
-       .gart_enable = &rs400_gart_enable,
-       .gart_disable = &rs400_gart_disable,
        .gart_tlb_flush = &rs400_gart_tlb_flush,
        .gart_set_page = &rs400_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
@@ -435,28 +341,14 @@ static struct radeon_asic rv515_asic = {
        .fini = &rv515_fini,
        .suspend = &rv515_suspend,
        .resume = &rv515_resume,
-       .errata = NULL,
-       .vram_info = NULL,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &rv515_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = NULL,
-       .wb_fini = NULL,
-       .gart_init = &rv370_pcie_gart_init,
-       .gart_fini = &rv370_pcie_gart_fini,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
        .cp_commit = &r100_cp_commit,
        .ring_start = &rv515_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = NULL,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
@@ -485,28 +377,14 @@ static struct radeon_asic r520_asic = {
        .fini = &rv515_fini,
        .suspend = &rv515_suspend,
        .resume = &r520_resume,
-       .errata = NULL,
-       .vram_info = NULL,
        .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &rv515_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = NULL,
-       .wb_fini = NULL,
-       .gart_init = NULL,
-       .gart_fini = NULL,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
        .cp_commit = &r100_cp_commit,
        .ring_start = &rv515_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = NULL,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
@@ -554,37 +432,23 @@ int r600_set_surface_reg(struct radeon_device *rdev, int reg,
                         uint32_t offset, uint32_t obj_size);
 int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
-int r600_ib_test(struct radeon_device *rdev);
 int r600_ring_test(struct radeon_device *rdev);
 int r600_copy_blit(struct radeon_device *rdev,
                   uint64_t src_offset, uint64_t dst_offset,
                   unsigned num_pages, struct radeon_fence *fence);
 
 static struct radeon_asic r600_asic = {
-       .errata = NULL,
        .init = &r600_init,
        .fini = &r600_fini,
        .suspend = &r600_suspend,
        .resume = &r600_resume,
        .cp_commit = &r600_cp_commit,
-       .vram_info = NULL,
        .vga_set_state = &r600_vga_set_state,
        .gpu_reset = &r600_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = &r600_wb_init,
-       .wb_fini = &r600_wb_fini,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
-       .ring_start = NULL,
        .ring_test = &r600_ring_test,
        .ring_ib_execute = &r600_ring_ib_execute,
-       .ib_test = &r600_ib_test,
        .irq_set = &r600_irq_set,
        .irq_process = &r600_irq_process,
        .fence_ring_emit = &r600_fence_ring_emit,
@@ -611,30 +475,17 @@ int rv770_resume(struct radeon_device *rdev);
 int rv770_gpu_reset(struct radeon_device *rdev);
 
 static struct radeon_asic rv770_asic = {
-       .errata = NULL,
        .init = &rv770_init,
        .fini = &rv770_fini,
        .suspend = &rv770_suspend,
        .resume = &rv770_resume,
        .cp_commit = &r600_cp_commit,
-       .vram_info = NULL,
        .gpu_reset = &rv770_gpu_reset,
        .vga_set_state = &r600_vga_set_state,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = &r600_wb_init,
-       .wb_fini = &r600_wb_fini,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
-       .ring_start = NULL,
        .ring_test = &r600_ring_test,
        .ring_ib_execute = &r600_ring_ib_execute,
-       .ib_test = &r600_ib_test,
        .irq_set = &r600_irq_set,
        .irq_process = &r600_irq_process,
        .fence_ring_emit = &r600_fence_ring_emit,
index 96e37a6..34a9b91 100644 (file)
 /*
  * BIOS.
  */
+
+/* If you boot an IGP board with a discrete card as the primary,
+ * the IGP rom is not accessible via the rom bar as the IGP rom is
+ * part of the system bios.  On boot, the system bios puts a
+ * copy of the igp rom at the start of vram if a discrete card is
+ * present.
+ */
+static bool igp_read_bios_from_vram(struct radeon_device *rdev)
+{
+       uint8_t __iomem *bios;
+       resource_size_t vram_base;
+       resource_size_t size = 256 * 1024; /* ??? */
+
+       rdev->bios = NULL;
+       vram_base = drm_get_resource_start(rdev->ddev, 0);
+       bios = ioremap(vram_base, size);
+       if (!bios) {
+               DRM_ERROR("Unable to mmap vram\n");
+               return false;
+       }
+
+       if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+               iounmap(bios);
+               DRM_ERROR("bad rom signature\n");
+               return false;
+       }
+       rdev->bios = kmalloc(size, GFP_KERNEL);
+       if (rdev->bios == NULL) {
+               iounmap(bios);
+               DRM_ERROR("kmalloc failed\n");
+               return false;
+       }
+       memcpy(rdev->bios, bios, size);
+       iounmap(bios);
+       return true;
+}
+
 static bool radeon_read_bios(struct radeon_device *rdev)
 {
        uint8_t __iomem *bios;
        size_t size;
 
        rdev->bios = NULL;
+       /* XXX: some cards may return 0 for rom size? ddx has a workaround */
        bios = pci_map_rom(rdev->pdev, &size);
        if (!bios) {
                return false;
@@ -341,7 +379,9 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev)
 
 static bool radeon_read_disabled_bios(struct radeon_device *rdev)
 {
-       if (rdev->family >= CHIP_RV770)
+       if (rdev->flags & RADEON_IS_IGP)
+               return igp_read_bios_from_vram(rdev);
+       else if (rdev->family >= CHIP_RV770)
                return r700_read_disabled_bios(rdev);
        else if (rdev->family >= CHIP_R600)
                return r600_read_disabled_bios(rdev);
@@ -356,7 +396,12 @@ bool radeon_get_bios(struct radeon_device *rdev)
        bool r;
        uint16_t tmp;
 
-       r = radeon_read_bios(rdev);
+       if (rdev->flags & RADEON_IS_IGP) {
+               r = igp_read_bios_from_vram(rdev);
+               if (r == false)
+                       r = radeon_read_bios(rdev);
+       } else
+               r = radeon_read_bios(rdev);
        if (r == false) {
                r = radeon_read_disabled_bios(rdev);
        }
index 152eef1..f5c32a7 100644 (file)
@@ -411,7 +411,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        R300_PIXCLK_TRANS_ALWAYS_ONb |
                                        R300_PIXCLK_TVO_ALWAYS_ONb |
                                        R300_P2G2CLK_ALWAYS_ONb |
-                                       R300_P2G2CLK_ALWAYS_ONb);
+                                       R300_P2G2CLK_DAC_ALWAYS_ONb);
                                WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
                        } else if (rdev->family >= CHIP_RV350) {
                                tmp = RREG32_PLL(R300_SCLK_CNTL2);
@@ -464,7 +464,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        R300_PIXCLK_TRANS_ALWAYS_ONb |
                                        R300_PIXCLK_TVO_ALWAYS_ONb |
                                        R300_P2G2CLK_ALWAYS_ONb |
-                                       R300_P2G2CLK_ALWAYS_ONb);
+                                       R300_P2G2CLK_DAC_ALWAYS_ONb);
                                WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
 
                                tmp = RREG32_PLL(RADEON_MCLK_MISC);
@@ -654,7 +654,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                 R300_PIXCLK_TRANS_ALWAYS_ONb |
                                 R300_PIXCLK_TVO_ALWAYS_ONb |
                                 R300_P2G2CLK_ALWAYS_ONb |
-                                R300_P2G2CLK_ALWAYS_ONb |
+                                R300_P2G2CLK_DAC_ALWAYS_ONb |
                                 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
                } else if (rdev->family >= CHIP_RV350) {
@@ -705,7 +705,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                 R300_PIXCLK_TRANS_ALWAYS_ONb |
                                 R300_PIXCLK_TVO_ALWAYS_ONb |
                                 R300_P2G2CLK_ALWAYS_ONb |
-                                R300_P2G2CLK_ALWAYS_ONb |
+                                R300_P2G2CLK_DAC_ALWAYS_ONb |
                                 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
                } else {
index ec835d5..3d66703 100644 (file)
@@ -322,10 +322,6 @@ int radeon_asic_init(struct radeon_device *rdev)
        case CHIP_RV380:
                rdev->asic = &r300_asic;
                if (rdev->flags & RADEON_IS_PCIE) {
-                       rdev->asic->gart_init = &rv370_pcie_gart_init;
-                       rdev->asic->gart_fini = &rv370_pcie_gart_fini;
-                       rdev->asic->gart_enable = &rv370_pcie_gart_enable;
-                       rdev->asic->gart_disable = &rv370_pcie_gart_disable;
                        rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
                        rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
                }
@@ -485,7 +481,6 @@ void radeon_combios_fini(struct radeon_device *rdev)
 static unsigned int radeon_vga_set_decode(void *cookie, bool state)
 {
        struct radeon_device *rdev = cookie;
-
        radeon_vga_set_state(rdev, state);
        if (state)
                return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
@@ -493,6 +488,29 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)
        else
                return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
+
+void radeon_agp_disable(struct radeon_device *rdev)
+{
+       rdev->flags &= ~RADEON_IS_AGP;
+       if (rdev->family >= CHIP_R600) {
+               DRM_INFO("Forcing AGP to PCIE mode\n");
+               rdev->flags |= RADEON_IS_PCIE;
+       } else if (rdev->family >= CHIP_RV515 ||
+                       rdev->family == CHIP_RV380 ||
+                       rdev->family == CHIP_RV410 ||
+                       rdev->family == CHIP_R423) {
+               DRM_INFO("Forcing AGP to PCIE mode\n");
+               rdev->flags |= RADEON_IS_PCIE;
+               rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+               rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+       } else {
+               DRM_INFO("Forcing AGP to PCI mode\n");
+               rdev->flags |= RADEON_IS_PCI;
+               rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+               rdev->asic->gart_set_page = &r100_pci_gart_set_page;
+       }
+}
+
 /*
  * Radeon device.
  */
@@ -531,32 +549,7 @@ int radeon_device_init(struct radeon_device *rdev,
        }
 
        if (radeon_agpmode == -1) {
-               rdev->flags &= ~RADEON_IS_AGP;
-               if (rdev->family >= CHIP_R600) {
-                       DRM_INFO("Forcing AGP to PCIE mode\n");
-                       rdev->flags |= RADEON_IS_PCIE;
-               } else if (rdev->family >= CHIP_RV515 ||
-                          rdev->family == CHIP_RV380 ||
-                          rdev->family == CHIP_RV410 ||
-                          rdev->family == CHIP_R423) {
-                       DRM_INFO("Forcing AGP to PCIE mode\n");
-                       rdev->flags |= RADEON_IS_PCIE;
-                       rdev->asic->gart_init = &rv370_pcie_gart_init;
-                       rdev->asic->gart_fini = &rv370_pcie_gart_fini;
-                       rdev->asic->gart_enable = &rv370_pcie_gart_enable;
-                       rdev->asic->gart_disable = &rv370_pcie_gart_disable;
-                       rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
-                       rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
-               } else {
-                       DRM_INFO("Forcing AGP to PCI mode\n");
-                       rdev->flags |= RADEON_IS_PCI;
-                       rdev->asic->gart_init = &r100_pci_gart_init;
-                       rdev->asic->gart_fini = &r100_pci_gart_fini;
-                       rdev->asic->gart_enable = &r100_pci_gart_enable;
-                       rdev->asic->gart_disable = &r100_pci_gart_disable;
-                       rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
-                       rdev->asic->gart_set_page = &r100_pci_gart_set_page;
-               }
+               radeon_agp_disable(rdev);
        }
 
        /* set DMA mask + need_dma32 flags.
@@ -588,111 +581,27 @@ int radeon_device_init(struct radeon_device *rdev,
        DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
        DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
 
-       rdev->new_init_path = false;
-       r = radeon_init(rdev);
-       if (r) {
-               return r;
-       }
-
        /* if we have > 1 VGA cards, then disable the radeon VGA resources */
        r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
        if (r) {
                return -EINVAL;
        }
 
-       if (!rdev->new_init_path) {
-               /* Setup errata flags */
-               radeon_errata(rdev);
-               /* Initialize scratch registers */
-               radeon_scratch_init(rdev);
-               /* Initialize surface registers */
-               radeon_surface_init(rdev);
-
-               /* BIOS*/
-               if (!radeon_get_bios(rdev)) {
-                       if (ASIC_IS_AVIVO(rdev))
-                               return -EINVAL;
-               }
-               if (rdev->is_atom_bios) {
-                       r = radeon_atombios_init(rdev);
-                       if (r) {
-                               return r;
-                       }
-               } else {
-                       r = radeon_combios_init(rdev);
-                       if (r) {
-                               return r;
-                       }
-               }
-               /* Reset gpu before posting otherwise ATOM will enter infinite loop */
-               if (radeon_gpu_reset(rdev)) {
-                       /* FIXME: what do we want to do here ? */
-               }
-               /* check if cards are posted or not */
-               if (!radeon_card_posted(rdev) && rdev->bios) {
-                       DRM_INFO("GPU not posted. posting now...\n");
-                       if (rdev->is_atom_bios) {
-                               atom_asic_init(rdev->mode_info.atom_context);
-                       } else {
-                               radeon_combios_asic_init(rdev->ddev);
-                       }
-               }
-               /* Get clock & vram information */
-               radeon_get_clock_info(rdev->ddev);
-               radeon_vram_info(rdev);
-               /* Initialize clocks */
-               r = radeon_clocks_init(rdev);
-               if (r) {
-                       return r;
-               }
+       r = radeon_init(rdev);
+       if (r)
+               return r;
 
-               /* Initialize memory controller (also test AGP) */
-               r = radeon_mc_init(rdev);
-               if (r) {
-                       return r;
-               }
-               /* Fence driver */
-               r = radeon_fence_driver_init(rdev);
-               if (r) {
-                       return r;
-               }
-               r = radeon_irq_kms_init(rdev);
-               if (r) {
-                       return r;
-               }
-               /* Memory manager */
-               r = radeon_object_init(rdev);
-               if (r) {
-                       return r;
-               }
-               r = radeon_gpu_gart_init(rdev);
+       if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
+               /* Acceleration not working on AGP card try again
+                * with fallback to PCI or PCIE GART
+                */
+               radeon_gpu_reset(rdev);
+               radeon_fini(rdev);
+               radeon_agp_disable(rdev);
+               r = radeon_init(rdev);
                if (r)
                        return r;
-               /* Initialize GART (initialize after TTM so we can allocate
-                * memory through TTM but finalize after TTM) */
-               r = radeon_gart_enable(rdev);
-               if (r)
-                       return 0;
-                       r = radeon_gem_init(rdev);
-               if (r)
-                       return 0;
-
-               /* 1M ring buffer */
-               r = radeon_cp_init(rdev, 1024 * 1024);
-               if (r)
-                       return 0;
-               r = radeon_wb_init(rdev);
-               if (r)
-                       DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
-               r = radeon_ib_pool_init(rdev);
-               if (r)
-                       return 0;
-               r = radeon_ib_test(rdev);
-               if (r)
-                       return 0;
-               rdev->accel_working = true;
        }
-       DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
        if (radeon_testing) {
                radeon_test_moves(rdev);
        }
@@ -706,32 +615,8 @@ void radeon_device_fini(struct radeon_device *rdev)
 {
        DRM_INFO("radeon: finishing device.\n");
        rdev->shutdown = true;
-       /* Order matter so becarefull if you rearrange anythings */
-       if (!rdev->new_init_path) {
-               radeon_ib_pool_fini(rdev);
-               radeon_cp_fini(rdev);
-               radeon_wb_fini(rdev);
-               radeon_gpu_gart_fini(rdev);
-               radeon_gem_fini(rdev);
-               radeon_mc_fini(rdev);
-#if __OS_HAS_AGP
-               radeon_agp_fini(rdev);
-#endif
-               radeon_irq_kms_fini(rdev);
-               vga_client_register(rdev->pdev, NULL, NULL, NULL);
-               radeon_fence_driver_fini(rdev);
-               radeon_clocks_fini(rdev);
-               radeon_object_fini(rdev);
-               if (rdev->is_atom_bios) {
-                       radeon_atombios_fini(rdev);
-               } else {
-                       radeon_combios_fini(rdev);
-               }
-               kfree(rdev->bios);
-               rdev->bios = NULL;
-       } else {
-               radeon_fini(rdev);
-       }
+       radeon_fini(rdev);
+       vga_client_register(rdev->pdev, NULL, NULL, NULL);
        iounmap(rdev->rmmio);
        rdev->rmmio = NULL;
 }
@@ -771,14 +656,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
 
        radeon_save_bios_scratch_regs(rdev);
 
-       if (!rdev->new_init_path) {
-               radeon_cp_disable(rdev);
-               radeon_gart_disable(rdev);
-               rdev->irq.sw_int = false;
-               radeon_irq_set(rdev);
-       } else {
-               radeon_suspend(rdev);
-       }
+       radeon_suspend(rdev);
        /* evict remaining vram memory */
        radeon_object_evict_vram(rdev);
 
@@ -797,7 +675,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
 int radeon_resume_kms(struct drm_device *dev)
 {
        struct radeon_device *rdev = dev->dev_private;
-       int r;
 
        acquire_console_sem();
        pci_set_power_state(dev->pdev, PCI_D0);
@@ -807,43 +684,7 @@ int radeon_resume_kms(struct drm_device *dev)
                return -1;
        }
        pci_set_master(dev->pdev);
-       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
-       if (!rdev->new_init_path) {
-               if (radeon_gpu_reset(rdev)) {
-                       /* FIXME: what do we want to do here ? */
-               }
-               /* post card */
-               if (rdev->is_atom_bios) {
-                       atom_asic_init(rdev->mode_info.atom_context);
-               } else {
-                       radeon_combios_asic_init(rdev->ddev);
-               }
-               /* Initialize clocks */
-               r = radeon_clocks_init(rdev);
-               if (r) {
-                       release_console_sem();
-                       return r;
-               }
-               /* Enable IRQ */
-               rdev->irq.sw_int = true;
-               radeon_irq_set(rdev);
-               /* Initialize GPU Memory Controller */
-               r = radeon_mc_init(rdev);
-               if (r) {
-                       goto out;
-               }
-               r = radeon_gart_enable(rdev);
-               if (r) {
-                       goto out;
-               }
-               r = radeon_cp_init(rdev, rdev->cp.ring_size);
-               if (r) {
-                       goto out;
-               }
-       } else {
-               radeon_resume(rdev);
-       }
-out:
+       radeon_resume(rdev);
        radeon_restore_bios_scratch_regs(rdev);
        fb_set_suspend(rdev->fbdev_info, 0);
        release_console_sem();
index 5d8141b..3655d91 100644 (file)
@@ -106,24 +106,33 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
                legacy_crtc_load_lut(crtc);
 }
 
-/** Sets the color ramps on behalf of RandR */
+/** Sets the color ramps on behalf of fbcon */
 void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
                              u16 blue, int regno)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
-       if (regno == 0)
-               DRM_DEBUG("gamma set %d\n", radeon_crtc->crtc_id);
        radeon_crtc->lut_r[regno] = red >> 6;
        radeon_crtc->lut_g[regno] = green >> 6;
        radeon_crtc->lut_b[regno] = blue >> 6;
 }
 
+/** Gets the color ramps on behalf of fbcon */
+void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+                             u16 *blue, int regno)
+{
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+       *red = radeon_crtc->lut_r[regno] << 6;
+       *green = radeon_crtc->lut_g[regno] << 6;
+       *blue = radeon_crtc->lut_b[regno] << 6;
+}
+
 static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
                                  u16 *blue, uint32_t size)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-       int i, j;
+       int i;
 
        if (size != 256) {
                return;
@@ -132,23 +141,11 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
                return;
        }
 
-       if (crtc->fb->depth == 16) {
-               for (i = 0; i < 64; i++) {
-                       if (i <= 31) {
-                               for (j = 0; j < 8; j++) {
-                                       radeon_crtc->lut_r[i * 8 + j] = red[i] >> 6;
-                                       radeon_crtc->lut_b[i * 8 + j] = blue[i] >> 6;
-                               }
-                       }
-                       for (j = 0; j < 4; j++)
-                               radeon_crtc->lut_g[i * 4 + j] = green[i] >> 6;
-               }
-       } else {
-               for (i = 0; i < 256; i++) {
-                       radeon_crtc->lut_r[i] = red[i] >> 6;
-                       radeon_crtc->lut_g[i] = green[i] >> 6;
-                       radeon_crtc->lut_b[i] = blue[i] >> 6;
-               }
+       /* userspace palettes are always correct as is */
+       for (i = 0; i < 256; i++) {
+               radeon_crtc->lut_r[i] = red[i] >> 6;
+               radeon_crtc->lut_g[i] = green[i] >> 6;
+               radeon_crtc->lut_b[i] = blue[i] >> 6;
        }
 
        radeon_crtc_load_lut(crtc);
@@ -724,7 +721,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
        if (ret) {
                return ret;
        }
-       /* allocate crtcs - TODO single crtc */
+
+       if (rdev->flags & RADEON_SINGLE_CRTC)
+               num_crtc = 1;
+
+       /* allocate crtcs */
        for (i = 0; i < num_crtc; i++) {
                radeon_crtc_init(rdev->ddev, i);
        }
index 6216467..a65ab1a 100644 (file)
@@ -1345,6 +1345,7 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
 void
 radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
 {
+       struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *encoder;
        struct radeon_encoder *radeon_encoder;
 
@@ -1364,7 +1365,10 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
                return;
 
        encoder = &radeon_encoder->base;
-       encoder->possible_crtcs = 0x3;
+       if (rdev->flags & RADEON_SINGLE_CRTC)
+               encoder->possible_crtcs = 0x1;
+       else
+               encoder->possible_crtcs = 0x3;
        encoder->possible_clones = 0;
 
        radeon_encoder->enc_priv = NULL;
index 1ba704e..b38c4c8 100644 (file)
@@ -55,6 +55,7 @@ static struct fb_ops radeonfb_ops = {
        .fb_imageblit = cfb_imageblit,
        .fb_pan_display = drm_fb_helper_pan_display,
        .fb_blank = drm_fb_helper_blank,
+       .fb_setcmap = drm_fb_helper_setcmap,
 };
 
 /**
@@ -123,6 +124,7 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo
 
 static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
        .gamma_set = radeon_crtc_fb_gamma_set,
+       .gamma_get = radeon_crtc_fb_gamma_get,
 };
 
 int radeonfb_create(struct drm_device *dev,
@@ -146,9 +148,15 @@ int radeonfb_create(struct drm_device *dev,
        unsigned long tmp;
        bool fb_tiled = false; /* useful for testing */
        u32 tiling_flags = 0;
+       int crtc_count;
 
        mode_cmd.width = surface_width;
        mode_cmd.height = surface_height;
+
+       /* avivo can't scanout real 24bpp */
+       if ((surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
+               surface_bpp = 32;
+
        mode_cmd.bpp = surface_bpp;
        /* need to align pitch with crtc limits */
        mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8);
@@ -217,7 +225,11 @@ int radeonfb_create(struct drm_device *dev,
        rfbdev = info->par;
        rfbdev->helper.funcs = &radeon_fb_helper_funcs;
        rfbdev->helper.dev = dev;
-       ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, 2,
+       if (rdev->flags & RADEON_SINGLE_CRTC)
+               crtc_count = 1;
+       else
+               crtc_count = 2;
+       ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, crtc_count,
                                            RADEONFB_CONN_LIMIT);
        if (ret)
                goto out_unref;
@@ -234,7 +246,7 @@ int radeonfb_create(struct drm_device *dev,
 
        strcpy(info->fix.id, "radeondrmfb");
 
-       drm_fb_helper_fill_fix(info, fb->pitch);
+       drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
 
        info->flags = FBINFO_DEFAULT;
        info->fbops = &radeonfb_ops;
@@ -309,7 +321,7 @@ int radeon_parse_options(char *options)
 
 int radeonfb_probe(struct drm_device *dev)
 {
-       return drm_fb_helper_single_fb_probe(dev, &radeonfb_create);
+       return drm_fb_helper_single_fb_probe(dev, 32, &radeonfb_create);
 }
 
 int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
index 1841145..8e0a875 100644 (file)
@@ -83,8 +83,12 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
 int radeon_irq_kms_init(struct radeon_device *rdev)
 {
        int r = 0;
+       int num_crtc = 2;
 
-       r = drm_vblank_init(rdev->ddev, 2);
+       if (rdev->flags & RADEON_SINGLE_CRTC)
+               num_crtc = 1;
+
+       r = drm_vblank_init(rdev->ddev, num_crtc);
        if (r) {
                return r;
        }
index 2b997a1..36410f8 100644 (file)
@@ -1053,6 +1053,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
        .mode_set_base = radeon_crtc_set_base,
        .prepare = radeon_crtc_prepare,
        .commit = radeon_crtc_commit,
+       .load_lut = radeon_crtc_load_lut,
 };
 
 
index b1547f7..6ceb958 100644 (file)
@@ -881,7 +881,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
                                        R420_TV_DAC_DACADJ_MASK |
                                        R420_TV_DAC_RDACPD |
                                        R420_TV_DAC_GDACPD |
-                                       R420_TV_DAC_GDACPD |
+                                       R420_TV_DAC_BDACPD |
                                        R420_TV_DAC_TVENABLE);
                } else {
                        tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
@@ -889,7 +889,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
                                        RADEON_TV_DAC_DACADJ_MASK |
                                        RADEON_TV_DAC_RDACPD |
                                        RADEON_TV_DAC_GDACPD |
-                                       RADEON_TV_DAC_GDACPD);
+                                       RADEON_TV_DAC_BDACPD);
                }
 
                /*  FIXME TV */
@@ -1318,7 +1318,10 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
                return;
 
        encoder = &radeon_encoder->base;
-       encoder->possible_crtcs = 0x3;
+       if (rdev->flags & RADEON_SINGLE_CRTC)
+               encoder->possible_crtcs = 0x1;
+       else
+               encoder->possible_crtcs = 0x3;
        encoder->possible_clones = 0;
 
        radeon_encoder->enc_priv = NULL;
index 570a587..e612268 100644 (file)
@@ -407,6 +407,8 @@ extern void
 radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on);
 extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
                                     u16 blue, int regno);
+extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+                                    u16 *blue, int regno);
 struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev,
                                                  struct drm_mode_fb_cmd *mode_cmd,
                                                  struct drm_gem_object *obj);
index 73af463..1f056da 100644 (file)
@@ -400,11 +400,9 @@ void radeon_object_list_add_object(struct radeon_object_list *lobj,
 int radeon_object_list_reserve(struct list_head *head)
 {
        struct radeon_object_list *lobj;
-       struct list_head *i;
        int r;
 
-       list_for_each(i, head) {
-               lobj = list_entry(i, struct radeon_object_list, list);
+       list_for_each_entry(lobj, head, list){
                if (!lobj->robj->pin_count) {
                        r = radeon_object_reserve(lobj->robj, true);
                        if (unlikely(r != 0)) {
@@ -420,13 +418,10 @@ int radeon_object_list_reserve(struct list_head *head)
 void radeon_object_list_unreserve(struct list_head *head)
 {
        struct radeon_object_list *lobj;
-       struct list_head *i;
 
-       list_for_each(i, head) {
-               lobj = list_entry(i, struct radeon_object_list, list);
+       list_for_each_entry(lobj, head, list) {
                if (!lobj->robj->pin_count) {
                        radeon_object_unreserve(lobj->robj);
-               } else {
                }
        }
 }
@@ -436,7 +431,6 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
        struct radeon_object_list *lobj;
        struct radeon_object *robj;
        struct radeon_fence *old_fence = NULL;
-       struct list_head *i;
        int r;
 
        r = radeon_object_list_reserve(head);
@@ -444,8 +438,7 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
                radeon_object_list_unreserve(head);
                return r;
        }
-       list_for_each(i, head) {
-               lobj = list_entry(i, struct radeon_object_list, list);
+       list_for_each_entry(lobj, head, list) {
                robj = lobj->robj;
                if (!robj->pin_count) {
                        if (lobj->wdomain) {
@@ -482,10 +475,8 @@ void radeon_object_list_unvalidate(struct list_head *head)
 {
        struct radeon_object_list *lobj;
        struct radeon_fence *old_fence = NULL;
-       struct list_head *i;
 
-       list_for_each(i, head) {
-               lobj = list_entry(i, struct radeon_object_list, list);
+       list_for_each_entry(lobj, head, list) {
                old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj;
                lobj->robj->tobj.sync_obj = NULL;
                if (old_fence) {
diff --git a/drivers/gpu/drm/radeon/rs100d.h b/drivers/gpu/drm/radeon/rs100d.h
new file mode 100644 (file)
index 0000000..48a913a
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef __RS100D_H__
+#define __RS100D_H__
+
+/* Registers */
+#define R_00015C_NB_TOM                              0x00015C
+#define   S_00015C_MC_FB_START(x)                      (((x) & 0xFFFF) << 0)
+#define   G_00015C_MC_FB_START(x)                      (((x) >> 0) & 0xFFFF)
+#define   C_00015C_MC_FB_START                         0xFFFF0000
+#define   S_00015C_MC_FB_TOP(x)                        (((x) & 0xFFFF) << 16)
+#define   G_00015C_MC_FB_TOP(x)                        (((x) >> 16) & 0xFFFF)
+#define   C_00015C_MC_FB_TOP         &nbs