mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 01:04:19 +08:00
Merge branches 'sh/g3-prep' and 'sh/stable-updates'
This commit is contained in:
commit
17eb9d6282
@ -21,25 +21,27 @@ Contact: Alan Stern <stern@rowland.harvard.edu>
|
||||
Description:
|
||||
Each USB device directory will contain a file named
|
||||
power/level. This file holds a power-level setting for
|
||||
the device, one of "on", "auto", or "suspend".
|
||||
the device, either "on" or "auto".
|
||||
|
||||
"on" means that the device is not allowed to autosuspend,
|
||||
although normal suspends for system sleep will still
|
||||
be honored. "auto" means the device will autosuspend
|
||||
and autoresume in the usual manner, according to the
|
||||
capabilities of its driver. "suspend" means the device
|
||||
is forced into a suspended state and it will not autoresume
|
||||
in response to I/O requests. However remote-wakeup requests
|
||||
from the device may still be enabled (the remote-wakeup
|
||||
setting is controlled separately by the power/wakeup
|
||||
attribute).
|
||||
capabilities of its driver.
|
||||
|
||||
During normal use, devices should be left in the "auto"
|
||||
level. The other levels are meant for administrative uses.
|
||||
level. The "on" level is meant for administrative uses.
|
||||
If you want to suspend a device immediately but leave it
|
||||
free to wake up in response to I/O requests, you should
|
||||
write "0" to power/autosuspend.
|
||||
|
||||
Device not capable of proper suspend and resume should be
|
||||
left in the "on" level. Although the USB spec requires
|
||||
devices to support suspend/resume, many of them do not.
|
||||
In fact so many don't that by default, the USB core
|
||||
initializes all non-hub devices in the "on" level. Some
|
||||
drivers may change this setting when they are bound.
|
||||
|
||||
What: /sys/bus/usb/devices/.../power/persist
|
||||
Date: May 2007
|
||||
KernelVersion: 2.6.23
|
||||
|
@ -226,5 +226,5 @@ struct driver_attribute driver_attr_debug;
|
||||
This can then be used to add and remove the attribute from the
|
||||
driver's directory using:
|
||||
|
||||
int driver_create_file(struct device_driver *, struct driver_attribute *);
|
||||
void driver_remove_file(struct device_driver *, struct driver_attribute *);
|
||||
int driver_create_file(struct device_driver *, const struct driver_attribute *);
|
||||
void driver_remove_file(struct device_driver *, const struct driver_attribute *);
|
||||
|
@ -91,8 +91,8 @@ struct device_attribute {
|
||||
const char *buf, size_t count);
|
||||
};
|
||||
|
||||
int device_create_file(struct device *, struct device_attribute *);
|
||||
void device_remove_file(struct device *, struct device_attribute *);
|
||||
int device_create_file(struct device *, const struct device_attribute *);
|
||||
void device_remove_file(struct device *, const struct device_attribute *);
|
||||
|
||||
It also defines this helper for defining device attributes:
|
||||
|
||||
@ -316,8 +316,8 @@ DEVICE_ATTR(_name, _mode, _show, _store);
|
||||
|
||||
Creation/Removal:
|
||||
|
||||
int device_create_file(struct device *device, struct device_attribute * attr);
|
||||
void device_remove_file(struct device * dev, struct device_attribute * attr);
|
||||
int device_create_file(struct device *dev, const struct device_attribute * attr);
|
||||
void device_remove_file(struct device *dev, const struct device_attribute * attr);
|
||||
|
||||
|
||||
- bus drivers (include/linux/device.h)
|
||||
@ -358,7 +358,7 @@ DRIVER_ATTR(_name, _mode, _show, _store)
|
||||
|
||||
Creation/Removal:
|
||||
|
||||
int driver_create_file(struct device_driver *, struct driver_attribute *);
|
||||
void driver_remove_file(struct device_driver *, struct driver_attribute *);
|
||||
int driver_create_file(struct device_driver *, const struct driver_attribute *);
|
||||
void driver_remove_file(struct device_driver *, const struct driver_attribute *);
|
||||
|
||||
|
||||
|
@ -42,80 +42,81 @@ struct dev_pm_ops {
|
||||
...
|
||||
};
|
||||
|
||||
The ->runtime_suspend() callback is executed by the PM core for the bus type of
|
||||
the device being suspended. The bus type's callback is then _entirely_
|
||||
_responsible_ for handling the device as appropriate, which may, but need not
|
||||
include executing the device driver's own ->runtime_suspend() callback (from the
|
||||
PM core's point of view it is not necessary to implement a ->runtime_suspend()
|
||||
callback in a device driver as long as the bus type's ->runtime_suspend() knows
|
||||
what to do to handle the device).
|
||||
The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are
|
||||
executed by the PM core for either the bus type, or device type (if the bus
|
||||
type's callback is not defined), or device class (if the bus type's and device
|
||||
type's callbacks are not defined) of given device. The bus type, device type
|
||||
and device class callbacks are referred to as subsystem-level callbacks in what
|
||||
follows.
|
||||
|
||||
* Once the bus type's ->runtime_suspend() callback has completed successfully
|
||||
The subsystem-level suspend callback is _entirely_ _responsible_ for handling
|
||||
the suspend of the device as appropriate, which may, but need not include
|
||||
executing the device driver's own ->runtime_suspend() callback (from the
|
||||
PM core's point of view it is not necessary to implement a ->runtime_suspend()
|
||||
callback in a device driver as long as the subsystem-level suspend callback
|
||||
knows what to do to handle the device).
|
||||
|
||||
* Once the subsystem-level suspend callback has completed successfully
|
||||
for given device, the PM core regards the device as suspended, which need
|
||||
not mean that the device has been put into a low power state. It is
|
||||
supposed to mean, however, that the device will not process data and will
|
||||
not communicate with the CPU(s) and RAM until its bus type's
|
||||
->runtime_resume() callback is executed for it. The run-time PM status of
|
||||
a device after successful execution of its bus type's ->runtime_suspend()
|
||||
callback is 'suspended'.
|
||||
not communicate with the CPU(s) and RAM until the subsystem-level resume
|
||||
callback is executed for it. The run-time PM status of a device after
|
||||
successful execution of the subsystem-level suspend callback is 'suspended'.
|
||||
|
||||
* If the bus type's ->runtime_suspend() callback returns -EBUSY or -EAGAIN,
|
||||
the device's run-time PM status is supposed to be 'active', which means that
|
||||
the device _must_ be fully operational afterwards.
|
||||
* If the subsystem-level suspend callback returns -EBUSY or -EAGAIN,
|
||||
the device's run-time PM status is 'active', which means that the device
|
||||
_must_ be fully operational afterwards.
|
||||
|
||||
* If the bus type's ->runtime_suspend() callback returns an error code
|
||||
different from -EBUSY or -EAGAIN, the PM core regards this as a fatal
|
||||
error and will refuse to run the helper functions described in Section 4
|
||||
for the device, until the status of it is directly set either to 'active'
|
||||
or to 'suspended' (the PM core provides special helper functions for this
|
||||
purpose).
|
||||
* If the subsystem-level suspend callback returns an error code different
|
||||
from -EBUSY or -EAGAIN, the PM core regards this as a fatal error and will
|
||||
refuse to run the helper functions described in Section 4 for the device,
|
||||
until the status of it is directly set either to 'active', or to 'suspended'
|
||||
(the PM core provides special helper functions for this purpose).
|
||||
|
||||
In particular, if the driver requires remote wakeup capability for proper
|
||||
functioning and device_run_wake() returns 'false' for the device, then
|
||||
->runtime_suspend() should return -EBUSY. On the other hand, if
|
||||
device_run_wake() returns 'true' for the device and the device is put
|
||||
into a low power state during the execution of its bus type's
|
||||
->runtime_suspend(), it is expected that remote wake-up (i.e. hardware mechanism
|
||||
allowing the device to request a change of its power state, such as PCI PME)
|
||||
will be enabled for the device. Generally, remote wake-up should be enabled
|
||||
for all input devices put into a low power state at run time.
|
||||
In particular, if the driver requires remote wake-up capability (i.e. hardware
|
||||
mechanism allowing the device to request a change of its power state, such as
|
||||
PCI PME) for proper functioning and device_run_wake() returns 'false' for the
|
||||
device, then ->runtime_suspend() should return -EBUSY. On the other hand, if
|
||||
device_run_wake() returns 'true' for the device and the device is put into a low
|
||||
power state during the execution of the subsystem-level suspend callback, it is
|
||||
expected that remote wake-up will be enabled for the device. Generally, remote
|
||||
wake-up should be enabled for all input devices put into a low power state at
|
||||
run time.
|
||||
|
||||
The ->runtime_resume() callback is executed by the PM core for the bus type of
|
||||
the device being woken up. The bus type's callback is then _entirely_
|
||||
_responsible_ for handling the device as appropriate, which may, but need not
|
||||
include executing the device driver's own ->runtime_resume() callback (from the
|
||||
PM core's point of view it is not necessary to implement a ->runtime_resume()
|
||||
callback in a device driver as long as the bus type's ->runtime_resume() knows
|
||||
what to do to handle the device).
|
||||
The subsystem-level resume callback is _entirely_ _responsible_ for handling the
|
||||
resume of the device as appropriate, which may, but need not include executing
|
||||
the device driver's own ->runtime_resume() callback (from the PM core's point of
|
||||
view it is not necessary to implement a ->runtime_resume() callback in a device
|
||||
driver as long as the subsystem-level resume callback knows what to do to handle
|
||||
the device).
|
||||
|
||||
* Once the bus type's ->runtime_resume() callback has completed successfully,
|
||||
the PM core regards the device as fully operational, which means that the
|
||||
device _must_ be able to complete I/O operations as needed. The run-time
|
||||
PM status of the device is then 'active'.
|
||||
* Once the subsystem-level resume callback has completed successfully, the PM
|
||||
core regards the device as fully operational, which means that the device
|
||||
_must_ be able to complete I/O operations as needed. The run-time PM status
|
||||
of the device is then 'active'.
|
||||
|
||||
* If the bus type's ->runtime_resume() callback returns an error code, the PM
|
||||
core regards this as a fatal error and will refuse to run the helper
|
||||
functions described in Section 4 for the device, until its status is
|
||||
directly set either to 'active' or to 'suspended' (the PM core provides
|
||||
special helper functions for this purpose).
|
||||
* If the subsystem-level resume callback returns an error code, the PM core
|
||||
regards this as a fatal error and will refuse to run the helper functions
|
||||
described in Section 4 for the device, until its status is directly set
|
||||
either to 'active' or to 'suspended' (the PM core provides special helper
|
||||
functions for this purpose).
|
||||
|
||||
The ->runtime_idle() callback is executed by the PM core for the bus type of
|
||||
given device whenever the device appears to be idle, which is indicated to the
|
||||
PM core by two counters, the device's usage counter and the counter of 'active'
|
||||
children of the device.
|
||||
The subsystem-level idle callback is executed by the PM core whenever the device
|
||||
appears to be idle, which is indicated to the PM core by two counters, the
|
||||
device's usage counter and the counter of 'active' children of the device.
|
||||
|
||||
* If any of these counters is decreased using a helper function provided by
|
||||
the PM core and it turns out to be equal to zero, the other counter is
|
||||
checked. If that counter also is equal to zero, the PM core executes the
|
||||
device bus type's ->runtime_idle() callback (with the device as an
|
||||
argument).
|
||||
subsystem-level idle callback with the device as an argument.
|
||||
|
||||
The action performed by a bus type's ->runtime_idle() callback is totally
|
||||
dependent on the bus type in question, but the expected and recommended action
|
||||
is to check if the device can be suspended (i.e. if all of the conditions
|
||||
necessary for suspending the device are satisfied) and to queue up a suspend
|
||||
request for the device in that case. The value returned by this callback is
|
||||
ignored by the PM core.
|
||||
The action performed by a subsystem-level idle callback is totally dependent on
|
||||
the subsystem in question, but the expected and recommended action is to check
|
||||
if the device can be suspended (i.e. if all of the conditions necessary for
|
||||
suspending the device are satisfied) and to queue up a suspend request for the
|
||||
device in that case. The value returned by this callback is ignored by the PM
|
||||
core.
|
||||
|
||||
The helper functions provided by the PM core, described in Section 4, guarantee
|
||||
that the following constraints are met with respect to the bus type's run-time
|
||||
@ -238,41 +239,41 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
|
||||
removing the device from device hierarchy
|
||||
|
||||
int pm_runtime_idle(struct device *dev);
|
||||
- execute ->runtime_idle() for the device's bus type; returns 0 on success
|
||||
or error code on failure, where -EINPROGRESS means that ->runtime_idle()
|
||||
is already being executed
|
||||
- execute the subsystem-level idle callback for the device; returns 0 on
|
||||
success or error code on failure, where -EINPROGRESS means that
|
||||
->runtime_idle() is already being executed
|
||||
|
||||
int pm_runtime_suspend(struct device *dev);
|
||||
- execute ->runtime_suspend() for the device's bus type; returns 0 on
|
||||
- execute the subsystem-level suspend callback for the device; returns 0 on
|
||||
success, 1 if the device's run-time PM status was already 'suspended', or
|
||||
error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt
|
||||
to suspend the device again in future
|
||||
|
||||
int pm_runtime_resume(struct device *dev);
|
||||
- execute ->runtime_resume() for the device's bus type; returns 0 on
|
||||
- execute the subsystem-leve resume callback for the device; returns 0 on
|
||||
success, 1 if the device's run-time PM status was already 'active' or
|
||||
error code on failure, where -EAGAIN means it may be safe to attempt to
|
||||
resume the device again in future, but 'power.runtime_error' should be
|
||||
checked additionally
|
||||
|
||||
int pm_request_idle(struct device *dev);
|
||||
- submit a request to execute ->runtime_idle() for the device's bus type
|
||||
(the request is represented by a work item in pm_wq); returns 0 on success
|
||||
or error code if the request has not been queued up
|
||||
- submit a request to execute the subsystem-level idle callback for the
|
||||
device (the request is represented by a work item in pm_wq); returns 0 on
|
||||
success or error code if the request has not been queued up
|
||||
|
||||
int pm_schedule_suspend(struct device *dev, unsigned int delay);
|
||||
- schedule the execution of ->runtime_suspend() for the device's bus type
|
||||
in future, where 'delay' is the time to wait before queuing up a suspend
|
||||
work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is
|
||||
queued up immediately); returns 0 on success, 1 if the device's PM
|
||||
- schedule the execution of the subsystem-level suspend callback for the
|
||||
device in future, where 'delay' is the time to wait before queuing up a
|
||||
suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work
|
||||
item is queued up immediately); returns 0 on success, 1 if the device's PM
|
||||
run-time status was already 'suspended', or error code if the request
|
||||
hasn't been scheduled (or queued up if 'delay' is 0); if the execution of
|
||||
->runtime_suspend() is already scheduled and not yet expired, the new
|
||||
value of 'delay' will be used as the time to wait
|
||||
|
||||
int pm_request_resume(struct device *dev);
|
||||
- submit a request to execute ->runtime_resume() for the device's bus type
|
||||
(the request is represented by a work item in pm_wq); returns 0 on
|
||||
- submit a request to execute the subsystem-level resume callback for the
|
||||
device (the request is represented by a work item in pm_wq); returns 0 on
|
||||
success, 1 if the device's run-time PM status was already 'active', or
|
||||
error code if the request hasn't been queued up
|
||||
|
||||
@ -303,12 +304,12 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
|
||||
run-time PM callbacks described in Section 2
|
||||
|
||||
int pm_runtime_disable(struct device *dev);
|
||||
- prevent the run-time PM helper functions from running the device bus
|
||||
type's run-time PM callbacks, make sure that all of the pending run-time
|
||||
PM operations on the device are either completed or canceled; returns
|
||||
1 if there was a resume request pending and it was necessary to execute
|
||||
->runtime_resume() for the device's bus type to satisfy that request,
|
||||
otherwise 0 is returned
|
||||
- prevent the run-time PM helper functions from running subsystem-level
|
||||
run-time PM callbacks for the device, make sure that all of the pending
|
||||
run-time PM operations on the device are either completed or canceled;
|
||||
returns 1 if there was a resume request pending and it was necessary to
|
||||
execute the subsystem-level resume callback for the device to satisfy that
|
||||
request, otherwise 0 is returned
|
||||
|
||||
void pm_suspend_ignore_children(struct device *dev, bool enable);
|
||||
- set/unset the power.ignore_children flag of the device
|
||||
@ -378,5 +379,55 @@ pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts,
|
||||
they will fail returning -EAGAIN, because the device's usage counter is
|
||||
incremented by the core before executing ->probe() and ->remove(). Still, it
|
||||
may be desirable to suspend the device as soon as ->probe() or ->remove() has
|
||||
finished, so the PM core uses pm_runtime_idle_sync() to invoke the device bus
|
||||
type's ->runtime_idle() callback at that time.
|
||||
finished, so the PM core uses pm_runtime_idle_sync() to invoke the
|
||||
subsystem-level idle callback for the device at that time.
|
||||
|
||||
6. Run-time PM and System Sleep
|
||||
|
||||
Run-time PM and system sleep (i.e., system suspend and hibernation, also known
|
||||
as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of
|
||||
ways. If a device is active when a system sleep starts, everything is
|
||||
straightforward. But what should happen if the device is already suspended?
|
||||
|
||||
The device may have different wake-up settings for run-time PM and system sleep.
|
||||
For example, remote wake-up may be enabled for run-time suspend but disallowed
|
||||
for system sleep (device_may_wakeup(dev) returns 'false'). When this happens,
|
||||
the subsystem-level system suspend callback is responsible for changing the
|
||||
device's wake-up setting (it may leave that to the device driver's system
|
||||
suspend routine). It may be necessary to resume the device and suspend it again
|
||||
in order to do so. The same is true if the driver uses different power levels
|
||||
or other settings for run-time suspend and system sleep.
|
||||
|
||||
During system resume, devices generally should be brought back to full power,
|
||||
even if they were suspended before the system sleep began. There are several
|
||||
reasons for this, including:
|
||||
|
||||
* The device might need to switch power levels, wake-up settings, etc.
|
||||
|
||||
* Remote wake-up events might have been lost by the firmware.
|
||||
|
||||
* The device's children may need the device to be at full power in order
|
||||
to resume themselves.
|
||||
|
||||
* The driver's idea of the device state may not agree with the device's
|
||||
physical state. This can happen during resume from hibernation.
|
||||
|
||||
* The device might need to be reset.
|
||||
|
||||
* Even though the device was suspended, if its usage counter was > 0 then most
|
||||
likely it would need a run-time resume in the near future anyway.
|
||||
|
||||
* Always going back to full power is simplest.
|
||||
|
||||
If the device was suspended before the sleep began, then its run-time PM status
|
||||
will have to be updated to reflect the actual post-system sleep status. The way
|
||||
to do this is:
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
The PM core always increments the run-time usage counter before calling the
|
||||
->prepare() callback and decrements it after calling the ->complete() callback.
|
||||
Hence disabling run-time PM temporarily like this will not cause any run-time
|
||||
suspend callbacks to be lost.
|
||||
|
42
Documentation/powerpc/dts-bindings/fsl/mpic.txt
Normal file
42
Documentation/powerpc/dts-bindings/fsl/mpic.txt
Normal file
@ -0,0 +1,42 @@
|
||||
* OpenPIC and its interrupt numbers on Freescale's e500/e600 cores
|
||||
|
||||
The OpenPIC specification does not specify which interrupt source has to
|
||||
become which interrupt number. This is up to the software implementation
|
||||
of the interrupt controller. The only requirement is that every
|
||||
interrupt source has to have an unique interrupt number / vector number.
|
||||
To accomplish this the current implementation assigns the number zero to
|
||||
the first source, the number one to the second source and so on until
|
||||
all interrupt sources have their unique number.
|
||||
Usually the assigned vector number equals the interrupt number mentioned
|
||||
in the documentation for a given core / CPU. This is however not true
|
||||
for the e500 cores (MPC85XX CPUs) where the documentation distinguishes
|
||||
between internal and external interrupt sources and starts counting at
|
||||
zero for both of them.
|
||||
|
||||
So what to write for external interrupt source X or internal interrupt
|
||||
source Y into the device tree? Here is an example:
|
||||
|
||||
The memory map for the interrupt controller in the MPC8544[0] shows,
|
||||
that the first interrupt source starts at 0x5_0000 (PIC Register Address
|
||||
Map-Interrupt Source Configuration Registers). This source becomes the
|
||||
number zero therefore:
|
||||
External interrupt 0 = interrupt number 0
|
||||
External interrupt 1 = interrupt number 1
|
||||
External interrupt 2 = interrupt number 2
|
||||
...
|
||||
Every interrupt number allocates 0x20 bytes register space. So to get
|
||||
its number it is sufficient to shift the lower 16bits to right by five.
|
||||
So for the external interrupt 10 we have:
|
||||
0x0140 >> 5 = 10
|
||||
|
||||
After the external sources, the internal sources follow. The in core I2C
|
||||
controller on the MPC8544 for instance has the internal source number
|
||||
27. Oo obtain its interrupt number we take the lower 16bits of its memory
|
||||
address (0x5_0560) and shift it right:
|
||||
0x0560 >> 5 = 43
|
||||
|
||||
Therefore the I2C device node for the MPC8544 CPU has to have the
|
||||
interrupt number 43 specified in the device tree.
|
||||
|
||||
[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual
|
||||
MPC8544ERM Rev. 1 10/2007
|
@ -403,4 +403,5 @@ STAC9872
|
||||
Cirrus Logic CS4206/4207
|
||||
========================
|
||||
mbp55 MacBook Pro 5,5
|
||||
imac27 IMac 27 Inch
|
||||
auto BIOS setup (default)
|
||||
|
@ -26,13 +26,33 @@ Procedure for submitting patches to the -stable tree:
|
||||
|
||||
- Send the patch, after verifying that it follows the above rules, to
|
||||
stable@kernel.org.
|
||||
- To have the patch automatically included in the stable tree, add the
|
||||
the tag
|
||||
Cc: stable@kernel.org
|
||||
in the sign-off area. Once the patch is merged it will be applied to
|
||||
the stable tree without anything else needing to be done by the author
|
||||
or subsystem maintainer.
|
||||
- If the patch requires other patches as prerequisites which can be
|
||||
cherry-picked than this can be specified in the following format in
|
||||
the sign-off area:
|
||||
|
||||
Cc: <stable@kernel.org> # .32.x: a1f84a3: sched: Check for idle
|
||||
Cc: <stable@kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
|
||||
Cc: <stable@kernel.org> # .32.x: fd21073: sched: Fix affinity logic
|
||||
Cc: <stable@kernel.org> # .32.x
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
|
||||
The tag sequence has the meaning of:
|
||||
git cherry-pick a1f84a3
|
||||
git cherry-pick 1b9508f
|
||||
git cherry-pick fd21073
|
||||
git cherry-pick <this commit>
|
||||
|
||||
- The sender will receive an ACK when the patch has been accepted into the
|
||||
queue, or a NAK if the patch is rejected. This response might take a few
|
||||
days, according to the developer's schedules.
|
||||
- If accepted, the patch will be added to the -stable queue, for review by
|
||||
other developers and by the relevant subsystem maintainer.
|
||||
- If the stable@kernel.org address is added to a patch, when it goes into
|
||||
Linus's tree it will automatically be emailed to the stable team.
|
||||
- Security patches should not be sent to this alias, but instead to the
|
||||
documented security@kernel.org address.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
Subsystem Trace Points: kmem
|
||||
|
||||
The tracing system kmem captures events related to object and page allocation
|
||||
within the kernel. Broadly speaking there are four major subheadings.
|
||||
The kmem tracing system captures events related to object and page allocation
|
||||
within the kernel. Broadly speaking there are five major subheadings.
|
||||
|
||||
o Slab allocation of small objects of unknown type (kmalloc)
|
||||
o Slab allocation of small objects of known type
|
||||
@ -9,7 +9,7 @@ within the kernel. Broadly speaking there are four major subheadings.
|
||||
o Per-CPU Allocator Activity
|
||||
o External Fragmentation
|
||||
|
||||
This document will describe what each of the tracepoints are and why they
|
||||
This document describes what each of the tracepoints is and why they
|
||||
might be useful.
|
||||
|
||||
1. Slab allocation of small objects of unknown type
|
||||
@ -34,7 +34,7 @@ kmem_cache_free call_site=%lx ptr=%p
|
||||
These events are similar in usage to the kmalloc-related events except that
|
||||
it is likely easier to pin the event down to a specific cache. At the time
|
||||
of writing, no information is available on what slab is being allocated from,
|
||||
but the call_site can usually be used to extrapolate that information
|
||||
but the call_site can usually be used to extrapolate that information.
|
||||
|
||||
3. Page allocation
|
||||
==================
|
||||
@ -80,9 +80,9 @@ event indicating whether it is for a percpu_refill or not.
|
||||
When the per-CPU list is too full, a number of pages are freed, each one
|
||||
which triggers a mm_page_pcpu_drain event.
|
||||
|
||||
The individual nature of the events are so that pages can be tracked
|
||||
The individual nature of the events is so that pages can be tracked
|
||||
between allocation and freeing. A number of drain or refill pages that occur
|
||||
consecutively imply the zone->lock being taken once. Large amounts of PCP
|
||||
consecutively imply the zone->lock being taken once. Large amounts of per-CPU
|
||||
refills and drains could imply an imbalance between CPUs where too much work
|
||||
is being concentrated in one place. It could also indicate that the per-CPU
|
||||
lists should be a larger size. Finally, large amounts of refills on one CPU
|
||||
@ -102,6 +102,6 @@ is important.
|
||||
|
||||
Large numbers of this event implies that memory is fragmenting and
|
||||
high-order allocations will start failing at some time in the future. One
|
||||
means of reducing the occurange of this event is to increase the size of
|
||||
means of reducing the occurrence of this event is to increase the size of
|
||||
min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where
|
||||
pageblock_size is usually the size of the default hugepage size.
|
||||
|
@ -71,12 +71,10 @@ being accessed through sysfs, then it definitely is idle.
|
||||
Forms of dynamic PM
|
||||
-------------------
|
||||
|
||||
Dynamic suspends can occur in two ways: manual and automatic.
|
||||
"Manual" means that the user has told the kernel to suspend a device,
|
||||
whereas "automatic" means that the kernel has decided all by itself to
|
||||
suspend a device. Automatic suspend is called "autosuspend" for
|
||||
short. In general, a device won't be autosuspended unless it has been
|
||||
idle for some minimum period of time, the so-called idle-delay time.
|
||||
Dynamic suspends occur when the kernel decides to suspend an idle
|
||||
device. This is called "autosuspend" for short. In general, a device
|
||||
won't be autosuspended unless it has been idle for some minimum period
|
||||
of time, the so-called idle-delay time.
|
||||
|
||||
Of course, nothing the kernel does on its own initiative should
|
||||
prevent the computer or its devices from working properly. If a
|
||||
@ -96,10 +94,11 @@ idle.
|
||||
We can categorize power management events in two broad classes:
|
||||
external and internal. External events are those triggered by some
|
||||
agent outside the USB stack: system suspend/resume (triggered by
|
||||
userspace), manual dynamic suspend/resume (also triggered by
|
||||
userspace), and remote wakeup (triggered by the device). Internal
|
||||
events are those triggered within the USB stack: autosuspend and
|
||||
autoresume.
|
||||
userspace), manual dynamic resume (also triggered by userspace), and
|
||||
remote wakeup (triggered by the device). Internal events are those
|
||||
triggered within the USB stack: autosuspend and autoresume. Note that
|
||||
all dynamic suspend events are internal; external agents are not
|
||||
allowed to issue dynamic suspends.
|
||||
|
||||
|
||||
The user interface for dynamic PM
|
||||
@ -145,9 +144,9 @@ relevant attribute files are: wakeup, level, and autosuspend.
|
||||
number of seconds the device should remain idle before
|
||||
the kernel will autosuspend it (the idle-delay time).
|
||||
The default is 2. 0 means to autosuspend as soon as
|
||||
the device becomes idle, and -1 means never to
|
||||
autosuspend. You can write a number to the file to
|
||||
change the autosuspend idle-delay time.
|
||||
the device becomes idle, and negative values mean
|
||||
never to autosuspend. You can write a number to the
|
||||
file to change the autosuspend idle-delay time.
|
||||
|
||||
Writing "-1" to power/autosuspend and writing "on" to power/level do
|
||||
essentially the same thing -- they both prevent the device from being
|
||||
@ -377,9 +376,9 @@ the device hasn't been idle for long enough, a delayed workqueue
|
||||
routine is automatically set up to carry out the operation when the
|
||||
autosuspend idle-delay has expired.
|
||||
|
||||
Autoresume attempts also can fail. This will happen if power/level is
|
||||
set to "suspend" or if the device doesn't manage to resume properly.
|
||||
Unlike autosuspend, there's no delay for an autoresume.
|
||||
Autoresume attempts also can fail, although failure would mean that
|
||||
the device is no longer present or operating properly. Unlike
|
||||
autosuspend, there's no delay for an autoresume.
|
||||
|
||||
|
||||
Other parts of the driver interface
|
||||
@ -527,13 +526,3 @@ succeed, it may still remain active and thus cause the system to
|
||||
resume as soon as the system suspend is complete. Or the remote
|
||||
wakeup may fail and get lost. Which outcome occurs depends on timing
|
||||
and on the hardware and firmware design.
|
||||
|
||||
More interestingly, a device might undergo a manual resume or
|
||||
autoresume during system suspend. With current kernels this shouldn't
|
||||
happen, because manual resumes must be initiated by userspace and
|
||||
autoresumes happen in response to I/O requests, but all user processes
|
||||
and I/O should be quiescent during a system suspend -- thanks to the
|
||||
freezer. However there are plans to do away with the freezer, which
|
||||
would mean these things would become possible. If and when this comes
|
||||
about, the USB core will carefully arrange matters so that either type
|
||||
of resume will block until the entire system has resumed.
|
||||
|
12
MAINTAINERS
12
MAINTAINERS
@ -1402,6 +1402,8 @@ L: linux-usb@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/usb/WUSB-Design-overview.txt
|
||||
F: Documentation/usb/wusb-cbaf
|
||||
F: drivers/usb/host/hwa-hc.c
|
||||
F: drivers/usb/host/whci/
|
||||
F: drivers/usb/wusbcore/
|
||||
F: include/linux/usb/wusb*
|
||||
|
||||
@ -3677,7 +3679,7 @@ F: include/linux/isicom.h
|
||||
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
|
||||
M: Felipe Balbi <felipe.balbi@nokia.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
T: git git://gitorious.org/musb/mainline.git
|
||||
T: git git://gitorious.org/usb/usb.git
|
||||
S: Maintained
|
||||
F: drivers/usb/musb/
|
||||
|
||||
@ -5430,7 +5432,10 @@ ULTRA-WIDEBAND (UWB) SUBSYSTEM:
|
||||
M: David Vrabel <david.vrabel@csr.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/uwb/*
|
||||
F: drivers/uwb/
|
||||
X: drivers/uwb/wlp/
|
||||
X: drivers/uwb/i1480/i1480u-wlp/
|
||||
X: drivers/uwb/i1480/i1480-wlp.h
|
||||
F: include/linux/uwb.h
|
||||
F: include/linux/uwb/
|
||||
|
||||
@ -5943,9 +5948,12 @@ W: http://linuxwimax.org
|
||||
|
||||
WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM
|
||||
M: David Vrabel <david.vrabel@csr.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: include/linux/wlp.h
|
||||
F: drivers/uwb/wlp/
|
||||
F: drivers/uwb/i1480/i1480u-wlp/
|
||||
F: drivers/uwb/i1480/i1480-wlp.h
|
||||
|
||||
WISTRON LAPTOP BUTTON DRIVER
|
||||
M: Miloslav Trmac <mitr@volny.cz>
|
||||
|
@ -108,12 +108,19 @@
|
||||
dcr-reg = <0x00c 0x002>;
|
||||
};
|
||||
|
||||
MQ0: mq {
|
||||
compatible = "ibm,mq-440spe";
|
||||
dcr-reg = <0x040 0x020>;
|
||||
};
|
||||
|
||||
plb {
|
||||
compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
/* addr-child addr-parent size */
|
||||
ranges = <0x4 0xe0000000 0x4 0xe0000000 0x20000000
|
||||
ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000
|
||||
0x4 0x00200000 0x4 0x00200000 0x00000400
|
||||
0x4 0xe0000000 0x4 0xe0000000 0x20000000
|
||||
0xc 0x00000000 0xc 0x00000000 0x20000000
|
||||
0xd 0x00000000 0xd 0x00000000 0x80000000
|
||||
0xd 0x80000000 0xd 0x80000000 0x80000000
|
||||
@ -400,6 +407,49 @@
|
||||
0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */
|
||||
0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
|
||||
};
|
||||
|
||||
I2O: i2o@400100000 {
|
||||
compatible = "ibm,i2o-440spe";
|
||||
reg = <0x00000004 0x00100000 0x100>;
|
||||
dcr-reg = <0x060 0x020>;
|
||||
};
|
||||
|
||||
DMA0: dma0@400100100 {
|
||||
compatible = "ibm,dma-440spe";
|
||||
cell-index = <0>;
|
||||
reg = <0x00000004 0x00100100 0x100>;
|
||||
dcr-reg = <0x060 0x020>;
|
||||
interrupt-parent = <&DMA0>;
|
||||
interrupts = <0 1>;
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
interrupt-map = <
|
||||
0 &UIC0 0x14 4
|
||||
1 &UIC1 0x16 4>;
|
||||
};
|
||||
|
||||
DMA1: dma1@400100200 {
|
||||
compatible = "ibm,dma-440spe";
|
||||
cell-index = <1>;
|
||||
reg = <0x00000004 0x00100200 0x100>;
|
||||
dcr-reg = <0x060 0x020>;
|
||||
interrupt-parent = <&DMA1>;
|
||||
interrupts = <0 1>;
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
interrupt-map = <
|
||||
0 &UIC0 0x16 4
|
||||
1 &UIC1 0x16 4>;
|
||||
};
|
||||
|
||||
xor-accel@400200000 {
|
||||
compatible = "amcc,xor-accelerator";
|
||||
reg = <0x00000004 0x00200000 0x400>;
|
||||
interrupt-parent = <&UIC1>;
|
||||
interrupts = <0x1f 4>;
|
||||
};
|
||||
};
|
||||
|
||||
chosen {
|
||||
|
@ -204,6 +204,7 @@
|
||||
interrupt-parent = <&ipic>;
|
||||
tbi-handle = <&tbi0>;
|
||||
phy-handle = < &phy0 >;
|
||||
fsl,magic-packet;
|
||||
|
||||
mdio@520 {
|
||||
#address-cells = <1>;
|
||||
@ -246,6 +247,7 @@
|
||||
interrupt-parent = <&ipic>;
|
||||
tbi-handle = <&tbi1>;
|
||||
phy-handle = < &phy1 >;
|
||||
fsl,magic-packet;
|
||||
|
||||
mdio@520 {
|
||||
#address-cells = <1>;
|
||||
@ -309,6 +311,22 @@
|
||||
interrupt-parent = <&ipic>;
|
||||
};
|
||||
|
||||
gtm1: timer@500 {
|
||||
compatible = "fsl,mpc8315-gtm", "fsl,gtm";
|
||||
reg = <0x500 0x100>;
|
||||
interrupts = <90 8 78 8 84 8 72 8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
clock-frequency = <133333333>;
|
||||
};
|
||||
|
||||
timer@600 {
|
||||
compatible = "fsl,mpc8315-gtm", "fsl,gtm";
|
||||
reg = <0x600 0x100>;
|
||||
interrupts = <91 8 79 8 85 8 73 8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
clock-frequency = <133333333>;
|
||||
};
|
||||
|
||||
/* IPIC
|
||||
* interrupts cell = <intr #, sense>
|
||||
* sense values match linux IORESOURCE_IRQ_* defines:
|
||||
@ -337,6 +355,15 @@
|
||||
0x59 0x8>;
|
||||
interrupt-parent = < &ipic >;
|
||||
};
|
||||
|
||||
pmc: power@b00 {
|
||||
compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc",
|
||||
"fsl,mpc8349-pmc";
|
||||
reg = <0xb00 0x100 0xa00 0x100>;
|
||||
interrupts = <80 8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
fsl,mpc8313-wakeup-timer = <>m1>;
|
||||
};
|
||||
};
|
||||
|
||||
pci0: pci@e0008500 {
|
||||
|
@ -63,6 +63,24 @@
|
||||
reg = <0x200 0x100>;
|
||||
};
|
||||
|
||||
gpio1: gpio-controller@c00 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mpc8349-gpio";
|
||||
reg = <0xc00 0x100>;
|
||||
interrupts = <74 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio2: gpio-controller@d00 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mpc8349-gpio";
|
||||
reg = <0xd00 0x100>;
|
||||
interrupts = <75 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
i2c@3000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@ -72,6 +90,12 @@
|
||||
interrupts = <14 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
dfsrr;
|
||||
|
||||
eeprom: at24@50 {
|
||||
compatible = "st-micro,24c256";
|
||||
reg = <0x50>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
i2c@3100 {
|
||||
@ -91,6 +115,25 @@
|
||||
interrupt-parent = <&ipic>;
|
||||
};
|
||||
|
||||
pcf1: iexp@38 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "ti,pcf8574a";
|
||||
reg = <0x38>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
pcf2: iexp@39 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "ti,pcf8574a";
|
||||
reg = <0x39>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
spd: at24@51 {
|
||||
compatible = "at24,spd";
|
||||
reg = <0x51>;
|
||||
};
|
||||
|
||||
mcu_pio: mcu@a {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mc9s08qg8-mpc8349emitx",
|
||||
@ -275,6 +318,24 @@
|
||||
reg = <0x700 0x100>;
|
||||
device_type = "ipic";
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
green {
|
||||
label = "Green";
|
||||
gpios = <&pcf1 0 1>;
|
||||
linux,default-trigger = "heartbeat";
|
||||
};
|
||||
|
||||
yellow {
|
||||
label = "Yellow";
|
||||
gpios = <&pcf1 1 1>;
|
||||
/* linux,default-trigger = "heartbeat"; */
|
||||
default-state = "on";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
pci0: pci@e0008500 {
|
||||
@ -331,7 +392,26 @@
|
||||
compatible = "fsl,mpc8349e-localbus",
|
||||
"fsl,pq2pro-localbus";
|
||||
reg = <0xe0005000 0xd8>;
|
||||
ranges = <0x3 0x0 0xf0000000 0x210>;
|
||||
ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */
|
||||
0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */
|
||||
0x2 0x0 0xf9000000 0x200000 /* exp slot */
|
||||
0x3 0x0 0xf0000000 0x210>; /* CF slot */
|
||||
|
||||
flash@0,0 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x0 0x0 0x800000>;
|
||||
bank-width = <2>;
|
||||
device-width = <1>;
|
||||
};
|
||||
|
||||
flash@0,800000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x0 0x800000 0x800000>;
|
||||
bank-width = <2>;
|
||||
device-width = <1>;
|
||||
};
|
||||
|
||||
pata@3,0 {
|
||||
compatible = "fsl,mpc8349emitx-pata", "ata-generic";
|
||||
|
@ -146,7 +146,7 @@
|
||||
|
||||
fpga@2,4000 {
|
||||
compatible = "pika,fpga-sd";
|
||||
reg = <0x00000002 0x00004000 0x00000A00>;
|
||||
reg = <0x00000002 0x00004000 0x00004000>;
|
||||
};
|
||||
|
||||
nor@0,0 {
|
||||
|
@ -86,7 +86,7 @@ static void ug_putc(char ch)
|
||||
|
||||
while (!ug_is_txfifo_ready() && count--)
|
||||
barrier();
|
||||
if (count)
|
||||
if (count >= 0)
|
||||
ug_raw_putc(ch);
|
||||
}
|
||||
|
||||
|
@ -757,7 +757,7 @@ CONFIG_SUNGEM=y
|
||||
# CONFIG_B44 is not set
|
||||
# CONFIG_ATL2 is not set
|
||||
CONFIG_NETDEV_1000=y
|
||||
CONFIG_ACENIC=y
|
||||
CONFIG_ACENIC=m
|
||||
CONFIG_ACENIC_OMIT_TIGON_I=y
|
||||
# CONFIG_DL2K is not set
|
||||
CONFIG_E1000=y
|
||||
@ -794,8 +794,8 @@ CONFIG_NETDEV_10000=y
|
||||
# CONFIG_BNX2X is not set
|
||||
# CONFIG_QLGE is not set
|
||||
# CONFIG_SFC is not set
|
||||
CONFIG_TR=y
|
||||
CONFIG_IBMOL=y
|
||||
# CONFIG_TR is not set
|
||||
# CONFIG_IBMOL is not set
|
||||
# CONFIG_3C359 is not set
|
||||
# CONFIG_TMS380TR is not set
|
||||
|
||||
|
@ -714,8 +714,8 @@ CONFIG_NETDEV_10000=y
|
||||
# CONFIG_BNX2X is not set
|
||||
# CONFIG_QLGE is not set
|
||||
# CONFIG_SFC is not set
|
||||
CONFIG_TR=y
|
||||
CONFIG_IBMOL=y
|
||||
# CONFIG_TR is not set
|
||||
# CONFIG_IBMOL is not set
|
||||
# CONFIG_3C359 is not set
|
||||
# CONFIG_TMS380TR is not set
|
||||
|
||||
|
@ -304,11 +304,11 @@ CONFIG_TICK_ONESHOT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_HZ_250 is not set
|
||||
# CONFIG_HZ_300 is not set
|
||||
# CONFIG_HZ_1000 is not set
|
||||
CONFIG_HZ=250
|
||||
CONFIG_HZ=100
|
||||
CONFIG_SCHED_HRTICK=y
|
||||
CONFIG_PREEMPT_NONE=y
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
@ -980,7 +980,7 @@ CONFIG_E100=y
|
||||
# CONFIG_SC92031 is not set
|
||||
# CONFIG_ATL2 is not set
|
||||
CONFIG_NETDEV_1000=y
|
||||
CONFIG_ACENIC=y
|
||||
CONFIG_ACENIC=m
|
||||
CONFIG_ACENIC_OMIT_TIGON_I=y
|
||||
# CONFIG_DL2K is not set
|
||||
CONFIG_E1000=y
|
||||
@ -1023,8 +1023,8 @@ CONFIG_PASEMI_MAC=y
|
||||
# CONFIG_BNX2X is not set
|
||||
# CONFIG_QLGE is not set
|
||||
# CONFIG_SFC is not set
|
||||
CONFIG_TR=y
|
||||
CONFIG_IBMOL=y
|
||||
# CONFIG_TR is not set
|
||||
# CONFIG_IBMOL is not set
|
||||
# CONFIG_3C359 is not set
|
||||
# CONFIG_TMS380TR is not set
|
||||
|
||||
@ -1863,7 +1863,7 @@ CONFIG_HFSPLUS_FS=m
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
CONFIG_CRAMFS=y
|
||||
CONFIG_CRAMFS=m
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_OMFS_FS is not set
|
||||
|
@ -1008,8 +1008,8 @@ CONFIG_IXGB=m
|
||||
# CONFIG_QLGE is not set
|
||||
# CONFIG_SFC is not set
|
||||
# CONFIG_BE2NET is not set
|
||||
CONFIG_TR=y
|
||||
CONFIG_IBMOL=y
|
||||
# CONFIG_TR is not set
|
||||
# CONFIG_IBMOL is not set
|
||||
# CONFIG_3C359 is not set
|
||||
# CONFIG_TMS380TR is not set
|
||||
CONFIG_WLAN=y
|
||||
|
@ -230,11 +230,11 @@ CONFIG_TICK_ONESHOT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_HZ_250 is not set
|
||||
# CONFIG_HZ_300 is not set
|
||||
# CONFIG_HZ_1000 is not set
|
||||
CONFIG_HZ=250
|
||||
CONFIG_HZ=100
|
||||
CONFIG_SCHED_HRTICK=y
|
||||
CONFIG_PREEMPT_NONE=y
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
@ -796,7 +796,7 @@ CONFIG_E100=y
|
||||
# CONFIG_NET_POCKET is not set
|
||||
# CONFIG_ATL2 is not set
|
||||
CONFIG_NETDEV_1000=y
|
||||
CONFIG_ACENIC=y
|
||||
CONFIG_ACENIC=m
|
||||
CONFIG_ACENIC_OMIT_TIGON_I=y
|
||||
# CONFIG_DL2K is not set
|
||||
CONFIG_E1000=y
|
||||
@ -834,8 +834,8 @@ CONFIG_S2IO=m
|
||||
# CONFIG_BNX2X is not set
|
||||
# CONFIG_QLGE is not set
|
||||
# CONFIG_SFC is not set
|
||||
CONFIG_TR=y
|
||||
CONFIG_IBMOL=y
|
||||
# CONFIG_TR is not set
|
||||
# CONFIG_IBMOL is not set
|
||||
# CONFIG_3C359 is not set
|
||||
# CONFIG_TMS380TR is not set
|
||||
|
||||
@ -1494,7 +1494,7 @@ CONFIG_CONFIGFS_FS=m
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
CONFIG_CRAMFS=y
|
||||
CONFIG_CRAMFS=m
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_OMFS_FS is not set
|
||||
|
@ -68,7 +68,7 @@
|
||||
_EMIT_BUG_ENTRY \
|
||||
: : "i" (__FILE__), "i" (__LINE__), \
|
||||
"i" (0), "i" (sizeof(struct bug_entry))); \
|
||||
for(;;) ; \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define BUG_ON(x) do { \
|
||||
|
@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio)
|
||||
return __gpio_cansleep(gpio);
|
||||
}
|
||||
|
||||
/*
|
||||
* Not implemented, yet.
|
||||
*/
|
||||
static inline int gpio_to_irq(unsigned int gpio)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return __gpio_to_irq(gpio);
|
||||
}
|
||||
|
||||
static inline int irq_to_gpio(unsigned int irq)
|
||||
|
@ -642,10 +642,14 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
|
||||
*/
|
||||
static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
|
||||
unsigned int areg, struct pt_regs *regs,
|
||||
unsigned int flags, unsigned int length)
|
||||
unsigned int flags, unsigned int length,
|
||||
unsigned int elsize)
|
||||
{
|
||||
char *ptr;
|
||||
unsigned long *lptr;
|
||||
int ret = 0;
|
||||
int sw = 0;
|
||||
int i, j;
|
||||
|
||||
flush_vsx_to_thread(current);
|
||||
|
||||
@ -654,19 +658,35 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
|
||||
else
|
||||
ptr = (char *) ¤t->thread.vr[reg - 32];
|
||||
|
||||
if (flags & ST)
|
||||
ret = __copy_to_user(addr, ptr, length);
|
||||
else {
|
||||
if (flags & SPLT){
|
||||
ret = __copy_from_user(ptr, addr, length);
|
||||
ptr += length;
|
||||
lptr = (unsigned long *) ptr;
|
||||
|
||||
if (flags & SW)
|
||||
sw = elsize-1;
|
||||
|
||||
for (j = 0; j < length; j += elsize) {
|
||||
for (i = 0; i < elsize; ++i) {
|
||||
if (flags & ST)
|
||||
ret |= __put_user(ptr[i^sw], addr + i);
|
||||
else
|
||||
ret |= __get_user(ptr[i^sw], addr + i);
|
||||
}
|
||||
ret |= __copy_from_user(ptr, addr, length);
|
||||
ptr += elsize;
|
||||
addr += elsize;
|
||||
}
|
||||
if (flags & U)
|
||||
regs->gpr[areg] = regs->dar;
|
||||
if (ret)
|
||||
|
||||
if (!ret) {
|
||||
if (flags & U)
|
||||
regs->gpr[areg] = regs->dar;
|
||||
|
||||
/* Splat load copies the same data to top and bottom 8 bytes */
|
||||
if (flags & SPLT)
|
||||
lptr[1] = lptr[0];
|
||||
/* For 8 byte loads, zero the top 8 bytes */
|
||||
else if (!(flags & ST) && (8 == length))
|
||||
lptr[1] = 0;
|
||||
} else
|
||||
return -EFAULT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@ -767,16 +787,25 @@ int fix_alignment(struct pt_regs *regs)
|
||||
|
||||
#ifdef CONFIG_VSX
|
||||
if ((instruction & 0xfc00003e) == 0x7c000018) {
|
||||
/* Additional register addressing bit (64 VSX vs 32 FPR/GPR */
|
||||
unsigned int elsize;
|
||||
|
||||
/* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */
|
||||
reg |= (instruction & 0x1) << 5;
|
||||
/* Simple inline decoder instead of a table */
|
||||
/* VSX has only 8 and 16 byte memory accesses */
|
||||
nb = 8;
|
||||
if (instruction & 0x200)
|
||||
nb = 16;
|
||||
else if (instruction & 0x080)
|
||||
nb = 8;
|
||||
else
|
||||
nb = 4;
|
||||
|
||||
/* Vector stores in little-endian mode swap individual
|
||||
elements, so process them separately */
|
||||
elsize = 4;
|
||||
if (instruction & 0x80)
|
||||
elsize = 8;
|
||||
|
||||
flags = 0;
|
||||
if (regs->msr & MSR_LE)
|
||||
flags |= SW;
|
||||
if (instruction & 0x100)
|
||||
flags |= ST;
|
||||
if (instruction & 0x040)
|
||||
@ -787,7 +816,7 @@ int fix_alignment(struct pt_regs *regs)
|
||||
nb = 8;
|
||||
}
|
||||
PPC_WARN_ALIGNMENT(vsx, regs);
|
||||
return emulate_vsx(addr, reg, areg, regs, flags, nb);
|
||||
return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize);
|
||||
}
|
||||
#endif
|
||||
/* A size of 0 indicates an instruction we don't support, with
|
||||
|
@ -340,7 +340,7 @@ static int __init htab_dt_scan_page_sizes(unsigned long node,
|
||||
else
|
||||
def->tlbiel = 0;
|
||||
|
||||
DBG(" %d: shift=%02x, sllp=%04x, avpnm=%08x, "
|
||||
DBG(" %d: shift=%02x, sllp=%04lx, avpnm=%08lx, "
|
||||
"tlbiel=%d, penc=%d\n",
|
||||
idx, shift, def->sllp, def->avpnm, def->tlbiel,
|
||||
def->penc);
|
||||
@ -663,7 +663,7 @@ static void __init htab_initialize(void)
|
||||
base = (unsigned long)__va(lmb.memory.region[i].base);
|
||||
size = lmb.memory.region[i].size;
|
||||
|
||||
DBG("creating mapping for region: %lx..%lx (prot: %x)\n",
|
||||
DBG("creating mapping for region: %lx..%lx (prot: %lx)\n",
|
||||
base, size, prot);
|
||||
|
||||
#ifdef CONFIG_U3_DART
|
||||
@ -879,7 +879,7 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
|
||||
*/
|
||||
int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
|
||||
{
|
||||
void *pgdir;
|
||||
pgd_t *pgdir;
|
||||
unsigned long vsid;
|
||||
struct mm_struct *mm;
|
||||
pte_t *ptep;
|
||||
@ -1025,7 +1025,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
|
||||
else
|
||||
#endif /* CONFIG_PPC_HAS_HASH_64K */
|
||||
{
|
||||
int spp = subpage_protection(pgdir, ea);
|
||||
int spp = subpage_protection(mm, ea);
|
||||
if (access & spp)
|
||||
rc = -2;
|
||||
else
|
||||
@ -1115,7 +1115,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
|
||||
{
|
||||
unsigned long hash, index, shift, hidx, slot;
|
||||
|
||||
DBG_LOW("flush_hash_page(va=%016x)\n", va);
|
||||
DBG_LOW("flush_hash_page(va=%016lx)\n", va);
|
||||
pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
|
||||
hash = hpt_hash(va, shift, ssize);
|
||||
hidx = __rpte_to_hidx(pte, index);
|
||||
@ -1123,7 +1123,7 @@ void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
|
||||
hash = ~hash;
|
||||
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
|
||||
slot += hidx & _PTEIDX_GROUP_IX;
|
||||
DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx);
|
||||
DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
|
||||
ppc_md.hpte_invalidate(slot, va, psize, ssize, local);
|
||||
} pte_iterate_hashed_end();
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
|
||||
read_lock(&tasklist_lock);
|
||||
for_each_process(p) {
|
||||
if (p->mm)
|
||||
cpu_mask_clear_cpu(cpu, mm_cpumask(p->mm));
|
||||
cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
break;
|
||||
|
@ -382,7 +382,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
|
||||
return 0;
|
||||
if (!get_pteptr(&init_mm, address, &kpte, &kpmd))
|
||||
return -EINVAL;
|
||||
set_pte_at(&init_mm, address, kpte, mk_pte(page, prot));
|
||||
__set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0);
|
||||
wmb();
|
||||
#ifdef CONFIG_PPC_STD_MMU
|
||||
flush_hash_pages(0, address, pmd_val(*kpmd), 1);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */
|
||||
#define PMCCR1_NEXT_STATE_SHIFT 2
|
||||
#define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/
|
||||
#define IMMR_SYSCR_OFFSET 0x100
|
||||
#define IMMR_RCW_OFFSET 0x900
|
||||
#define RCW_PCI_HOST 0x80000000
|
||||
|
||||
@ -78,6 +79,22 @@ struct mpc83xx_clock {
|
||||
u32 sccr;
|
||||
};
|
||||
|
||||
struct mpc83xx_syscr {
|
||||
__be32 sgprl;
|
||||
__be32 sgprh;
|
||||
__be32 spridr;
|
||||
__be32 :32;
|
||||
__be32 spcr;
|
||||
__be32 sicrl;
|
||||
__be32 sicrh;
|
||||
};
|
||||
|
||||
struct mpc83xx_saved {
|
||||
u32 sicrl;
|
||||
u32 sicrh;
|
||||
u32 sccr;
|
||||
};
|
||||
|
||||
struct pmc_type {
|
||||
int has_deep_sleep;
|
||||
};
|
||||
@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping;
|
||||
static int pmc_irq;
|
||||
static struct mpc83xx_pmc __iomem *pmc_regs;
|
||||
static struct mpc83xx_clock __iomem *clock_regs;
|
||||
static struct mpc83xx_syscr __iomem *syscr_regs;
|
||||
static struct mpc83xx_saved saved_regs;
|
||||
static int is_pci_agent, wake_from_pci;
|
||||
static phys_addr_t immrbase;
|
||||
static int pci_pm_state;
|
||||
@ -137,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mpc83xx_suspend_restore_regs(void)
|
||||
{
|
||||
out_be32(&syscr_regs->sicrl, saved_regs.sicrl);
|
||||
out_be32(&syscr_regs->sicrh, saved_regs.sicrh);
|
||||
out_be32(&clock_regs->sccr, saved_regs.sccr);
|
||||
}
|
||||
|
||||
static void mpc83xx_suspend_save_regs(void)
|
||||
{
|
||||
saved_regs.sicrl = in_be32(&syscr_regs->sicrl);
|
||||
saved_regs.sicrh = in_be32(&syscr_regs->sicrh);
|
||||
saved_regs.sccr = in_be32(&clock_regs->sccr);
|
||||
}
|
||||
|
||||
static int mpc83xx_suspend_enter(suspend_state_t state)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
@ -166,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
|
||||
*/
|
||||
|
||||
if (deep_sleeping) {
|
||||
mpc83xx_suspend_save_regs();
|
||||
|
||||
out_be32(&pmc_regs->mask, PMCER_ALL);
|
||||
|
||||
out_be32(&pmc_regs->config1,
|
||||
@ -179,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
|
||||
in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
|
||||
|
||||
out_be32(&pmc_regs->mask, PMCER_PMCI);
|
||||
|
||||
mpc83xx_suspend_restore_regs();
|
||||
} else {
|
||||
out_be32(&pmc_regs->mask, PMCER_PMCI);
|
||||
|
||||
@ -194,7 +231,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mpc83xx_suspend_finish(void)
|
||||
static void mpc83xx_suspend_end(void)
|
||||
{
|
||||
deep_sleeping = 0;
|
||||
}
|
||||
@ -278,7 +315,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = {
|
||||
.valid = mpc83xx_suspend_valid,
|
||||
.begin = mpc83xx_suspend_begin,
|
||||
.enter = mpc83xx_suspend_enter,
|
||||
.finish = mpc83xx_suspend_finish,
|
||||
.end = mpc83xx_suspend_end,
|
||||
};
|
||||
|
||||
static int pmc_probe(struct of_device *ofdev,
|
||||
@ -333,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev,
|
||||
goto out_pmc;
|
||||
}
|
||||
|
||||
if (has_deep_sleep) {
|
||||
syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET,
|
||||
sizeof(*syscr_regs));
|
||||
if (!syscr_regs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_syscr;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_pci_agent)
|
||||
mpc83xx_set_agent();
|
||||
|
||||
suspend_set_ops(&mpc83xx_suspend_ops);
|
||||
return 0;
|
||||
|
||||
out_syscr:
|
||||
iounmap(clock_regs);
|
||||
out_pmc:
|
||||
iounmap(pmc_regs);
|
||||
out:
|
||||
|
@ -86,7 +86,7 @@ static int mpc8568_fixup_125_clock(struct phy_device *phydev)
|
||||
scr = phy_read(phydev, MV88E1111_SCR);
|
||||
|
||||
if (scr < 0)
|
||||
return err;
|
||||
return scr;
|
||||
|
||||
err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);
|
||||
|
||||
|
@ -102,7 +102,7 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
set_irq_chip_data(virq, h->host_data);
|
||||
get_irq_desc(virq)->status |= IRQ_LEVEL;
|
||||
irq_to_desc(virq)->status |= IRQ_LEVEL;
|
||||
set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq);
|
||||
return 0;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
set_irq_chip_data(virq, h->host_data);
|
||||
get_irq_desc(virq)->status |= IRQ_LEVEL;
|
||||
irq_to_desc(virq)->status |= IRQ_LEVEL;
|
||||
set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq);
|
||||
return 0;
|
||||
}
|
||||
@ -132,9 +132,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
|
||||
struct irq_host *irq_host = get_irq_data(cascade_virq);
|
||||
unsigned int virq;
|
||||
|
||||
spin_lock(&desc->lock);
|
||||
raw_spin_lock(&desc->lock);
|
||||
desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
|
||||
spin_unlock(&desc->lock);
|
||||
raw_spin_unlock(&desc->lock);
|
||||
|
||||
virq = __hlwd_pic_get_irq(irq_host);
|
||||
if (virq != NO_IRQ)
|
||||
@ -142,11 +142,11 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
|
||||
else
|
||||
pr_err("spurious interrupt!\n");
|
||||
|
||||
spin_lock(&desc->lock);
|
||||
raw_spin_lock(&desc->lock);
|
||||
desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
|
||||
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
|
||||
desc->chip->unmask(cascade_virq);
|
||||
spin_unlock(&desc->lock);
|
||||
raw_spin_unlock(&desc->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -120,7 +120,7 @@ static void ug_putc(char ch)
|
||||
|
||||
while (!ug_is_txfifo_ready() && count--)
|
||||
barrier();
|
||||
if (count)
|
||||
if (count >= 0)
|
||||
ug_raw_putc(ch);
|
||||
}
|
||||
|
||||
|
@ -855,59 +855,58 @@ static int mf_get_boot_rtc(struct rtc_time *tm)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
static int mf_cmdline_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int len;
|
||||
char *p;
|
||||
char *page, *p;
|
||||
struct vsp_cmd_data vsp_cmd;
|
||||
int rc;
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
/* The HV appears to return no more than 256 bytes of command line */
|
||||
if (off >= 256)
|
||||
return 0;
|
||||
if ((off + count) > 256)
|
||||
count = 256 - off;
|
||||
|
||||
dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE);
|
||||
if (dma_addr == DMA_ERROR_CODE)
|
||||
page = kmalloc(256, GFP_KERNEL);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
memset(page, 0, off + count);
|
||||
|
||||
dma_addr = iseries_hv_map(page, 256, DMA_FROM_DEVICE);
|
||||
if (dma_addr == DMA_ERROR_CODE) {
|
||||
kfree(page);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(page, 0, 256);
|
||||
memset(&vsp_cmd, 0, sizeof(vsp_cmd));
|
||||
vsp_cmd.cmd = 33;
|
||||
vsp_cmd.sub_data.kern.token = dma_addr;
|
||||
vsp_cmd.sub_data.kern.address_type = HvLpDma_AddressType_TceIndex;
|
||||
vsp_cmd.sub_data.kern.side = (u64)data;
|
||||
vsp_cmd.sub_data.kern.length = off + count;
|
||||
vsp_cmd.sub_data.kern.side = (u64)m->private;
|
||||
vsp_cmd.sub_data.kern.length = 256;
|
||||
mb();
|
||||
rc = signal_vsp_instruction(&vsp_cmd);
|
||||
iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE);
|
||||
if (rc)
|
||||
iseries_hv_unmap(dma_addr, 256, DMA_FROM_DEVICE);
|
||||
if (rc) {
|
||||
kfree(page);
|
||||
return rc;
|
||||
if (vsp_cmd.result_code != 0)
|
||||
}
|
||||
if (vsp_cmd.result_code != 0) {
|
||||
kfree(page);
|
||||
return -ENOMEM;
|
||||
}
|
||||
p = page;
|
||||
len = 0;
|
||||
while (len < (off + count)) {
|
||||
if ((*p == '\0') || (*p == '\n')) {
|
||||
if (*p == '\0')
|
||||
*p = '\n';
|
||||
p++;
|
||||
len++;
|
||||
*eof = 1;
|
||||
while (p - page < 256) {
|
||||
if (*p == '\0' || *p == '\n') {
|
||||
*p = '\n';
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len < off) {
|
||||
*eof = 1;
|
||||
len = 0;
|
||||
}
|
||||
return len;
|
||||
seq_write(m, page, p - page);
|
||||
kfree(page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mf_cmdline_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, mf_cmdline_proc_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -962,10 +961,8 @@ static int proc_mf_dump_vmlinux(char *page, char **start, off_t off,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int proc_mf_dump_side(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
static int mf_side_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
int len;
|
||||
char mf_current_side = ' ';
|
||||
struct vsp_cmd_data vsp_cmd;
|
||||
|
||||
@ -989,21 +986,17 @@ static int proc_mf_dump_side(char *page, char **start, off_t off,
|
||||
}
|
||||
}
|
||||
|
||||
len = sprintf(page, "%c\n", mf_current_side);
|
||||
|
||||
if (len <= (off + count))
|
||||
*eof = 1;
|
||||
*start = page + off;
|
||||
len -= off;
|
||||
if (len > count)
|
||||
len = count;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
return len;
|
||||
seq_printf(m, "%c\n", mf_current_side);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_mf_change_side(struct file *file, const char __user *buffer,
|
||||
unsigned long count, void *data)
|
||||
static int mf_side_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, mf_side_proc_show, NULL);
|
||||
}
|
||||
|
||||
static ssize_t mf_side_proc_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
char side;
|
||||
u64 newSide;
|
||||
@ -1041,6 +1034,15 @@ static int proc_mf_change_side(struct file *file, const char __user *buffer,
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations mf_side_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mf_side_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = mf_side_proc_write,
|
||||
};
|
||||
|
||||
#if 0
|
||||
static void mf_getSrcHistory(char *buffer, int size)
|
||||
{
|
||||
@ -1087,8 +1089,7 @@ static void mf_getSrcHistory(char *buffer, int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int proc_mf_dump_src(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
static int mf_src_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
#if 0
|
||||
int len;
|
||||
@ -1109,8 +1110,13 @@ static int proc_mf_dump_src(char *page, char **start, off_t off,
|
||||
#endif
|
||||
}
|
||||
|
||||
static int proc_mf_change_src(struct file *file, const char __user *buffer,
|
||||
unsigned long count, void *data)
|
||||
static int mf_src_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, mf_src_proc_show, NULL);
|
||||
}
|
||||
|
||||
static ssize_t mf_src_proc_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
char stkbuf[10];
|
||||
|
||||
@ -1135,9 +1141,19 @@ static int proc_mf_change_src(struct file *file, const char __user *buffer,
|
||||
return count;
|
||||
}
|
||||
|
||||
static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
|
||||
unsigned long count, void *data)
|
||||
static const struct file_operations mf_src_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mf_src_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = mf_src_proc_write,
|
||||
};
|
||||
|
||||
static ssize_t mf_cmdline_proc_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
void *data = PDE(file->f_path.dentry->d_inode)->data;
|
||||
struct vsp_cmd_data vsp_cmd;
|
||||
dma_addr_t dma_addr;
|
||||
char *page;
|
||||
@ -1172,6 +1188,15 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations mf_cmdline_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mf_cmdline_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = mf_cmdline_proc_write,
|
||||
};
|
||||
|
||||
static ssize_t proc_mf_change_vmlinux(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -1246,12 +1271,10 @@ static int __init mf_proc_init(void)
|
||||
if (!mf)
|
||||
return 1;
|
||||
|
||||
ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf);
|
||||
ent = proc_create_data("cmdline", S_IRUSR|S_IWUSR, mf,
|
||||
&mf_cmdline_proc_fops, (void *)(long)i);
|
||||
if (!ent)
|
||||
return 1;
|
||||
ent->data = (void *)(long)i;
|
||||
ent->read_proc = proc_mf_dump_cmdline;
|
||||
ent->write_proc = proc_mf_change_cmdline;
|
||||
|
||||
if (i == 3) /* no vmlinux entry for 'D' */
|
||||
continue;
|
||||
@ -1263,19 +1286,15 @@ static int __init mf_proc_init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
|
||||
ent = proc_create("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
|
||||
&mf_side_proc_fops);
|
||||
if (!ent)
|
||||
return 1;
|
||||
ent->data = (void *)0;
|
||||
ent->read_proc = proc_mf_dump_side;
|
||||
ent->write_proc = proc_mf_change_side;
|
||||
|
||||
ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
|
||||
ent = proc_create("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root,
|
||||
&mf_src_proc_fops);
|
||||
if (!ent)
|
||||
return 1;
|
||||
ent->data = (void *)0;
|
||||
ent->read_proc = proc_mf_dump_src;
|
||||
ent->write_proc = proc_mf_change_src;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
|
||||
u16 vlanMap;
|
||||
dma_addr_t handle;
|
||||
HvLpEvent_Rc hvrc;
|
||||
DECLARE_COMPLETION(done);
|
||||
DECLARE_COMPLETION_ONSTACK(done);
|
||||
struct device_node *node;
|
||||
const char *sysid;
|
||||
|
||||
|
@ -2,6 +2,8 @@ config PPC_PSERIES
|
||||
depends on PPC64 && PPC_BOOK3S
|
||||
bool "IBM pSeries & new (POWER5-based) iSeries"
|
||||
select MPIC
|
||||
select PCI_MSI
|
||||
select XICS
|
||||
select PPC_I8259
|
||||
select PPC_RTAS
|
||||
select PPC_RTAS_DAEMON
|
||||
|
@ -38,19 +38,28 @@
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/memory.h>
|
||||
|
||||
#include "plpar_wrappers.h"
|
||||
|
||||
#define CMM_DRIVER_VERSION "1.0.0"
|
||||
#define CMM_DEFAULT_DELAY 1
|
||||
#define CMM_HOTPLUG_DELAY 5
|
||||
#define CMM_DEBUG 0
|
||||
#define CMM_DISABLE 0
|
||||
#define CMM_OOM_KB 1024
|
||||
#define CMM_MIN_MEM_MB 256
|
||||
#define KB2PAGES(_p) ((_p)>>(PAGE_SHIFT-10))
|
||||
#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
|
||||
/*
|
||||
* The priority level tries to ensure that this notifier is called as
|
||||
* late as possible to reduce thrashing in the shared memory pool.
|
||||
*/
|
||||
#define CMM_MEM_HOTPLUG_PRI 1
|
||||
#define CMM_MEM_ISOLATE_PRI 15
|
||||
|
||||
static unsigned int delay = CMM_DEFAULT_DELAY;
|
||||
static unsigned int hotplug_delay = CMM_HOTPLUG_DELAY;
|
||||
static unsigned int oom_kb = CMM_OOM_KB;
|
||||
static unsigned int cmm_debug = CMM_DEBUG;
|
||||
static unsigned int cmm_disabled = CMM_DISABLE;
|
||||
@ -65,6 +74,10 @@ MODULE_VERSION(CMM_DRIVER_VERSION);
|
||||
module_param_named(delay, delay, uint, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(delay, "Delay (in seconds) between polls to query hypervisor paging requests. "
|
||||
"[Default=" __stringify(CMM_DEFAULT_DELAY) "]");
|
||||
module_param_named(hotplug_delay, hotplug_delay, uint, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(delay, "Delay (in seconds) after memory hotplug remove "
|
||||
"before loaning resumes. "
|
||||
"[Default=" __stringify(CMM_HOTPLUG_DELAY) "]");
|
||||
module_param_named(oom_kb, oom_kb, uint, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(oom_kb, "Amount of memory in kb to free on OOM. "
|
||||
"[Default=" __stringify(CMM_OOM_KB) "]");
|
||||
@ -92,6 +105,9 @@ static unsigned long oom_freed_pages;
|
||||
static struct cmm_page_array *cmm_page_list;
|
||||
static DEFINE_SPINLOCK(cmm_lock);
|
||||
|
||||
static DEFINE_MUTEX(hotplug_mutex);
|
||||
static int hotplug_occurred; /* protected by the hotplug mutex */
|
||||
|
||||
static struct task_struct *cmm_thread_ptr;
|
||||
|
||||
/**
|
||||
@ -110,6 +126,17 @@ static long cmm_alloc_pages(long nr)
|
||||
cmm_dbg("Begin request for %ld pages\n", nr);
|
||||
|
||||
while (nr) {
|
||||
/* Exit if a hotplug operation is in progress or occurred */
|
||||
if (mutex_trylock(&hotplug_mutex)) {
|
||||
if (hotplug_occurred) {
|
||||
mutex_unlock(&hotplug_mutex);
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&hotplug_mutex);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
addr = __get_free_page(GFP_NOIO | __GFP_NOWARN |
|
||||
__GFP_NORETRY | __GFP_NOMEMALLOC);
|
||||
if (!addr)
|
||||
@ -119,8 +146,9 @@ static long cmm_alloc_pages(long nr)
|
||||
if (!pa || pa->index >= CMM_NR_PAGES) {
|
||||
/* Need a new page for the page list. */
|
||||
spin_unlock(&cmm_lock);
|
||||
npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN |
|
||||
__GFP_NORETRY | __GFP_NOMEMALLOC);
|
||||
npa = (struct cmm_page_array *)__get_free_page(
|
||||
GFP_NOIO | __GFP_NOWARN |
|
||||
__GFP_NORETRY | __GFP_NOMEMALLOC);
|
||||
if (!npa) {
|
||||
pr_info("%s: Can not allocate new page list\n", __func__);
|
||||
free_page(addr);
|
||||
@ -282,9 +310,28 @@ static int cmm_thread(void *dummy)
|
||||
while (1) {
|
||||
timeleft = msleep_interruptible(delay * 1000);
|
||||
|
||||
if (kthread_should_stop() || timeleft) {
|
||||
loaned_pages_target = loaned_pages;
|
||||
if (kthread_should_stop() || timeleft)
|
||||
break;
|
||||
|
||||
if (mutex_trylock(&hotplug_mutex)) {
|
||||
if (hotplug_occurred) {
|
||||
hotplug_occurred = 0;
|
||||
mutex_unlock(&hotplug_mutex);
|
||||
cmm_dbg("Hotplug operation has occurred, "
|
||||
"loaning activity suspended "
|
||||
"for %d seconds.\n",
|
||||
hotplug_delay);
|
||||
timeleft = msleep_interruptible(hotplug_delay *
|
||||
1000);
|
||||
if (kthread_should_stop() || timeleft)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
mutex_unlock(&hotplug_mutex);
|
||||
} else {
|
||||
cmm_dbg("Hotplug operation in progress, activity "
|
||||
"suspended\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
cmm_get_mpp();
|
||||
@ -413,6 +460,193 @@ static struct notifier_block cmm_reboot_nb = {
|
||||
.notifier_call = cmm_reboot_notifier,
|
||||
};
|
||||
|
||||
/**
|
||||
* cmm_count_pages - Count the number of pages loaned in a particular range.
|
||||
*
|
||||
* @arg: memory_isolate_notify structure with address range and count
|
||||
*
|
||||
* Return value:
|
||||
* 0 on success
|
||||
**/
|
||||
static unsigned long cmm_count_pages(void *arg)
|
||||
{
|
||||
struct memory_isolate_notify *marg = arg;
|
||||
struct cmm_page_array *pa;
|
||||
unsigned long start = (unsigned long)pfn_to_kaddr(marg->start_pfn);
|
||||
unsigned long end = start + (marg->nr_pages << PAGE_SHIFT);
|
||||
unsigned long idx;
|
||||
|
||||
spin_lock(&cmm_lock);
|
||||
pa = cmm_page_list;
|
||||
while (pa) {
|
||||
if ((unsigned long)pa >= start && (unsigned long)pa < end)
|
||||
marg->pages_found++;
|
||||
for (idx = 0; idx < pa->index; idx++)
|
||||
if (pa->page[idx] >= start && pa->page[idx] < end)
|
||||
marg->pages_found++;
|
||||
pa = pa->next;
|
||||
}
|
||||
spin_unlock(&cmm_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cmm_memory_isolate_cb - Handle memory isolation notifier calls
|
||||
* @self: notifier block struct
|
||||
* @action: action to take
|
||||
* @arg: struct memory_isolate_notify data for handler
|
||||
*
|
||||
* Return value:
|
||||
* NOTIFY_OK or notifier error based on subfunction return value
|
||||
**/
|
||||
static int cmm_memory_isolate_cb(struct notifier_block *self,
|
||||
unsigned long action, void *arg)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (action == MEM_ISOLATE_COUNT)
|
||||
ret = cmm_count_pages(arg);
|
||||
|
||||
if (ret)
|
||||
ret = notifier_from_errno(ret);
|
||||
else
|
||||
ret = NOTIFY_OK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct notifier_block cmm_mem_isolate_nb = {
|
||||
.notifier_call = cmm_memory_isolate_cb,
|
||||
.priority = CMM_MEM_ISOLATE_PRI
|
||||
};
|
||||
|
||||
/**
|
||||
* cmm_mem_going_offline - Unloan pages where memory is to be removed
|
||||
* @arg: memory_notify structure with page range to be offlined
|
||||
*
|
||||
* Return value:
|
||||
* 0 on success
|
||||
**/
|
||||
static int cmm_mem_going_offline(void *arg)
|
||||
{
|
||||
struct memory_notify *marg = arg;
|
||||
unsigned long start_page = (unsigned long)pfn_to_kaddr(marg->start_pfn);
|
||||
unsigned long end_page = start_page + (marg->nr_pages << PAGE_SHIFT);
|
||||
struct cmm_page_array *pa_curr, *pa_last, *npa;
|
||||
unsigned long idx;
|
||||
unsigned long freed = 0;
|
||||
|
||||
cmm_dbg("Memory going offline, searching 0x%lx (%ld pages).\n",
|
||||
start_page, marg->nr_pages);
|
||||
spin_lock(&cmm_lock);
|
||||
|
||||
/* Search the page list for pages in the range to be offlined */
|
||||
pa_last = pa_curr = cmm_page_list;
|
||||
while (pa_curr) {
|
||||
for (idx = (pa_curr->index - 1); (idx + 1) > 0; idx--) {
|
||||
if ((pa_curr->page[idx] < start_page) ||
|
||||
(pa_curr->page[idx] >= end_page))
|
||||
continue;
|
||||
|
||||
plpar_page_set_active(__pa(pa_curr->page[idx]));
|
||||
free_page(pa_curr->page[idx]);
|
||||
freed++;
|
||||
loaned_pages--;
|
||||
totalram_pages++;
|
||||
pa_curr->page[idx] = pa_last->page[--pa_last->index];
|
||||
if (pa_last->index == 0) {
|
||||
if (pa_curr == pa_last)
|
||||
pa_curr = pa_last->next;
|
||||
pa_last = pa_last->next;
|
||||
free_page((unsigned long)cmm_page_list);
|
||||
cmm_page_list = pa_last;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pa_curr = pa_curr->next;
|
||||
}
|
||||
|
||||
/* Search for page list structures in the range to be offlined */
|
||||
pa_last = NULL;
|
||||
pa_curr = cmm_page_list;
|
||||
while (pa_curr) {
|
||||
if (((unsigned long)pa_curr >= start_page) &&
|
||||
((unsigned long)pa_curr < end_page)) {
|
||||
npa = (struct cmm_page_array *)__get_free_page(
|
||||
GFP_NOIO | __GFP_NOWARN |
|
||||
__GFP_NORETRY | __GFP_NOMEMALLOC);
|
||||
if (!npa) {
|
||||
spin_unlock(&cmm_lock);
|
||||
cmm_dbg("Failed to allocate memory for list "
|
||||
"management. Memory hotplug "
|
||||
"failed.\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy(npa, pa_curr, PAGE_SIZE);
|
||||
if (pa_curr == cmm_page_list)
|
||||
cmm_page_list = npa;
|
||||
if (pa_last)
|
||||
pa_last->next = npa;
|
||||
free_page((unsigned long) pa_curr);
|
||||
freed++;
|
||||
pa_curr = npa;
|
||||
}
|
||||
|
||||
pa_last = pa_curr;
|
||||
pa_curr = pa_curr->next;
|
||||
}
|
||||
|
||||
spin_unlock(&cmm_lock);
|
||||
cmm_dbg("Released %ld pages in the search range.\n", freed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cmm_memory_cb - Handle memory hotplug notifier calls
|
||||
* @self: notifier block struct
|
||||
* @action: action to take
|
||||
* @arg: struct memory_notify data for handler
|
||||
*
|
||||
* Return value:
|
||||
* NOTIFY_OK or notifier error based on subfunction return value
|
||||
*
|
||||
**/
|
||||
static int cmm_memory_cb(struct notifier_block *self,
|
||||
unsigned long action, void *arg)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (action) {
|
||||
case MEM_GOING_OFFLINE:
|
||||
mutex_lock(&hotplug_mutex);
|
||||
hotplug_occurred = 1;
|
||||
ret = cmm_mem_going_offline(arg);
|
||||
break;
|
||||
case MEM_OFFLINE:
|
||||
case MEM_CANCEL_OFFLINE:
|
||||
mutex_unlock(&hotplug_mutex);
|
||||
cmm_dbg("Memory offline operation complete.\n");
|
||||
break;
|
||||
case MEM_GOING_ONLINE:
|
||||
case MEM_ONLINE:
|
||||
case MEM_CANCEL_ONLINE:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
ret = notifier_from_errno(ret);
|
||||
else
|
||||
ret = NOTIFY_OK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct notifier_block cmm_mem_nb = {
|
||||
.notifier_call = cmm_memory_cb,
|
||||
.priority = CMM_MEM_HOTPLUG_PRI
|
||||
};
|
||||
|
||||
/**
|
||||
* cmm_init - Module initialization
|
||||
*
|
||||
@ -435,18 +669,24 @@ static int cmm_init(void)
|
||||
if ((rc = cmm_sysfs_register(&cmm_sysdev)))
|
||||
goto out_reboot_notifier;
|
||||
|
||||
if (register_memory_notifier(&cmm_mem_nb) ||
|
||||
register_memory_isolate_notifier(&cmm_mem_isolate_nb))
|
||||
goto out_unregister_notifier;
|
||||
|
||||
if (cmm_disabled)
|
||||
return rc;
|
||||
|
||||
cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
|
||||
if (IS_ERR(cmm_thread_ptr)) {
|
||||
rc = PTR_ERR(cmm_thread_ptr);
|
||||
goto out_unregister_sysfs;
|
||||
goto out_unregister_notifier;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
out_unregister_sysfs:
|
||||
out_unregister_notifier:
|
||||
unregister_memory_notifier(&cmm_mem_nb);
|
||||
unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
|
||||
cmm_unregister_sysfs(&cmm_sysdev);
|
||||
out_reboot_notifier:
|
||||
unregister_reboot_notifier(&cmm_reboot_nb);
|
||||
@ -467,6 +707,8 @@ static void cmm_exit(void)
|
||||
kthread_stop(cmm_thread_ptr);
|
||||
unregister_oom_notifier(&cmm_oom_nb);
|
||||
unregister_reboot_notifier(&cmm_reboot_nb);
|
||||
unregister_memory_notifier(&cmm_mem_nb);
|
||||
unregister_memory_isolate_notifier(&cmm_mem_isolate_nb);
|
||||
cmm_free_pages(loaned_pages);
|
||||
cmm_unregister_sysfs(&cmm_sysdev);
|
||||
}
|
||||
|
@ -346,12 +346,14 @@ int dlpar_release_drc(u32 drc_index)
|
||||
|
||||
static DEFINE_MUTEX(pseries_cpu_hotplug_mutex);
|
||||
|
||||
void cpu_hotplug_driver_lock()
|
||||
void cpu_hotplug_driver_lock(void)
|
||||
__acquires(pseries_cpu_hotplug_mutex)
|
||||
{
|
||||
mutex_lock(&pseries_cpu_hotplug_mutex);
|
||||
}
|
||||
|
||||
void cpu_hotplug_driver_unlock()
|
||||
void cpu_hotplug_driver_unlock(void)
|
||||
__releases(pseries_cpu_hotplug_mutex)
|
||||
{
|
||||
mutex_unlock(&pseries_cpu_hotplug_mutex);
|
||||
}
|
||||
|
@ -144,8 +144,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr)
|
||||
hcpuid = get_hard_smp_processor_id(nr);
|
||||
rc = plpar_hcall_norets(H_PROD, hcpuid);
|
||||
if (rc != H_SUCCESS)
|
||||
panic("Error: Prod to wake up processor %d Ret= %ld\n",
|
||||
nr, rc);
|
||||
printk(KERN_ERR "Error: Prod to wake up processor %d\
|
||||
Ret= %ld\n", nr, rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,13 +143,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
|
||||
struct irq_desc *desc = irq_to_desc(virq);
|
||||
unsigned int vold, vnew, edibit;
|
||||
|
||||
if (flow_type == IRQ_TYPE_NONE)
|
||||
flow_type = IRQ_TYPE_LEVEL_LOW;
|
||||
/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
|
||||
* IRQ_TYPE_EDGE_BOTH (default). All others are IRQ_TYPE_EDGE_FALLING
|
||||
* or IRQ_TYPE_LEVEL_LOW (default)
|
||||
*/
|
||||
if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) {
|
||||
if (flow_type == IRQ_TYPE_NONE)
|
||||
flow_type = IRQ_TYPE_EDGE_BOTH;
|
||||
|
||||
if (flow_type & IRQ_TYPE_EDGE_RISING) {
|
||||
printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n",
|
||||
flow_type);
|
||||
return -EINVAL;
|
||||
if (flow_type != IRQ_TYPE_EDGE_BOTH &&
|
||||
flow_type != IRQ_TYPE_EDGE_FALLING)
|
||||
goto err_sense;
|
||||
} else {
|
||||
if (flow_type == IRQ_TYPE_NONE)
|
||||
flow_type = IRQ_TYPE_LEVEL_LOW;
|
||||
|
||||
if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
|
||||
goto err_sense;
|
||||
}
|
||||
|
||||
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
|
||||
@ -181,6 +191,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
|
||||
if (vold != vnew)
|
||||
out_be32(&cpm2_intctl->ic_siexr, vnew);
|
||||
return 0;
|
||||
|
||||
err_sense:
|
||||
pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct irq_chip cpm2_pic = {
|
||||
|
@ -464,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(bus);
|
||||
struct mpc83xx_pcie_priv *pcie = hose->dn->data;
|
||||
u8 bus_no = bus->number - hose->first_busno;
|
||||
u32 dev_base = bus_no << 24 | devfn << 16;
|
||||
u32 dev_base = bus->number << 24 | devfn << 16;
|
||||
int ret;
|
||||
|
||||
ret = mpc83xx_pcie_exclude_device(bus, devfn);
|
||||
@ -515,12 +514,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 val)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(bus);
|
||||
void __iomem *cfg_addr;
|
||||
|
||||
cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
|
||||
if (!cfg_addr)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
/* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
|
||||
if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
|
||||
val &= 0xffffff00;
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
out_8(cfg_addr, val);
|
||||
|
@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
|
||||
mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
|
||||
}
|
||||
|
||||
/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
|
||||
* defined as output cannot be determined by reading GPDAT register,
|
||||
* so we use shadow data register instead. The status of input pins
|
||||
* is determined by reading GPDAT register.
|
||||
*/
|
||||
static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
u32 val;
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
|
||||
|
||||
val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
|
||||
|
||||
return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
|
||||
gc->ngpio = MPC8XXX_GPIO_PINS;
|
||||
gc->direction_input = mpc8xxx_gpio_dir_in;
|
||||
gc->direction_output = mpc8xxx_gpio_dir_out;
|
||||
gc->get = mpc8xxx_gpio_get;
|
||||
if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
|
||||
gc->get = mpc8572_gpio_get;
|
||||
else
|
||||
gc->get = mpc8xxx_gpio_get;
|
||||
gc->set = mpc8xxx_gpio_set;
|
||||
|
||||
ret = of_mm_gpiochip_add(np, mm_gc);
|
||||
|
@ -567,13 +567,11 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
|
||||
#endif /* CONFIG_MPIC_U3_HT_IRQS */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int irq_choose_cpu(unsigned int virt_irq)
|
||||
static int irq_choose_cpu(const cpumask_t *mask)
|
||||
{
|
||||
cpumask_t mask;
|
||||
int cpuid;
|
||||
|
||||
cpumask_copy(&mask, irq_to_desc(virt_irq)->affinity);
|
||||
if (cpus_equal(mask, CPU_MASK_ALL)) {
|
||||
if (cpumask_equal(mask, cpu_all_mask)) {
|
||||
static int irq_rover;
|
||||
static DEFINE_SPINLOCK(irq_rover_lock);
|
||||
unsigned long flags;
|
||||
@ -594,20 +592,15 @@ static int irq_choose_cpu(unsigned int virt_irq)
|
||||
|
||||
spin_unlock_irqrestore(&irq_rover_lock, flags);
|
||||
} else {
|
||||
cpumask_t tmp;
|
||||
|
||||
cpus_and(tmp, cpu_online_map, mask);
|
||||
|
||||
if (cpus_empty(tmp))
|
||||
cpuid = cpumask_first_and(mask, cpu_online_mask);
|
||||
if (cpuid >= nr_cpu_ids)
|
||||
goto do_round_robin;
|
||||
|
||||
cpuid = first_cpu(tmp);
|
||||
}
|
||||
|
||||
return get_hard_smp_processor_id(cpuid);
|
||||
}
|
||||
#else
|
||||
static int irq_choose_cpu(unsigned int virt_irq)
|
||||
static int irq_choose_cpu(const cpumask_t *mask)
|
||||
{
|
||||
return hard_smp_processor_id();
|
||||
}
|
||||
@ -816,7 +809,7 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
||||
unsigned int src = mpic_irq_to_hw(irq);
|
||||
|
||||
if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
|
||||
int cpuid = irq_choose_cpu(irq);
|
||||
int cpuid = irq_choose_cpu(cpumask);
|
||||
|
||||
mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
|
||||
} else {
|
||||
|
@ -39,7 +39,12 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
|
||||
|
||||
pr_debug("mpic: found U3, guessing msi allocator setup\n");
|
||||
|
||||
/* Reserve source numbers we know are reserved in the HW */
|
||||
/* Reserve source numbers we know are reserved in the HW.
|
||||
*
|
||||
* This is a bit of a mix of U3 and U4 reserves but that's going
|
||||
* to work fine, we have plenty enugh numbers left so let's just
|
||||
* mark anything we don't like reserved.
|
||||
*/
|
||||
for (i = 0; i < 8; i++)
|
||||
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
|
||||
|
||||
@ -49,6 +54,10 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
|
||||
for (i = 100; i < 105; i++)
|
||||
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
|
||||
|
||||
for (i = 124; i < mpic->irq_count; i++)
|
||||
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
|
||||
|
||||
|
||||
np = NULL;
|
||||
while ((np = of_find_all_nodes(np))) {
|
||||
pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
|
||||
|
@ -64,12 +64,12 @@ static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
|
||||
return addr;
|
||||
}
|
||||
|
||||
static u64 find_ht_magic_addr(struct pci_dev *pdev)
|
||||
static u64 find_ht_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
|
||||
{
|
||||
struct pci_bus *bus;
|
||||
unsigned int pos;
|
||||
|
||||
for (bus = pdev->bus; bus; bus = bus->parent) {
|
||||
for (bus = pdev->bus; bus && bus->self; bus = bus->parent) {
|
||||
pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING);
|
||||
if (pos)
|
||||
return read_ht_magic_addr(bus->self, pos);
|
||||
@ -78,13 +78,41 @@ static u64 find_ht_magic_addr(struct pci_dev *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
|
||||
{
|
||||
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
|
||||
|
||||
/* U4 PCIe MSIs need to write to the special register in
|
||||
* the bridge that generates interrupts. There should be
|
||||
* theorically a register at 0xf8005000 where you just write
|
||||
* the MSI number and that triggers the right interrupt, but
|
||||
* unfortunately, this is busted in HW, the bridge endian swaps
|
||||
* the value and hits the wrong nibble in the register.
|
||||
*
|
||||
* So instead we use another register set which is used normally
|
||||
* for converting HT interrupts to MPIC interrupts, which decodes
|
||||
* the interrupt number as part of the low address bits
|
||||
*
|
||||
* This will not work if we ever use more than one legacy MSI in
|
||||
* a block but we never do. For one MSI or multiple MSI-X where
|
||||
* each interrupt address can be specified separately, it works
|
||||
* just fine.
|
||||
*/
|
||||
if (of_device_is_compatible(hose->dn, "u4-pcie") ||
|
||||
of_device_is_compatible(hose->dn, "U4-pcie"))
|
||||
return 0xf8004000 | (hwirq << 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
|
||||
{
|
||||
if (type == PCI_CAP_ID_MSIX)
|
||||
pr_debug("u3msi: MSI-X untested, trying anyway.\n");
|
||||
|
||||
/* If we can't find a magic address then MSI ain't gonna work */
|
||||
if (find_ht_magic_addr(pdev) == 0) {
|
||||
if (find_ht_magic_addr(pdev, 0) == 0 &&
|
||||
find_u4_magic_addr(pdev, 0) == 0) {
|
||||
pr_debug("u3msi: no magic address found for %s\n",
|
||||
pci_name(pdev));
|
||||
return -ENXIO;
|
||||
@ -118,10 +146,6 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||
u64 addr;
|
||||
int hwirq;
|
||||
|
||||
addr = find_ht_magic_addr(pdev);
|
||||
msg.address_lo = addr & 0xFFFFFFFF;
|
||||
msg.address_hi = addr >> 32;
|
||||
|
||||
list_for_each_entry(entry, &pdev->msi_list, list) {
|
||||
hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
|
||||
if (hwirq < 0) {
|
||||
@ -129,6 +153,12 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||
return hwirq;
|
||||
}
|
||||
|
||||
addr = find_ht_magic_addr(pdev, hwirq);
|
||||
if (addr == 0)
|
||||
addr = find_u4_magic_addr(pdev, hwirq);
|
||||
msg.address_lo = addr & 0xFFFFFFFF;
|
||||
msg.address_hi = addr >> 32;
|
||||
|
||||
virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
|
||||
if (virq == NO_IRQ) {
|
||||
pr_debug("u3msi: failed mapping hwirq 0x%x\n", hwirq);
|
||||
@ -143,6 +173,8 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||
pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
|
||||
virq, hwirq, (unsigned long)addr);
|
||||
|
||||
printk("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
|
||||
virq, hwirq, (unsigned long)addr);
|
||||
msg.data = hwirq;
|
||||
write_msi_msg(virq, &msg);
|
||||
|
||||
|
@ -128,8 +128,6 @@ static struct platform_device nor_flash_device = {
|
||||
|
||||
/* SH Eth */
|
||||
#define SH_ETH_ADDR (0xA4600000)
|
||||
#define SH_ETH_MAHR (SH_ETH_ADDR + 0x1C0)
|
||||
#define SH_ETH_MALR (SH_ETH_ADDR + 0x1C8)
|
||||
static struct resource sh_eth_resources[] = {
|
||||
[0] = {
|
||||
.start = SH_ETH_ADDR,
|
||||
@ -509,6 +507,7 @@ static struct platform_device sdhi1_device = {
|
||||
|
||||
#else
|
||||
|
||||
/* MMC SPI */
|
||||
static int mmc_spi_get_ro(struct device *dev)
|
||||
{
|
||||
return gpio_get_value(GPIO_PTY6);
|
||||
@ -542,6 +541,7 @@ static struct spi_board_info spi_bus[] = {
|
||||
},
|
||||
};
|
||||
|
||||
/* MSIOF0 */
|
||||
static struct sh_msiof_spi_info msiof0_data = {
|
||||
.num_chipselect = 1,
|
||||
};
|
||||
|
@ -133,12 +133,8 @@ void __update_cache(struct vm_area_struct *vma,
|
||||
page = pfn_to_page(pfn);
|
||||
if (pfn_valid(pfn)) {
|
||||
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
|
||||
if (dirty) {
|
||||
unsigned long addr = (unsigned long)page_address(page);
|
||||
|
||||
if (pages_do_alias(addr, address & PAGE_MASK))
|
||||
__flush_purge_region((void *)addr, PAGE_SIZE);
|
||||
}
|
||||
if (dirty)
|
||||
__flush_purge_region(page_address(page), PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,7 @@ static enum ucode_state microcode_update_cpu(int cpu)
|
||||
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
||||
enum ucode_state ustate;
|
||||
|
||||
if (uci->valid && uci->mc)
|
||||
if (uci->valid)
|
||||
ustate = microcode_resume_cpu(cpu);
|
||||
else
|
||||
ustate = microcode_init_cpu(cpu);
|
||||
|
@ -1557,6 +1557,25 @@ static unsigned short atapi_io_port[] = {
|
||||
P_ATAPI_DMARQ,
|
||||
P_ATAPI_INTRQ,
|
||||
P_ATAPI_IORDY,
|
||||
P_ATAPI_D0A,
|
||||
P_ATAPI_D1A,
|
||||
P_ATAPI_D2A,
|
||||
P_ATAPI_D3A,
|
||||
P_ATAPI_D4A,
|
||||
P_ATAPI_D5A,
|
||||
P_ATAPI_D6A,
|
||||
P_ATAPI_D7A,
|
||||
P_ATAPI_D8A,
|
||||
P_ATAPI_D9A,
|
||||
P_ATAPI_D10A,
|
||||
P_ATAPI_D11A,
|
||||
P_ATAPI_D12A,
|
||||
P_ATAPI_D13A,
|
||||
P_ATAPI_D14A,
|
||||
P_ATAPI_D15A,
|
||||
P_ATAPI_A0A,
|
||||
P_ATAPI_A1A,
|
||||
P_ATAPI_A2A,
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_cmd64x"
|
||||
#define DRV_VERSION "0.3.1"
|
||||
#define DRV_VERSION "0.2.5"
|
||||
|
||||
/*
|
||||
* CMD64x specific registers definition.
|
||||
@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
|
||||
/* Merge the control bits */
|
||||
regU |= 1 << adev->devno; /* UDMA on */
|
||||
if (adev->dma_mode > 2) /* 15nS timing */
|
||||
if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */
|
||||
regU |= 4 << adev->devno;
|
||||
} else {
|
||||
regU &= ~ (1 << adev->devno); /* UDMA off */
|
||||
@ -254,109 +254,17 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
}
|
||||
|
||||
/**
|
||||
* cmd64x_bmdma_stop - DMA stop callback
|
||||
* cmd646r1_dma_stop - DMA stop callback
|
||||
* @qc: Command in progress
|
||||
*
|
||||
* Track the completion of live DMA commands and clear the
|
||||
* host->private_data DMA tracking flag as we do.
|
||||
* Stub for now while investigating the r1 quirk in the old driver.
|
||||
*/
|
||||
|
||||
static void cmd64x_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
ata_bmdma_stop(qc);
|
||||
WARN_ON(ap->host->private_data != ap);
|
||||
ap->host->private_data = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* cmd64x_qc_defer - Defer logic for chip limits
|
||||
* @qc: queued command
|
||||
*
|
||||
* Decide whether we can issue the command. Called under the host lock.
|
||||
*/
|
||||
|
||||
static int cmd64x_qc_defer(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_host *host = qc->ap->host;
|
||||
struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
|
||||
int rc;
|
||||
int dma = 0;
|
||||
|
||||
/* Apply the ATA rules first */
|
||||
rc = ata_std_qc_defer(qc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (qc->tf.protocol == ATAPI_PROT_DMA ||
|
||||
qc->tf.protocol == ATA_PROT_DMA)
|
||||
dma = 1;
|
||||
|
||||
/* If the other port is not live then issue the command */
|
||||
if (alt == NULL || !alt->qc_active) {
|
||||
if (dma)
|
||||
host->private_data = qc->ap;
|
||||
return 0;
|
||||
}
|
||||
/* If there is a live DMA command then wait */
|
||||
if (host->private_data != NULL)
|
||||
return ATA_DEFER_PORT;
|
||||
if (dma)
|
||||
/* Cannot overlap our DMA command */
|
||||
return ATA_DEFER_PORT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cmd64x_interrupt - ATA host interrupt handler
|
||||
* @irq: irq line (unused)
|
||||
* @dev_instance: pointer to our ata_host information structure
|
||||
*
|
||||
* Our interrupt handler for PCI IDE devices. Calls
|
||||
* ata_sff_host_intr() for each port that is flagging an IRQ. We cannot
|
||||
* use the defaults as we need to avoid touching status/altstatus during
|
||||
* a DMA.
|
||||
*
|
||||
* LOCKING:
|
||||
* Obtains host lock during operation.
|
||||
*
|
||||
* RETURNS:
|
||||
* IRQ_NONE or IRQ_HANDLED.
|
||||
*/
|
||||
irqreturn_t cmd64x_interrupt(int irq, void *dev_instance)
|
||||
{
|
||||
struct ata_host *host = dev_instance;
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
unsigned int i;
|
||||
unsigned int handled = 0;
|
||||
unsigned long flags;
|
||||
static const u8 irq_reg[2] = { CFR, ARTTIM23 };
|
||||
static const u8 irq_mask[2] = { 1 << 2, 1 << 4 };
|
||||
|
||||
/* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap;
|
||||
u8 reg;
|
||||
|
||||
pci_read_config_byte(pdev, irq_reg[i], ®);
|
||||
ap = host->ports[i];
|
||||
if (ap && (reg & irq_mask[i]) &&
|
||||
!(ap->flags & ATA_FLAG_DISABLED)) {
|
||||
struct ata_queued_cmd *qc;
|
||||
|
||||
qc = ata_qc_from_tag(ap, ap->link.active_tag);
|
||||
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
|
||||
(qc->flags & ATA_QCFLAG_ACTIVE))
|
||||
handled |= ata_sff_host_intr(ap, qc);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
static struct scsi_host_template cmd64x_sht = {
|
||||
ATA_BMDMA_SHT(DRV_NAME),
|
||||
};
|
||||
@ -365,8 +273,6 @@ static const struct ata_port_operations cmd64x_base_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.set_piomode = cmd64x_set_piomode,
|
||||
.set_dmamode = cmd64x_set_dmamode,
|
||||
.bmdma_stop = cmd64x_bmdma_stop,
|
||||
.qc_defer = cmd64x_qc_defer,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cmd64x_port_ops = {
|
||||
@ -376,6 +282,7 @@ static struct ata_port_operations cmd64x_port_ops = {
|
||||
|
||||
static struct ata_port_operations cmd646r1_port_ops = {
|
||||
.inherits = &cmd64x_base_ops,
|
||||
.bmdma_stop = cmd646r1_bmdma_stop,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
};
|
||||
|
||||
@ -383,7 +290,6 @@ static struct ata_port_operations cmd648_port_ops = {
|
||||
.inherits = &cmd64x_base_ops,
|
||||
.bmdma_stop = cmd648_bmdma_stop,
|
||||
.cable_detect = cmd648_cable_detect,
|
||||
.qc_defer = ata_std_qc_defer
|
||||
};
|
||||
|
||||
static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
@ -432,7 +338,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
|
||||
u8 mrdmode;
|
||||
int rc;
|
||||
struct ata_host *host;
|
||||
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
@ -450,25 +355,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
ppi[0] = &cmd_info[3];
|
||||
}
|
||||
|
||||
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
|
||||
pci_read_config_byte(pdev, MRDMODE, &mrdmode);
|
||||
mrdmode &= ~ 0x30; /* IRQ set up */
|
||||
mrdmode |= 0x02; /* Memory read line enable */
|
||||
pci_write_config_byte(pdev, MRDMODE, mrdmode);
|
||||
|
||||
/* Force PIO 0 here.. */
|
||||
|
||||
/* PPC specific fixup copied from old driver */
|
||||
#ifdef CONFIG_PPC
|
||||
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
|
||||
#endif
|
||||
rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
|
||||
if (rc)
|
||||
return rc;
|
||||
/* We use this pointer to track the AP which has DMA running */
|
||||
host->private_data = NULL;
|
||||
|
||||
pci_set_master(pdev);
|
||||
return ata_pci_sff_activate_host(host, cmd64x_interrupt, &cmd64x_sht);
|
||||
return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -703,9 +703,9 @@ int bus_add_driver(struct device_driver *drv)
|
||||
return 0;
|
||||
|
||||
out_unregister:
|
||||
kobject_put(&priv->kobj);
|
||||
kfree(drv->p);
|
||||
drv->p = NULL;
|
||||
kobject_put(&priv->kobj);
|
||||
out_put_bus:
|
||||
bus_put(bus);
|
||||
return error;
|
||||
|
@ -446,7 +446,8 @@ struct kset *devices_kset;
|
||||
* @dev: device.
|
||||
* @attr: device attribute descriptor.
|
||||
*/
|
||||
int device_create_file(struct device *dev, struct device_attribute *attr)
|
||||
int device_create_file(struct device *dev,
|
||||
const struct device_attribute *attr)
|
||||
{
|
||||
int error = 0;
|
||||
if (dev)
|
||||
@ -459,7 +460,8 @@ int device_create_file(struct device *dev, struct device_attribute *attr)
|
||||
* @dev: device.
|
||||
* @attr: device attribute descriptor.
|
||||
*/
|
||||
void device_remove_file(struct device *dev, struct device_attribute *attr)
|
||||
void device_remove_file(struct device *dev,
|
||||
const struct device_attribute *attr)
|
||||
{
|
||||
if (dev)
|
||||
sysfs_remove_file(&dev->kobj, &attr->attr);
|
||||
@ -470,7 +472,8 @@ void device_remove_file(struct device *dev, struct device_attribute *attr)
|
||||
* @dev: device.
|
||||
* @attr: device binary attribute descriptor.
|
||||
*/
|
||||
int device_create_bin_file(struct device *dev, struct bin_attribute *attr)
|
||||
int device_create_bin_file(struct device *dev,
|
||||
const struct bin_attribute *attr)
|
||||
{
|
||||
int error = -EINVAL;
|
||||
if (dev)
|
||||
@ -484,7 +487,8 @@ EXPORT_SYMBOL_GPL(device_create_bin_file);
|
||||
* @dev: device.
|
||||
* @attr: device binary attribute descriptor.
|
||||
*/
|
||||
void device_remove_bin_file(struct device *dev, struct bin_attribute *attr)
|
||||
void device_remove_bin_file(struct device *dev,
|
||||
const struct bin_attribute *attr)
|
||||
{
|
||||
if (dev)
|
||||
sysfs_remove_bin_file(&dev->kobj, attr);
|
||||
@ -905,8 +909,10 @@ int device_add(struct device *dev)
|
||||
dev->init_name = NULL;
|
||||
}
|
||||
|
||||
if (!dev_name(dev))
|
||||
if (!dev_name(dev)) {
|
||||
error = -EINVAL;
|
||||
goto name_error;
|
||||
}
|
||||
|
||||
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
|
||||
|
||||
|
@ -32,7 +32,7 @@ static int dev_mount = 1;
|
||||
static int dev_mount;
|
||||
#endif
|
||||
|
||||
static rwlock_t dirlock;
|
||||
static DEFINE_MUTEX(dirlock);
|
||||
|
||||
static int __init mount_param(char *str)
|
||||
{
|
||||
@ -93,7 +93,7 @@ static int create_path(const char *nodepath)
|
||||
{
|
||||
int err;
|
||||
|
||||
read_lock(&dirlock);
|
||||
mutex_lock(&dirlock);
|
||||
err = dev_mkdir(nodepath, 0755);
|
||||
if (err == -ENOENT) {
|
||||
char *path;
|
||||
@ -101,8 +101,10 @@ static int create_path(const char *nodepath)
|
||||
|
||||
/* parent directories do not exist, create them */
|
||||
path = kstrdup(nodepath, GFP_KERNEL);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
if (!path) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
s = path;
|
||||
for (;;) {
|
||||
s = strchr(s, '/');
|
||||
@ -117,7 +119,8 @@ static int create_path(const char *nodepath)
|
||||
}
|
||||
kfree(path);
|
||||
}
|
||||
read_unlock(&dirlock);
|
||||
out:
|
||||
mutex_unlock(&dirlock);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -229,7 +232,7 @@ static int delete_path(const char *nodepath)
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
write_lock(&dirlock);
|
||||
mutex_lock(&dirlock);
|
||||
for (;;) {
|
||||
char *base;
|
||||
|
||||
@ -241,7 +244,7 @@ static int delete_path(const char *nodepath)
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
write_unlock(&dirlock);
|
||||
mutex_unlock(&dirlock);
|
||||
|
||||
kfree(path);
|
||||
return err;
|
||||
@ -352,8 +355,6 @@ int __init devtmpfs_init(void)
|
||||
int err;
|
||||
struct vfsmount *mnt;
|
||||
|
||||
rwlock_init(&dirlock);
|
||||
|
||||
err = register_filesystem(&dev_fs_type);
|
||||
if (err) {
|
||||
printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
|
||||
|
@ -98,7 +98,7 @@ EXPORT_SYMBOL_GPL(driver_find_device);
|
||||
* @attr: driver attribute descriptor.
|
||||
*/
|
||||
int driver_create_file(struct device_driver *drv,
|
||||
struct driver_attribute *attr)
|
||||
const struct driver_attribute *attr)
|
||||
{
|
||||
int error;
|
||||
if (drv)
|
||||
@ -115,7 +115,7 @@ EXPORT_SYMBOL_GPL(driver_create_file);
|
||||
* @attr: driver attribute descriptor.
|
||||
*/
|
||||
void driver_remove_file(struct device_driver *drv,
|
||||
struct driver_attribute *attr)
|
||||
const struct driver_attribute *attr)
|
||||
{
|
||||
if (drv)
|
||||
sysfs_remove_file(&drv->p->kobj, &attr->attr);
|
||||
|
@ -63,6 +63,20 @@ void unregister_memory_notifier(struct notifier_block *nb)
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_memory_notifier);
|
||||
|
||||
static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain);
|
||||
|
||||
int register_memory_isolate_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return atomic_notifier_chain_register(&memory_isolate_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL(register_memory_isolate_notifier);
|
||||
|
||||
void unregister_memory_isolate_notifier(struct notifier_block *nb)
|
||||
{
|
||||
atomic_notifier_chain_unregister(&memory_isolate_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_memory_isolate_notifier);
|
||||
|
||||
/*
|
||||
* register_memory - Setup a sysfs device for a memory block
|
||||
*/
|
||||
@ -157,6 +171,11 @@ int memory_notify(unsigned long val, void *v)
|
||||
return blocking_notifier_call_chain(&memory_chain, val, v);
|
||||
}
|
||||
|
||||
int memory_isolate_notify(unsigned long val, void *v)
|
||||
{
|
||||
return atomic_notifier_call_chain(&memory_isolate_chain, val, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
|
||||
* OK to have direct references to sparsemem variables in here.
|
||||
|
@ -441,6 +441,7 @@ error:
|
||||
platform_device_put(pdev);
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_device_register_data);
|
||||
|
||||
static int platform_drv_probe(struct device *_dev)
|
||||
{
|
||||
|
@ -161,6 +161,32 @@ void device_pm_move_last(struct device *dev)
|
||||
list_move_tail(&dev->power.entry, &dpm_list);
|
||||
}
|
||||
|
||||
static ktime_t initcall_debug_start(struct device *dev)
|
||||
{
|
||||
ktime_t calltime = ktime_set(0, 0);
|
||||
|
||||
if (initcall_debug) {
|
||||
pr_info("calling %s+ @ %i\n",
|
||||
dev_name(dev), task_pid_nr(current));
|
||||
calltime = ktime_get();
|
||||
}
|
||||
|
||||
return calltime;
|
||||
}
|
||||
|
||||
static void initcall_debug_report(struct device *dev, ktime_t calltime,
|
||||
int error)
|
||||
{
|
||||
ktime_t delta, rettime;
|
||||
|
||||
if (initcall_debug) {
|
||||
rettime = ktime_get();
|
||||
delta = ktime_sub(rettime, calltime);
|
||||
pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
|
||||
error, (unsigned long long)ktime_to_ns(delta) >> 10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_op - Execute the PM operation appropriate for given PM event.
|
||||
* @dev: Device to handle.
|
||||
@ -172,13 +198,9 @@ static int pm_op(struct device *dev,
|
||||
pm_message_t state)
|
||||
{
|
||||
int error = 0;
|
||||
ktime_t calltime, delta, rettime;
|
||||
ktime_t calltime;
|
||||
|
||||
if (initcall_debug) {
|
||||
pr_info("calling %s+ @ %i\n",
|
||||
dev_name(dev), task_pid_nr(current));
|
||||
calltime = ktime_get();
|
||||
}
|
||||
calltime = initcall_debug_start(dev);
|
||||
|
||||
switch (state.event) {
|
||||
#ifdef CONFIG_SUSPEND
|
||||
@ -227,12 +249,7 @@ static int pm_op(struct device *dev,
|
||||
error = -EINVAL;
|
||||
}
|
||||
|
||||
if (initcall_debug) {
|
||||
rettime = ktime_get();
|
||||
delta = ktime_sub(rettime, calltime);
|
||||
pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
|
||||
error, (unsigned long long)ktime_to_ns(delta) >> 10);
|
||||
}
|
||||
initcall_debug_report(dev, calltime, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -309,8 +326,9 @@ static int pm_noirq_op(struct device *dev,
|
||||
if (initcall_debug) {
|
||||
rettime = ktime_get();
|
||||
delta = ktime_sub(rettime, calltime);
|
||||
printk("initcall %s_i+ returned %d after %Ld usecs\n", dev_name(dev),
|
||||
error, (unsigned long long)ktime_to_ns(delta) >> 10);
|
||||
printk("initcall %s_i+ returned %d after %Ld usecs\n",
|
||||
dev_name(dev), error,
|
||||
(unsigned long long)ktime_to_ns(delta) >> 10);
|
||||
}
|
||||
|
||||
return error;
|
||||
@ -354,6 +372,23 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info,
|
||||
kobject_name(&dev->kobj), pm_verb(state.event), info, error);
|
||||
}
|
||||
|
||||
static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)
|
||||
{
|
||||
ktime_t calltime;
|
||||
s64 usecs64;
|
||||
int usecs;
|
||||
|
||||
calltime = ktime_get();
|
||||
usecs64 = ktime_to_ns(ktime_sub(calltime, starttime));
|
||||
do_div(usecs64, NSEC_PER_USEC);
|
||||
usecs = usecs64;
|
||||
if (usecs == 0)
|
||||
usecs = 1;
|
||||
pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n",
|
||||
info ?: "", info ? " " : "", pm_verb(state.event),
|
||||
usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
/*------------------------- Resume routines -------------------------*/
|
||||
|
||||
/**
|
||||
@ -390,6 +425,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
|
||||
void dpm_resume_noirq(pm_message_t state)
|
||||
{
|
||||
struct device *dev;
|
||||
ktime_t starttime = ktime_get();
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
transition_started = false;
|
||||
@ -403,10 +439,31 @@ void dpm_resume_noirq(pm_message_t state)
|
||||
pm_dev_err(dev, state, " early", error);
|
||||
}
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
dpm_show_time(starttime, state, "early");
|
||||
resume_device_irqs();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dpm_resume_noirq);
|
||||
|
||||
/**
|
||||
* legacy_resume - Execute a legacy (bus or class) resume callback for device.
|
||||
* dev: Device to resume.
|
||||
* cb: Resume callback to execute.
|
||||
*/
|
||||
static int legacy_resume(struct device *dev, int (*cb)(struct device *dev))
|
||||
{
|
||||
int error;
|
||||
ktime_t calltime;
|
||||
|
||||
calltime = initcall_debug_start(dev);
|
||||
|
||||
error = cb(dev);
|
||||
suspend_report_result(cb, error);
|
||||
|
||||
initcall_debug_report(dev, calltime, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* device_resume - Execute "resume" callbacks for given device.
|
||||
* @dev: Device to handle.
|
||||
@ -427,7 +484,7 @@ static int device_resume(struct device *dev, pm_message_t state)
|
||||
error = pm_op(dev, dev->bus->pm, state);
|
||||
} else if (dev->bus->resume) {
|
||||
pm_dev_dbg(dev, state, "legacy ");
|
||||
error = dev->bus->resume(dev);
|
||||
error = legacy_resume(dev, dev->bus->resume);
|
||||
}
|
||||
if (error)
|
||||
goto End;
|
||||
@ -448,7 +505,7 @@ static int device_resume(struct device *dev, pm_message_t state)
|
||||
error = pm_op(dev, dev->class->pm, state);
|
||||
} else if (dev->class->resume) {
|
||||
pm_dev_dbg(dev, state, "legacy class ");
|
||||
error = dev->class->resume(dev);
|
||||
error = legacy_resume(dev, dev->class->resume);
|
||||
}
|
||||
}
|
||||
End:
|
||||
@ -468,6 +525,7 @@ static int device_resume(struct device *dev, pm_message_t state)
|
||||
static void dpm_resume(pm_message_t state)
|
||||
{
|
||||
struct list_head list;
|
||||
ktime_t starttime = ktime_get();
|
||||
|
||||
INIT_LIST_HEAD(&list);
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
@ -496,6 +554,7 @@ static void dpm_resume(pm_message_t state)
|
||||
}
|
||||
list_splice(&list, &dpm_list);
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
dpm_show_time(starttime, state, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -548,7 +607,7 @@ static void dpm_complete(pm_message_t state)
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
|
||||
device_complete(dev, state);
|
||||
pm_runtime_put_noidle(dev);
|
||||
pm_runtime_put_sync(dev);
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
}
|
||||
@ -628,6 +687,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
|
||||
int dpm_suspend_noirq(pm_message_t state)
|
||||
{
|
||||
struct device *dev;
|
||||
ktime_t starttime = ktime_get();
|
||||
int error = 0;
|
||||
|
||||
suspend_device_irqs();
|
||||
@ -643,10 +703,33 @@ int dpm_suspend_noirq(pm_message_t state)
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
if (error)
|
||||
dpm_resume_noirq(resume_event(state));
|
||||
else
|
||||
dpm_show_time(starttime, state, "late");
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
|
||||
|
||||
/**
|
||||
* legacy_suspend - Execute a legacy (bus or class) suspend callback for device.
|
||||
* dev: Device to suspend.
|
||||
* cb: Suspend callback to execute.
|
||||
*/
|
||||
static int legacy_suspend(struct device *dev, pm_message_t state,
|
||||
int (*cb)(struct device *dev, pm_message_t state))
|
||||
{
|
||||
int error;
|
||||
ktime_t calltime;
|
||||
|
||||
calltime = initcall_debug_start(dev);
|
||||
|
||||
error = cb(dev, state);
|
||||
suspend_report_result(cb, error);
|
||||
|
||||
initcall_debug_report(dev, calltime, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* device_suspend - Execute "suspend" callbacks for given device.
|
||||
* @dev: Device to handle.
|
||||
@ -664,8 +747,7 @@ static int device_suspend(struct device *dev, pm_message_t state)
|
||||
error = pm_op(dev, dev->class->pm, state);
|
||||
} else if (dev->class->suspend) {
|
||||
pm_dev_dbg(dev, state, "legacy class ");
|
||||
error = dev->class->suspend(dev, state);
|
||||
suspend_report_result(dev->class->suspend, error);
|
||||
error = legacy_suspend(dev, state, dev->class->suspend);
|
||||
}
|
||||
if (error)
|
||||
goto End;
|
||||
@ -686,8 +768,7 @@ static int device_suspend(struct device *dev, pm_message_t state)
|
||||
error = pm_op(dev, dev->bus->pm, state);
|
||||
} else if (dev->bus->suspend) {
|
||||
pm_dev_dbg(dev, state, "legacy ");
|
||||
error = dev->bus->suspend(dev, state);
|
||||
suspend_report_result(dev->bus->suspend, error);
|
||||
error = legacy_suspend(dev, state, dev->bus->suspend);
|
||||
}
|
||||
}
|
||||
End:
|
||||
@ -703,6 +784,7 @@ static int device_suspend(struct device *dev, pm_message_t state)
|
||||
static int dpm_suspend(pm_message_t state)
|
||||
{
|
||||
struct list_head list;
|
||||
ktime_t starttime = ktime_get();
|
||||
int error = 0;
|
||||
|
||||
INIT_LIST_HEAD(&list);
|
||||
@ -728,6 +810,8 @@ static int dpm_suspend(pm_message_t state)
|
||||
}
|
||||
list_splice(&list, dpm_list.prev);
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
if (!error)
|
||||
dpm_show_time(starttime, state, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -796,7 +880,7 @@ static int dpm_prepare(pm_message_t state)
|
||||
pm_runtime_get_noresume(dev);
|
||||
if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) {
|
||||
/* Wake-up requested during system sleep transition. */
|
||||
pm_runtime_put_noidle(dev);
|
||||
pm_runtime_put_sync(dev);
|
||||
error = -EBUSY;
|
||||
} else {
|
||||
error = device_prepare(dev, state);
|
||||
|
@ -84,6 +84,19 @@ static int __pm_runtime_idle(struct device *dev)
|
||||
|
||||
dev->bus->pm->runtime_idle(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
} else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) {
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
||||
dev->type->pm->runtime_idle(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
} else if (dev->class && dev->class->pm
|
||||
&& dev->class->pm->runtime_idle) {
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
||||
dev->class->pm->runtime_idle(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
}
|
||||
|
||||
@ -192,6 +205,22 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
|
||||
|
||||
retval = dev->bus->pm->runtime_suspend(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
dev->power.runtime_error = retval;
|
||||
} else if (dev->type && dev->type->pm
|
||||
&& dev->type->pm->runtime_suspend) {
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
||||
retval = dev->type->pm->runtime_suspend(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
dev->power.runtime_error = retval;
|
||||
} else if (dev->class && dev->class->pm
|
||||
&& dev->class->pm->runtime_suspend) {
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
||||
retval = dev->class->pm->runtime_suspend(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
dev->power.runtime_error = retval;
|
||||
} else {
|
||||
@ -357,6 +386,22 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
|
||||
|
||||
retval = dev->bus->pm->runtime_resume(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
dev->power.runtime_error = retval;
|
||||
} else if (dev->type && dev->type->pm
|
||||
&& dev->type->pm->runtime_resume) {
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
||||
retval = dev->type->pm->runtime_resume(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
dev->power.runtime_error = retval;
|
||||
} else if (dev->class && dev->class->pm
|
||||
&& dev->class->pm->runtime_resume) {
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
||||
retval = dev->class->pm->runtime_resume(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
dev->power.runtime_error = retval;
|
||||
} else {
|
||||
|
@ -307,6 +307,7 @@ static void btusb_bulk_complete(struct urb *urb)
|
||||
return;
|
||||
|
||||
usb_anchor_urb(urb, &data->bulk_anchor);
|
||||
usb_mark_last_busy(data->udev);
|
||||
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
|
@ -358,7 +358,7 @@ struct port {
|
||||
u8 update_flow_control;
|
||||
struct ctrl_ul ctrl_ul;
|
||||
struct ctrl_dl ctrl_dl;
|
||||
struct kfifo *fifo_ul;
|
||||
struct kfifo fifo_ul;
|
||||
void __iomem *dl_addr[2];
|
||||
u32 dl_size[2];
|
||||
u8 toggle_dl;
|
||||
@ -685,8 +685,6 @@ static int nozomi_read_config_table(struct nozomi *dc)
|
||||
dump_table(dc);
|
||||
|
||||
for (i = PORT_MDM; i < MAX_PORT; i++) {
|
||||
dc->port[i].fifo_ul =
|
||||
kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
|
||||
memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
|
||||
memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
|
||||
}
|
||||
@ -798,7 +796,7 @@ static int send_data(enum port_type index, struct nozomi *dc)
|
||||
struct tty_struct *tty = tty_port_tty_get(&port->port);
|
||||
|
||||
/* Get data from tty and place in buf for now */
|
||||
size = __kfifo_get(port->fifo_ul, dc->send_buf,
|
||||
size = kfifo_out(&port->fifo_ul, dc->send_buf,
|
||||
ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX);
|
||||
|
||||
if (size == 0) {
|
||||
@ -988,11 +986,11 @@ static int receive_flow_control(struct nozomi *dc)
|
||||
|
||||
} else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) {
|
||||
|
||||
if (__kfifo_len(dc->port[port].fifo_ul)) {
|
||||
if (kfifo_len(&dc->port[port].fifo_ul)) {
|
||||
DBG1("Enable interrupt (0x%04X) on port: %d",
|
||||
enable_ier, port);
|
||||
DBG1("Data in buffer [%d], enable transmit! ",
|
||||
__kfifo_len(dc->port[port].fifo_ul));
|
||||
kfifo_len(&dc->port[port].fifo_ul));
|
||||
enable_transmit_ul(port, dc);
|
||||
} else {
|
||||
DBG1("No data in buffer...");
|
||||
@ -1433,6 +1431,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
||||
goto err_free_sbuf;
|
||||
}
|
||||
|
||||
for (i = PORT_MDM; i < MAX_PORT; i++) {
|
||||
if (kfifo_alloc(&dc->port[i].fifo_ul,
|
||||
FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Could not allocate kfifo buffer\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_free_kfifo;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_init(&dc->spin_mutex);
|
||||
|
||||
nozomi_setup_private_data(dc);
|
||||
@ -1445,7 +1453,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
||||
NOZOMI_NAME, dc);
|
||||
if (unlikely(ret)) {
|
||||
dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq);
|
||||
goto err_free_sbuf;
|
||||
goto err_free_kfifo;
|
||||
}
|
||||
|
||||
DBG1("base_addr: %p", dc->base_addr);
|
||||
@ -1464,13 +1472,28 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
||||
dc->state = NOZOMI_STATE_ENABLED;
|
||||
|
||||
for (i = 0; i < MAX_PORT; i++) {
|
||||
struct device *tty_dev;
|
||||
|
||||
mutex_init(&dc->port[i].tty_sem);
|
||||
tty_port_init(&dc->port[i].port);
|
||||
tty_register_device(ntty_driver, dc->index_start + i,
|
||||
tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
|
||||
&pdev->dev);
|
||||
|
||||
if (IS_ERR(tty_dev)) {
|
||||
ret = PTR_ERR(tty_dev);
|
||||
dev_err(&pdev->dev, "Could not allocate tty?\n");
|
||||
goto err_free_tty;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_tty:
|
||||
for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
|
||||
tty_unregister_device(ntty_driver, i);
|
||||
err_free_kfifo:
|
||||
for (i = 0; i < MAX_PORT; i++)
|
||||
kfifo_free(&dc->port[i].fifo_ul);
|
||||
err_free_sbuf:
|
||||
kfree(dc->send_buf);
|
||||
iounmap(dc->base_addr);
|
||||
@ -1536,8 +1559,7 @@ static void __devexit nozomi_card_exit(struct pci_dev *pdev)
|
||||
free_irq(pdev->irq, dc);
|
||||
|
||||
for (i = 0; i < MAX_PORT; i++)
|
||||
if (dc->port[i].fifo_ul)
|
||||
kfifo_free(dc->port[i].fifo_ul);
|
||||
kfifo_free(&dc->port[i].fifo_ul);
|
||||
|
||||
kfree(dc->send_buf);
|
||||
|
||||
@ -1673,7 +1695,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count);
|
||||
rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);
|
||||
|
||||
/* notify card */
|
||||
if (unlikely(dc == NULL)) {
|
||||
@ -1721,7 +1743,7 @@ static int ntty_write_room(struct tty_struct *tty)
|
||||
if (!port->port.count)
|
||||
goto exit;
|
||||
|
||||
room = port->fifo_ul->size - __kfifo_len(port->fifo_ul);
|
||||
room = port->fifo_ul.size - kfifo_len(&port->fifo_ul);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&port->tty_sem);
|
||||
@ -1878,7 +1900,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
|
||||
goto exit_in_buffer;
|
||||
}
|
||||
|
||||
rval = __kfifo_len(port->fifo_ul);
|
||||
rval = kfifo_len(&port->fifo_ul);
|
||||
|
||||
exit_in_buffer:
|
||||
return rval;
|
||||
|
@ -487,7 +487,7 @@ static struct sonypi_device {
|
||||
int camera_power;
|
||||
int bluetooth_power;
|
||||
struct mutex lock;
|
||||
struct kfifo *fifo;
|
||||
struct kfifo fifo;
|
||||
spinlock_t fifo_lock;
|
||||
wait_queue_head_t fifo_proc_list;
|
||||
struct fasync_struct *fifo_async;
|
||||
@ -496,7 +496,7 @@ static struct sonypi_device {
|
||||
struct input_dev *input_jog_dev;
|
||||
struct input_dev *input_key_dev;
|
||||
struct work_struct input_work;
|
||||
struct kfifo *input_fifo;
|
||||
struct kfifo input_fifo;
|
||||
spinlock_t input_fifo_lock;
|
||||
} sonypi_device;
|
||||
|
||||
@ -777,8 +777,9 @@ static void input_keyrelease(struct work_struct *work)
|
||||
{
|
||||
struct sonypi_keypress kp;
|
||||
|
||||
while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp,
|
||||
sizeof(kp)) == sizeof(kp)) {
|
||||
while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
|
||||
sizeof(kp), &sonypi_device.input_fifo_lock)
|
||||
== sizeof(kp)) {
|
||||
msleep(10);
|
||||
input_report_key(kp.dev, kp.key, 0);
|
||||
input_sync(kp.dev);
|
||||
@ -827,8 +828,9 @@ static void sonypi_report_input_event(u8 event)
|
||||
if (kp.dev) {
|
||||
input_report_key(kp.dev, kp.key, 1);
|
||||
input_sync(kp.dev);
|
||||
kfifo_put(sonypi_device.input_fifo,
|
||||
(unsigned char *)&kp, sizeof(kp));
|
||||
kfifo_in_locked(&sonypi_device.input_fifo,
|
||||
(unsigned char *)&kp, sizeof(kp),
|
||||
&sonypi_device.input_fifo_lock);
|
||||
schedule_work(&sonypi_device.input_work);
|
||||
}
|
||||
}
|
||||
@ -880,7 +882,8 @@ found:
|
||||
acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
|
||||
#endif
|
||||
|
||||
kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
|
||||
kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
|
||||
sizeof(event), &sonypi_device.fifo_lock);
|
||||
kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
|
||||
wake_up_interruptible(&sonypi_device.fifo_proc_list);
|
||||
|
||||
@ -906,7 +909,7 @@ static int sonypi_misc_open(struct inode *inode, struct file *file)
|
||||
mutex_lock(&sonypi_device.lock);
|
||||
/* Flush input queue on first open */
|
||||
if (!sonypi_device.open_count)
|
||||
kfifo_reset(sonypi_device.fifo);
|
||||
kfifo_reset(&sonypi_device.fifo);
|
||||
sonypi_device.open_count++;
|
||||
mutex_unlock(&sonypi_device.lock);
|
||||
unlock_kernel();
|
||||
@ -919,17 +922,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
|
||||
ssize_t ret;
|
||||
unsigned char c;
|
||||
|
||||
if ((kfifo_len(sonypi_device.fifo) == 0) &&
|
||||
if ((kfifo_len(&sonypi_device.fifo) == 0) &&
|
||||
(file->f_flags & O_NONBLOCK))
|
||||
return -EAGAIN;
|
||||
|
||||
ret = wait_event_interruptible(sonypi_device.fifo_proc_list,
|
||||
kfifo_len(sonypi_device.fifo) != 0);
|
||||
kfifo_len(&sonypi_device.fifo) != 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
while (ret < count &&
|
||||
(kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
|
||||
(kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c),
|
||||
&sonypi_device.fifo_lock) == sizeof(c))) {
|
||||
if (put_user(c, buf++))
|
||||
return -EFAULT;
|
||||
ret++;
|
||||
@ -946,7 +950,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
|
||||
static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
poll_wait(file, &sonypi_device.fifo_proc_list, wait);
|
||||
if (kfifo_len(sonypi_device.fifo))
|
||||
if (kfifo_len(&sonypi_device.fifo))
|
||||
return POLLIN | POLLRDNORM;
|
||||
return 0;
|
||||
}
|
||||
@ -1313,11 +1317,10 @@ static int __devinit sonypi_probe(struct platform_device *dev)
|
||||
"http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
|
||||
|
||||
spin_lock_init(&sonypi_device.fifo_lock);
|
||||
sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
|
||||
&sonypi_device.fifo_lock);
|
||||
if (IS_ERR(sonypi_device.fifo)) {
|
||||
error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
|
||||
if (error) {
|
||||
printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
|
||||
return PTR_ERR(sonypi_device.fifo);
|
||||
return error;
|
||||
}
|
||||
|
||||
init_waitqueue_head(&sonypi_device.fifo_proc_list);
|
||||
@ -1393,12 +1396,10 @@ static int __devinit sonypi_probe(struct platform_device *dev)
|
||||
}
|
||||
|
||||
spin_lock_init(&sonypi_device.input_fifo_lock);
|
||||
sonypi_device.input_fifo =
|
||||
kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
|
||||
&sonypi_device.input_fifo_lock);
|
||||
if (IS_ERR(sonypi_device.input_fifo)) {
|
||||
error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (error) {
|
||||
printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
|
||||
error = PTR_ERR(sonypi_device.input_fifo);
|
||||
goto err_inpdev_unregister;
|
||||
}
|
||||
|
||||
@ -1423,7 +1424,7 @@ static int __devinit sonypi_probe(struct platform_device *dev)
|
||||
pci_disable_device(pcidev);
|
||||
err_put_pcidev:
|
||||
pci_dev_put(pcidev);
|
||||
kfifo_free(sonypi_device.fifo);
|
||||
kfifo_free(&sonypi_device.fifo);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -1438,7 +1439,7 @@ static int __devexit sonypi_remove(struct platform_device *dev)
|
||||
if (useinput) {
|
||||
input_unregister_device(sonypi_device.input_key_dev);
|
||||
input_unregister_device(sonypi_device.input_jog_dev);
|
||||
kfifo_free(sonypi_device.input_fifo);
|
||||
kfifo_free(&sonypi_device.input_fifo);
|
||||
}
|
||||
|
||||
misc_deregister(&sonypi_misc_device);
|
||||
@ -1451,7 +1452,7 @@ static int __devexit sonypi_remove(struct platform_device *dev)
|
||||
pci_dev_put(sonypi_device.dev);
|
||||
}
|
||||
|
||||
kfifo_free(sonypi_device.fifo);
|
||||
kfifo_free(&sonypi_device.fifo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -434,11 +434,11 @@ static int drm_version(struct drm_device *dev, void *data,
|
||||
* Looks up the ioctl function in the ::ioctls table, checking for root
|
||||
* previleges if so required, and dispatches to the respective function.
|
||||
*/
|
||||
int drm_ioctl(struct inode *inode, struct file *filp,
|
||||
long drm_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct drm_file *file_priv = filp->private_data;
|
||||
struct drm_device *dev = file_priv->minor->dev;
|
||||
struct drm_device *dev;
|
||||
struct drm_ioctl_desc *ioctl;
|
||||
drm_ioctl_t *func;
|
||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
@ -446,6 +446,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
|
||||
char stack_kdata[128];
|
||||
char *kdata = NULL;
|
||||
|
||||
dev = file_priv->minor->dev;
|
||||
atomic_inc(&dev->ioctl_count);
|
||||
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
|
||||
++file_priv->ioctl_count;
|
||||
@ -501,7 +502,13 @@ int drm_ioctl(struct inode *inode, struct file *filp,
|
||||
goto err_i1;
|
||||
}
|
||||
}
|
||||
retcode = func(dev, kdata, file_priv);
|
||||
if (ioctl->flags & DRM_UNLOCKED)
|
||||
retcode = func(dev, kdata, file_priv);
|
||||
else {
|
||||
lock_kernel();
|
||||
retcode = func(dev, kdata, file_priv);
|
||||
unlock_kernel();
|
||||
}
|
||||
|
||||
if (cmd & IOC_OUT) {
|
||||
if (copy_to_user((void __user *)arg, kdata,
|
||||
|
@ -913,7 +913,7 @@ static int drm_cvt_modes(struct drm_connector *connector,
|
||||
const int rates[] = { 60, 85, 75, 60, 50 };
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int width, height;
|
||||
int uninitialized_var(width), height;
|
||||
cvt = &(timing->data.other_data.data.cvt[i]);
|
||||
|
||||
height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2;
|
||||
|
@ -104,7 +104,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
|
||||
&version->desc))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
err = drm_ioctl(file,
|
||||
DRM_IOCTL_VERSION, (unsigned long)version);
|
||||
if (err)
|
||||
return err;
|
||||
@ -145,8 +145,7 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,
|
||||
&u->unique))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
|
||||
err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -174,8 +173,7 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd,
|
||||
&u->unique))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
|
||||
return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
|
||||
}
|
||||
|
||||
typedef struct drm_map32 {
|
||||
@ -205,8 +203,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
|
||||
if (__put_user(idx, &map->offset))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_MAP, (unsigned long)map);
|
||||
err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -246,8 +243,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
|
||||
|| __put_user(m32.flags, &map->flags))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_ADD_MAP, (unsigned long)map);
|
||||
err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -284,8 +280,7 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd,
|
||||
if (__put_user((void *)(unsigned long)handle, &map->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_RM_MAP, (unsigned long)map);
|
||||
return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map);
|
||||
}
|
||||
|
||||
typedef struct drm_client32 {
|
||||
@ -314,8 +309,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
|
||||
if (__put_user(idx, &client->idx))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_CLIENT, (unsigned long)client);
|
||||
err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -351,8 +345,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd,
|
||||
if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_STATS, (unsigned long)stats);
|
||||
err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -395,8 +388,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd,
|
||||
|| __put_user(agp_start, &buf->agp_start))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
|
||||
err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -427,8 +419,7 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd,
|
||||
|| __put_user(b32.high_mark, &buf->high_mark))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
|
||||
return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
|
||||
}
|
||||
|
||||
typedef struct drm_buf_info32 {
|
||||
@ -469,8 +460,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
|
||||
|| __put_user(list, &request->list))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_INFO_BUFS, (unsigned long)request);
|
||||
err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -531,8 +521,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
|
||||
|| __put_user(list, &request->list))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_MAP_BUFS, (unsigned long)request);
|
||||
err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -578,8 +567,7 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd,
|
||||
&request->list))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_FREE_BUFS, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_ctx_priv_map32 {
|
||||
@ -605,8 +593,7 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
|
||||
&request->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
|
||||
}
|
||||
|
||||
static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
|
||||
@ -628,8 +615,7 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
|
||||
if (__put_user(ctx_id, &request->ctx_id))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
|
||||
err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -664,8 +650,7 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
|
||||
&res->contexts))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_RES_CTX, (unsigned long)res);
|
||||
err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -718,8 +703,7 @@ static int compat_drm_dma(struct file *file, unsigned int cmd,
|
||||
&d->request_sizes))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_DMA, (unsigned long)d);
|
||||
err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -751,8 +735,7 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
|
||||
if (put_user(m32.mode, &mode->mode))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
|
||||
return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
|
||||
}
|
||||
|
||||
typedef struct drm_agp_info32 {
|
||||
@ -781,8 +764,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd,
|
||||
if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_INFO, (unsigned long)info);
|
||||
err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -827,16 +809,14 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
|
||||
|| __put_user(req32.type, &request->type))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
|
||||
err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (__get_user(req32.handle, &request->handle)
|
||||
|| __get_user(req32.physical, &request->physical)
|
||||
|| copy_to_user(argp, &req32, sizeof(req32))) {
|
||||
drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_FREE, (unsigned long)request);
|
||||
drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@ -856,8 +836,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd,
|
||||
|| __put_user(handle, &request->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_FREE, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_agp_binding32 {
|
||||
@ -881,8 +860,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
|
||||
|| __put_user(req32.offset, &request->offset))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_BIND, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request);
|
||||
}
|
||||
|
||||
static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
|
||||
@ -898,8 +876,7 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
|
||||
|| __put_user(handle, &request->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
|
||||
}
|
||||
#endif /* __OS_HAS_AGP */
|
||||
|
||||
@ -923,8 +900,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
|
||||
|| __put_user(x, &request->size))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_SG_ALLOC, (unsigned long)request);
|
||||
err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -950,8 +926,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
|
||||
|| __put_user(x << PAGE_SHIFT, &request->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_SG_FREE, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_IA64)
|
||||
@ -981,8 +956,7 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd,
|
||||
__put_user(update32.data, &request->data))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
|
||||
err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
@ -1023,8 +997,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
|
||||
|| __put_user(req32.request.signal, &request->request.signal))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
|
||||
err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -1094,16 +1067,14 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
* than always failing.
|
||||
*/
|
||||
if (nr >= ARRAY_SIZE(drm_compat_ioctls))
|
||||
return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
return drm_ioctl(filp, cmd, arg);
|
||||
|
||||
fn = drm_compat_ioctls[nr];
|
||||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
ret = drm_ioctl(filp, cmd, arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
|
||||
if (entry->size >= size + wasted) {
|
||||
if (!best_match)
|
||||
return entry;
|
||||
if (size < best_size) {
|
||||
if (entry->size < best_size) {
|
||||
best = entry;
|
||||
best_size = entry->size;
|
||||
}
|
||||
@ -408,7 +408,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
|
||||
if (entry->size >= size + wasted) {
|
||||
if (!best_match)
|
||||
return entry;
|
||||
if (size < best_size) {
|
||||
if (entry->size < best_size) {
|
||||
best = entry;
|
||||
best_size = entry->size;
|
||||
}
|
||||
|
@ -408,6 +408,11 @@ static int ch7006_probe(struct i2c_client *client, const struct i2c_device_id *i
|
||||
|
||||
ch7006_info(client, "Detected version ID: %x\n", val);
|
||||
|
||||
/* I don't know what this is for, but otherwise I get no
|
||||
* signal.
|
||||
*/
|
||||
ch7006_write(client, 0x3d, 0x0);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -427,11 +427,6 @@ void ch7006_state_load(struct i2c_client *client,
|
||||
ch7006_load_reg(client, state, CH7006_SUBC_INC7);
|
||||
ch7006_load_reg(client, state, CH7006_PLL_CONTROL);
|
||||
ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0);
|
||||
|
||||
/* I don't know what this is for, but otherwise I get no
|
||||
* signal.
|
||||
*/
|
||||
ch7006_write(client, 0x3d, 0x0);
|
||||
}
|
||||
|
||||
void ch7006_state_save(struct i2c_client *client,
|
||||
|
@ -115,7 +115,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
|
||||
static const struct file_operations i810_buffer_fops = {
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = i810_mmap_buffers,
|
||||
.fasync = drm_fasync,
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ static struct drm_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
|
@ -117,7 +117,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
|
||||
static const struct file_operations i830_buffer_fops = {
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = i830_mmap_buffers,
|
||||
.fasync = drm_fasync,
|
||||
};
|
||||
|
@ -70,7 +70,7 @@ static struct drm_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
|
@ -329,7 +329,7 @@ static struct drm_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = drm_gem_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
|
@ -66,8 +66,7 @@ static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
|
||||
&batchbuffer->cliprects))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_BATCHBUFFER,
|
||||
return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER,
|
||||
(unsigned long)batchbuffer);
|
||||
}
|
||||
|
||||
@ -102,8 +101,8 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
|
||||
&cmdbuffer->cliprects))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
|
||||
return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER,
|
||||
(unsigned long)cmdbuffer);
|
||||
}
|
||||
|
||||
typedef struct drm_i915_irq_emit32 {
|
||||
@ -125,8 +124,8 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
|
||||
&request->irq_seq))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT,
|
||||
(unsigned long)request);
|
||||
}
|
||||
typedef struct drm_i915_getparam32 {
|
||||
int param;
|
||||
@ -149,8 +148,8 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd,
|
||||
&request->value))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
|
||||
(unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_i915_mem_alloc32 {
|
||||
@ -178,8 +177,8 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd,
|
||||
&request->region_offset))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_ALLOC, (unsigned long)request);
|
||||
return drm_ioctl(file, DRM_IOCTL_I915_ALLOC,
|
||||
(unsigned long)request);
|
||||
}
|
||||
|
||||
drm_ioctl_compat_t *i915_compat_ioctls[] = {
|
||||
@ -211,12 +210,10 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
|
||||
fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
|
||||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
ret = drm_ioctl(filp, cmd, arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ static struct drm_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
|
@ -100,8 +100,7 @@ static int compat_mga_init(struct file *file, unsigned int cmd,
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_MGA_INIT, (unsigned long)init);
|
||||
return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init);
|
||||
}
|
||||
|
||||
typedef struct drm_mga_getparam32 {
|
||||
@ -125,8 +124,7 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd,
|
||||
&getparam->value))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
|
||||
return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
|
||||
}
|
||||
|
||||
typedef struct drm_mga_drm_bootstrap32 {
|
||||
@ -166,8 +164,7 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
|
||||
|| __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_path.dentry->d_inode, file,
|
||||
DRM_IOCTL_MGA_DMA_BOOTSTRAP,
|
||||
err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP,
|
||||
(unsigned long)dma_bootstrap);
|
||||
if (err)
|
||||
return err;
|
||||
@ -220,12 +217,10 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
|
||||
fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
|
||||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
ret = drm_ioctl(filp, cmd, arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -8,14 +8,15 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
|
||||
nouveau_sgdma.o nouveau_dma.o \
|
||||
nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
|
||||
nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
|
||||
nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
|
||||
nouveau_dp.o \
|
||||
nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
|
||||
nouveau_dp.o nouveau_grctx.o \
|
||||
nv04_timer.o \
|
||||
nv04_mc.o nv40_mc.o nv50_mc.o \
|
||||
nv04_fb.o nv10_fb.o nv40_fb.o \
|
||||
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
|
||||
nv04_graph.o nv10_graph.o nv20_graph.o \
|
||||
nv40_graph.o nv50_graph.o \
|
||||
nv40_grctx.o \
|
||||
nv04_instmem.o nv50_instmem.o \
|
||||
nv50_crtc.o nv50_dac.o nv50_sor.o \
|
||||
nv50_cursor.o nv50_display.o nv50_fbcon.o \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -227,6 +227,7 @@ struct nvbios {
|
||||
|
||||
uint16_t pll_limit_tbl_ptr;
|
||||
uint16_t ram_restrict_tbl_ptr;
|
||||
uint8_t ram_restrict_group_count;
|
||||
|
||||
uint16_t some_script_ptr; /* BIT I + 14 */
|
||||
uint16_t init96_tbl_ptr; /* BIT I + 16 */
|
||||
|
@ -154,6 +154,11 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype)
|
||||
nvbo->placement.busy_placement = nvbo->placements;
|
||||
nvbo->placement.num_placement = n;
|
||||
nvbo->placement.num_busy_placement = n;
|
||||
|
||||
if (nvbo->pin_refcnt) {
|
||||
while (n--)
|
||||
nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -400,10 +405,16 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
|
||||
struct nouveau_bo *nvbo = nouveau_bo(bo);
|
||||
|
||||
switch (bo->mem.mem_type) {
|
||||
case TTM_PL_VRAM:
|
||||
nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT |
|
||||
TTM_PL_FLAG_SYSTEM);
|
||||
break;
|
||||
default:
|
||||
nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
|
||||
break;
|
||||
}
|
||||
|
||||
*pl = nvbo->placement;
|
||||
}
|
||||
|
||||
|
||||
@ -455,11 +466,8 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, int no_wait,
|
||||
int ret;
|
||||
|
||||
chan = nvbo->channel;
|
||||
if (!chan || nvbo->tile_flags || nvbo->no_vm) {
|
||||
if (!chan || nvbo->tile_flags || nvbo->no_vm)
|
||||
chan = dev_priv->channel;
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
src_offset = old_mem->mm_node->start << PAGE_SHIFT;
|
||||
dst_offset = new_mem->mm_node->start << PAGE_SHIFT;
|
||||
@ -625,7 +633,8 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE)
|
||||
if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE ||
|
||||
!dev_priv->channel)
|
||||
return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem);
|
||||
|
||||
if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) {
|
||||
|
@ -86,7 +86,7 @@ nouveau_connector_destroy(struct drm_connector *drm_connector)
|
||||
struct nouveau_connector *connector = nouveau_connector(drm_connector);
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
if (!connector)
|
||||
return;
|
||||
@ -420,7 +420,7 @@ nouveau_connector_native_mode(struct nouveau_connector *connector)
|
||||
/* Use preferred mode if there is one.. */
|
||||
list_for_each_entry(mode, &connector->base.probed_modes, head) {
|
||||
if (mode->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
NV_DEBUG(dev, "native mode from preferred\n");
|
||||
NV_DEBUG_KMS(dev, "native mode from preferred\n");
|
||||
return drm_mode_duplicate(dev, mode);
|
||||
}
|
||||
}
|
||||
@ -445,7 +445,7 @@ nouveau_connector_native_mode(struct nouveau_connector *connector)
|
||||
largest = mode;
|
||||
}
|
||||
|
||||
NV_DEBUG(dev, "native mode from largest: %dx%d@%d\n",
|
||||
NV_DEBUG_KMS(dev, "native mode from largest: %dx%d@%d\n",
|
||||
high_w, high_h, high_v);
|
||||
return largest ? drm_mode_duplicate(dev, largest) : NULL;
|
||||
}
|
||||
@ -725,7 +725,7 @@ nouveau_connector_create(struct drm_device *dev, int index, int type)
|
||||
struct drm_encoder *encoder;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
|
||||
if (!nv_connector)
|
||||
|
@ -187,7 +187,7 @@ nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t *config)
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
NV_DEBUG(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]);
|
||||
NV_DEBUG_KMS(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]);
|
||||
|
||||
/* Keep all lanes at the same level.. */
|
||||
for (i = 0; i < nv_encoder->dp.link_nr; i++) {
|
||||
@ -228,7 +228,7 @@ nouveau_dp_link_train_commit(struct drm_encoder *encoder, uint8_t *config)
|
||||
int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1);
|
||||
int dpe_headerlen, ret, i;
|
||||
|
||||
NV_DEBUG(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
NV_DEBUG_KMS(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
config[0], config[1], config[2], config[3]);
|
||||
|
||||
dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
|
||||
@ -276,12 +276,12 @@ nouveau_dp_link_train(struct drm_encoder *encoder)
|
||||
bool cr_done, cr_max_vs, eq_done;
|
||||
int ret = 0, i, tries, voltage;
|
||||
|
||||
NV_DEBUG(dev, "link training!!\n");
|
||||
NV_DEBUG_KMS(dev, "link training!!\n");
|
||||
train:
|
||||
cr_done = eq_done = false;
|
||||
|
||||
/* set link configuration */
|
||||
NV_DEBUG(dev, "\tbegin train: bw %d, lanes %d\n",
|
||||
NV_DEBUG_KMS(dev, "\tbegin train: bw %d, lanes %d\n",
|
||||
nv_encoder->dp.link_bw, nv_encoder->dp.link_nr);
|
||||
|
||||
ret = nouveau_dp_link_bw_set(encoder, nv_encoder->dp.link_bw);
|
||||
@ -297,7 +297,7 @@ train:
|
||||
return false;
|
||||
|
||||
/* clock recovery */
|
||||
NV_DEBUG(dev, "\tbegin cr\n");
|
||||
NV_DEBUG_KMS(dev, "\tbegin cr\n");
|
||||
ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_1);
|
||||
if (ret)
|
||||
goto stop;
|
||||
@ -314,7 +314,7 @@ train:
|
||||
ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 2);
|
||||
if (ret)
|
||||
break;
|
||||
NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n",
|
||||
NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n",
|
||||
status[0], status[1]);
|
||||
|
||||
cr_done = true;
|
||||
@ -346,7 +346,7 @@ train:
|
||||
goto stop;
|
||||
|
||||
/* channel equalisation */
|
||||
NV_DEBUG(dev, "\tbegin eq\n");
|
||||
NV_DEBUG_KMS(dev, "\tbegin eq\n");
|
||||
ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_2);
|
||||
if (ret)
|
||||
goto stop;
|
||||
@ -357,7 +357,7 @@ train:
|
||||
ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 3);
|
||||
if (ret)
|
||||
break;
|
||||
NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n",
|
||||
NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n",
|
||||
status[0], status[1]);
|
||||
|
||||
eq_done = true;
|
||||
@ -395,9 +395,9 @@ stop:
|
||||
|
||||
/* retry at a lower setting, if possible */
|
||||
if (!ret && !(eq_done && cr_done)) {
|
||||
NV_DEBUG(dev, "\twe failed\n");
|
||||
NV_DEBUG_KMS(dev, "\twe failed\n");
|
||||
if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62) {
|
||||
NV_DEBUG(dev, "retry link training at low rate\n");
|
||||
NV_DEBUG_KMS(dev, "retry link training at low rate\n");
|
||||
nv_encoder->dp.link_bw = DP_LINK_BW_1_62;
|
||||
goto train;
|
||||
}
|
||||
@ -418,7 +418,7 @@ nouveau_dp_detect(struct drm_encoder *encoder)
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
NV_DEBUG(dev, "encoder: link_bw %d, link_nr %d\n"
|
||||
NV_DEBUG_KMS(dev, "encoder: link_bw %d, link_nr %d\n"
|
||||
"display: link_bw %d, link_nr %d version 0x%02x\n",
|
||||
nv_encoder->dcb->dpconf.link_bw,
|
||||
nv_encoder->dcb->dpconf.link_nr,
|
||||
@ -446,7 +446,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
|
||||
uint32_t tmp, ctrl, stat = 0, data32[4] = {};
|
||||
int ret = 0, i, index = auxch->rd;
|
||||
|
||||
NV_DEBUG(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr);
|
||||
NV_DEBUG_KMS(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr);
|
||||
|
||||
tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd));
|
||||
nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp | 0x00100000);
|
||||
@ -472,7 +472,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
|
||||
if (!(cmd & 1)) {
|
||||
memcpy(data32, data, data_nr);
|
||||
for (i = 0; i < 4; i++) {
|
||||
NV_DEBUG(dev, "wr %d: 0x%08x\n", i, data32[i]);
|
||||
NV_DEBUG_KMS(dev, "wr %d: 0x%08x\n", i, data32[i]);
|
||||
nv_wr32(dev, NV50_AUXCH_DATA_OUT(index, i), data32[i]);
|
||||
}
|
||||
}
|
||||
@ -504,7 +504,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
|
||||
if (cmd & 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i));
|
||||
NV_DEBUG(dev, "rd %d: 0x%08x\n", i, data32[i]);
|
||||
NV_DEBUG_KMS(dev, "rd %d: 0x%08x\n", i, data32[i]);
|
||||
}
|
||||
memcpy(data, data32, data_nr);
|
||||
}
|
||||
|
@ -35,6 +35,10 @@
|
||||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)");
|
||||
int nouveau_ctxfw = 0;
|
||||
module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
|
||||
|
||||
MODULE_PARM_DESC(noagp, "Disable AGP");
|
||||
int nouveau_noagp;
|
||||
module_param_named(noagp, nouveau_noagp, int, 0400);
|
||||
@ -273,7 +277,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
|
||||
|
||||
for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
|
||||
chan = dev_priv->fifos[i];
|
||||
if (!chan)
|
||||
if (!chan || !chan->pushbuf_bo)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < NOUVEAU_DMA_SKIPS; j++)
|
||||
@ -341,7 +345,7 @@ static struct drm_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.mmap = nouveau_ttm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
|
@ -54,6 +54,7 @@ struct nouveau_fpriv {
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_bios.h"
|
||||
struct nouveau_grctx;
|
||||
|
||||
#define MAX_NUM_DCB_ENTRIES 16
|
||||
|
||||
@ -317,6 +318,7 @@ struct nouveau_pgraph_engine {
|
||||
bool accel_blocked;
|
||||
void *ctxprog;
|
||||
void *ctxvals;
|
||||
int grctx_size;
|
||||
|
||||
int (*init)(struct drm_device *);
|
||||
void (*takedown)(struct drm_device *);
|
||||
@ -647,6 +649,7 @@ extern int nouveau_fbpercrtc;
|
||||
extern char *nouveau_tv_norm;
|
||||
extern int nouveau_reg_debug;
|
||||
extern char *nouveau_vbios;
|
||||
extern int nouveau_ctxfw;
|
||||
|
||||
/* nouveau_state.c */
|
||||
extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
|
||||
@ -959,9 +962,7 @@ extern int nv40_graph_create_context(struct nouveau_channel *);
|
||||
extern void nv40_graph_destroy_context(struct nouveau_channel *);
|
||||
extern int nv40_graph_load_context(struct nouveau_channel *);
|
||||
extern int nv40_graph_unload_context(struct drm_device *);
|
||||
extern int nv40_grctx_init(struct drm_device *);
|
||||
extern void nv40_grctx_fini(struct drm_device *);
|
||||
extern void nv40_grctx_vals_load(struct drm_device *, struct nouveau_gpuobj *);
|
||||
extern void nv40_grctx_init(struct nouveau_grctx *);
|
||||
|
||||
/* nv50_graph.c */
|
||||
extern struct nouveau_pgraph_object_class nv50_graph_grclass[];
|
||||
@ -975,6 +976,12 @@ extern int nv50_graph_load_context(struct nouveau_channel *);
|
||||
extern int nv50_graph_unload_context(struct drm_device *);
|
||||
extern void nv50_graph_context_switch(struct drm_device *);
|
||||
|
||||
/* nouveau_grctx.c */
|
||||
extern int nouveau_grctx_prog_load(struct drm_device *);
|
||||
extern void nouveau_grctx_vals_load(struct drm_device *,
|
||||
struct nouveau_gpuobj *);
|
||||
extern void nouveau_grctx_fini(struct drm_device *);
|
||||
|
||||
/* nv04_instmem.c */
|
||||
extern int nv04_instmem_init(struct drm_device *);
|
||||
extern void nv04_instmem_takedown(struct drm_device *);
|
||||
@ -1207,14 +1214,24 @@ static inline void nv_wo32(struct drm_device *dev, struct nouveau_gpuobj *obj,
|
||||
pci_name(d->pdev), ##arg)
|
||||
#ifndef NV_DEBUG_NOTRACE
|
||||
#define NV_DEBUG(d, fmt, arg...) do { \
|
||||
if (drm_debug) { \
|
||||
if (drm_debug & DRM_UT_DRIVER) { \
|
||||
NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \
|
||||
__LINE__, ##arg); \
|
||||
} \
|
||||
} while (0)
|
||||
#define NV_DEBUG_KMS(d, fmt, arg...) do { \
|
||||
if (drm_debug & DRM_UT_KMS) { \
|
||||
NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \
|
||||
__LINE__, ##arg); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define NV_DEBUG(d, fmt, arg...) do { \
|
||||
if (drm_debug) \
|
||||
if (drm_debug & DRM_UT_DRIVER) \
|
||||
NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define NV_DEBUG_KMS(d, fmt, arg...) do { \
|
||||
if (drm_debug & DRM_UT_KMS) \
|
||||
NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
@ -58,7 +58,7 @@ nouveau_fbcon_sync(struct fb_info *info)
|
||||
struct nouveau_channel *chan = dev_priv->channel;
|
||||
int ret, i;
|
||||
|
||||
if (!chan->accel_done ||
|
||||
if (!chan || !chan->accel_done ||
|
||||
info->state != FBINFO_STATE_RUNNING ||
|
||||
info->flags & FBINFO_HWACCEL_DISABLED)
|
||||
return 0;
|
||||
@ -318,14 +318,16 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width,
|
||||
par->nouveau_fb = nouveau_fb;
|
||||
par->dev = dev;
|
||||
|
||||
switch (dev_priv->card_type) {
|
||||
case NV_50:
|
||||
nv50_fbcon_accel_init(info);
|
||||
break;
|
||||
default:
|
||||
nv04_fbcon_accel_init(info);
|
||||
break;
|
||||
};
|
||||
if (dev_priv->channel) {
|
||||
switch (dev_priv->card_type) {
|
||||
case NV_50:
|
||||
nv50_fbcon_accel_init(info);
|
||||
break;
|
||||
default:
|
||||
nv04_fbcon_accel_init(info);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
nouveau_fbcon_zfill(dev);
|
||||
|
||||
@ -347,7 +349,7 @@ out:
|
||||
int
|
||||
nouveau_fbcon_probe(struct drm_device *dev)
|
||||
{
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_create);
|
||||
}
|
||||
|
161
drivers/gpu/drm/nouveau/nouveau_grctx.c
Normal file
161
drivers/gpu/drm/nouveau/nouveau_grctx.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2009 Red Hat Inc.
|
||||
*
|
||||
* 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: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include "drmP.h"
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
struct nouveau_ctxprog {
|
||||
uint32_t signature;
|
||||
uint8_t version;
|
||||
uint16_t length;
|
||||
uint32_t data[];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nouveau_ctxvals {
|
||||
uint32_t signature;
|
||||
uint8_t version;
|
||||
uint32_t length;
|
||||
struct {
|
||||
uint32_t offset;
|
||||
uint32_t value;
|
||||
} data[];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int
|
||||
nouveau_grctx_prog_load(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
const int chipset = dev_priv->chipset;
|
||||
const struct firmware *fw;
|
||||
const struct nouveau_ctxprog *cp;
|
||||
const struct nouveau_ctxvals *cv;
|
||||
char name[32];
|
||||
int ret, i;
|
||||
|
||||
if (pgraph->accel_blocked)
|
||||
return -ENODEV;
|
||||
|
||||
if (!pgraph->ctxprog) {
|
||||
sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
|
||||
ret = request_firmware(&fw, name, &dev->pdev->dev);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL);
|
||||
if (!pgraph->ctxprog) {
|
||||
NV_ERROR(dev, "OOM copying ctxprog\n");
|
||||
release_firmware(fw);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(pgraph->ctxprog, fw->data, fw->size);
|
||||
|
||||
cp = pgraph->ctxprog;
|
||||
if (le32_to_cpu(cp->signature) != 0x5043564e ||
|
||||
cp->version != 0 ||
|
||||
le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
|
||||
NV_ERROR(dev, "ctxprog invalid\n");
|
||||
release_firmware(fw);
|
||||
nouveau_grctx_fini(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
release_firmware(fw);
|
||||
}
|
||||
|
||||
if (!pgraph->ctxvals) {
|
||||
sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
|
||||
ret = request_firmware(&fw, name, &dev->pdev->dev);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
|
||||
nouveau_grctx_fini(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL);
|
||||
if (!pgraph->ctxprog) {
|
||||
NV_ERROR(dev, "OOM copying ctxprog\n");
|
||||
release_firmware(fw);
|
||||
nouveau_grctx_fini(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(pgraph->ctxvals, fw->data, fw->size);
|
||||
|
||||
cv = (void *)pgraph->ctxvals;
|
||||
if (le32_to_cpu(cv->signature) != 0x5643564e ||
|
||||
cv->version != 0 ||
|
||||
le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
|
||||
NV_ERROR(dev, "ctxvals invalid\n");
|
||||
release_firmware(fw);
|
||||
nouveau_grctx_fini(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
release_firmware(fw);
|
||||
}
|
||||
|
||||
cp = pgraph->ctxprog;
|
||||
|
||||
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
|
||||
for (i = 0; i < le16_to_cpu(cp->length); i++)
|
||||
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
|
||||
le32_to_cpu(cp->data[i]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_grctx_fini(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
|
||||
if (pgraph->ctxprog) {
|
||||
kfree(pgraph->ctxprog);
|
||||
pgraph->ctxprog = NULL;
|
||||
}
|
||||
|
||||
if (pgraph->ctxvals) {
|
||||
kfree(pgraph->ctxprog);
|
||||
pgraph->ctxvals = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
struct nouveau_ctxvals *cv = pgraph->ctxvals;
|
||||
int i;
|
||||
|
||||
if (!cv)
|
||||
return;
|
||||
|
||||
for (i = 0; i < le32_to_cpu(cv->length); i++)
|
||||
nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
|
||||
le32_to_cpu(cv->data[i].value));
|
||||
}
|
133
drivers/gpu/drm/nouveau/nouveau_grctx.h
Normal file
133
drivers/gpu/drm/nouveau/nouveau_grctx.h
Normal file
@ -0,0 +1,133 @@
|
||||
#ifndef __NOUVEAU_GRCTX_H__
|
||||
#define __NOUVEAU_GRCTX_H__
|
||||
|
||||
struct nouveau_grctx {
|
||||
struct drm_device *dev;
|
||||
|
||||
enum {
|
||||
NOUVEAU_GRCTX_PROG,
|
||||
NOUVEAU_GRCTX_VALS
|
||||
} mode;
|
||||
void *data;
|
||||
|
||||
uint32_t ctxprog_max;
|
||||
uint32_t ctxprog_len;
|
||||
uint32_t ctxprog_reg;
|
||||
int ctxprog_label[32];
|
||||
uint32_t ctxvals_pos;
|
||||
uint32_t ctxvals_base;
|
||||
};
|
||||
|
||||
#ifdef CP_CTX
|
||||
static inline void
|
||||
cp_out(struct nouveau_grctx *ctx, uint32_t inst)
|
||||
{
|
||||
uint32_t *ctxprog = ctx->data;
|
||||
|
||||
if (ctx->mode != NOUVEAU_GRCTX_PROG)
|
||||
return;
|
||||
|
||||
BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max);
|
||||
ctxprog[ctx->ctxprog_len++] = inst;
|
||||
}
|
||||
|
||||
static inline void
|
||||
cp_lsr(struct nouveau_grctx *ctx, uint32_t val)
|
||||
{
|
||||
cp_out(ctx, CP_LOAD_SR | val);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length)
|
||||
{
|
||||
ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
|
||||
|
||||
ctx->ctxvals_base = ctx->ctxvals_pos;
|
||||
ctx->ctxvals_pos = ctx->ctxvals_base + length;
|
||||
|
||||
if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) {
|
||||
cp_lsr(ctx, length);
|
||||
length = 0;
|
||||
}
|
||||
|
||||
cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cp_name(struct nouveau_grctx *ctx, int name)
|
||||
{
|
||||
uint32_t *ctxprog = ctx->data;
|
||||
int i;
|
||||
|
||||
if (ctx->mode != NOUVEAU_GRCTX_PROG)
|
||||
return;
|
||||
|
||||
ctx->ctxprog_label[name] = ctx->ctxprog_len;
|
||||
for (i = 0; i < ctx->ctxprog_len; i++) {
|
||||
if ((ctxprog[i] & 0xfff00000) != 0xff400000)
|
||||
continue;
|
||||
if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT))
|
||||
continue;
|
||||
ctxprog[i] = (ctxprog[i] & 0x00ff00ff) |
|
||||
(ctx->ctxprog_len << CP_BRA_IP_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name)
|
||||
{
|
||||
int ip = 0;
|
||||
|
||||
if (mod != 2) {
|
||||
ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT;
|
||||
if (ip == 0)
|
||||
ip = 0xff000000 | (name << CP_BRA_IP_SHIFT);
|
||||
}
|
||||
|
||||
cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
|
||||
(state ? 0 : CP_BRA_IF_CLEAR));
|
||||
}
|
||||
#define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
|
||||
#ifdef CP_BRA_MOD
|
||||
#define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
|
||||
#define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
_cp_wait(struct nouveau_grctx *ctx, int flag, int state)
|
||||
{
|
||||
cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
|
||||
}
|
||||
#define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
|
||||
|
||||
static inline void
|
||||
_cp_set(struct nouveau_grctx *ctx, int flag, int state)
|
||||
{
|
||||
cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
|
||||
}
|
||||
#define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
|
||||
|
||||
static inline void
|
||||
cp_pos(struct nouveau_grctx *ctx, int offset)
|
||||
{
|
||||
ctx->ctxvals_pos = offset;
|
||||
ctx->ctxvals_base = ctx->ctxvals_pos;
|
||||
|
||||
cp_lsr(ctx, ctx->ctxvals_pos);
|
||||
cp_out(ctx, CP_SET_CONTEXT_POINTER);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val)
|
||||
{
|
||||
if (ctx->mode != NOUVEAU_GRCTX_VALS)
|
||||
return;
|
||||
|
||||
reg = (reg - 0x00400000) / 4;
|
||||
reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base;
|
||||
|
||||
nv_wo32(ctx->dev, ctx->data, reg, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -61,12 +61,10 @@ long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
|
||||
fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE];
|
||||
#endif
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn)(filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
ret = drm_ioctl(filp, cmd, arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -299,94 +299,13 @@ nouveau_vga_set_decode(void *priv, bool state)
|
||||
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_card_init(struct drm_device *dev)
|
||||
static int
|
||||
nouveau_card_init_channel(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_engine *engine;
|
||||
struct nouveau_gpuobj *gpuobj;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
|
||||
|
||||
if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
|
||||
return 0;
|
||||
|
||||
vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
|
||||
|
||||
/* Initialise internal driver API hooks */
|
||||
ret = nouveau_init_engine_ptrs(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
engine = &dev_priv->engine;
|
||||
dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
|
||||
|
||||
/* Parse BIOS tables / Run init tables if card not POSTed */
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
ret = nouveau_bios_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nouveau_gpuobj_early_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Initialise instance memory, must happen before mem_init so we
|
||||
* know exactly how much VRAM we're able to use for "normal"
|
||||
* purposes.
|
||||
*/
|
||||
ret = engine->instmem.init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Setup the memory manager */
|
||||
ret = nouveau_mem_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* PMC */
|
||||
ret = engine->mc.init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* PTIMER */
|
||||
ret = engine->timer.init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* PFB */
|
||||
ret = engine->fb.init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* PGRAPH */
|
||||
ret = engine->graph.init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* PFIFO */
|
||||
ret = engine->fifo.init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* this call irq_preinstall, register irq handler and
|
||||
* call irq_postinstall
|
||||
*/
|
||||
ret = drm_irq_install(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_vblank_init(dev, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* what about PVIDEO/PCRTC/PRAMDAC etc? */
|
||||
|
||||
ret = nouveau_channel_alloc(dev, &dev_priv->channel,
|
||||
(struct drm_file *)-2,
|
||||
NvDmaFB, NvDmaTT);
|
||||
@ -399,39 +318,133 @@ nouveau_card_init(struct drm_device *dev)
|
||||
NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
|
||||
&gpuobj);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_err;
|
||||
|
||||
ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
|
||||
gpuobj, NULL);
|
||||
if (ret) {
|
||||
nouveau_gpuobj_del(dev, &gpuobj);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
gpuobj = NULL;
|
||||
ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0,
|
||||
dev_priv->gart_info.aper_size,
|
||||
NV_DMA_ACCESS_RW, &gpuobj, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_err;
|
||||
|
||||
ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
|
||||
gpuobj, NULL);
|
||||
if (ret) {
|
||||
nouveau_gpuobj_del(dev, &gpuobj);
|
||||
return ret;
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
out_err:
|
||||
nouveau_gpuobj_del(dev, &gpuobj);
|
||||
nouveau_channel_free(dev_priv->channel);
|
||||
dev_priv->channel = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_card_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_engine *engine;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
|
||||
|
||||
if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
|
||||
return 0;
|
||||
|
||||
vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
|
||||
|
||||
/* Initialise internal driver API hooks */
|
||||
ret = nouveau_init_engine_ptrs(dev);
|
||||
if (ret)
|
||||
goto out;
|
||||
engine = &dev_priv->engine;
|
||||
dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
|
||||
|
||||
/* Parse BIOS tables / Run init tables if card not POSTed */
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
ret = nouveau_bios_init(dev);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nouveau_gpuobj_early_init(dev);
|
||||
if (ret)
|
||||
goto out_bios;
|
||||
|
||||
/* Initialise instance memory, must happen before mem_init so we
|
||||
* know exactly how much VRAM we're able to use for "normal"
|
||||
* purposes.
|
||||
*/
|
||||
ret = engine->instmem.init(dev);
|
||||
if (ret)
|
||||
goto out_gpuobj_early;
|
||||
|
||||
/* Setup the memory manager */
|
||||
ret = nouveau_mem_init(dev);
|
||||
if (ret)
|
||||
goto out_instmem;
|
||||
|
||||
ret = nouveau_gpuobj_init(dev);
|
||||
if (ret)
|
||||
goto out_mem;
|
||||
|
||||
/* PMC */
|
||||
ret = engine->mc.init(dev);
|
||||
if (ret)
|
||||
goto out_gpuobj;
|
||||
|
||||
/* PTIMER */
|
||||
ret = engine->timer.init(dev);
|
||||
if (ret)
|
||||
goto out_mc;
|
||||
|
||||
/* PFB */
|
||||
ret = engine->fb.init(dev);
|
||||
if (ret)
|
||||
goto out_timer;
|
||||
|
||||
/* PGRAPH */
|
||||
ret = engine->graph.init(dev);
|
||||
if (ret)
|
||||
goto out_fb;
|
||||
|
||||
/* PFIFO */
|
||||
ret = engine->fifo.init(dev);
|
||||
if (ret)
|
||||
goto out_graph;
|
||||
|
||||
/* this call irq_preinstall, register irq handler and
|
||||
* call irq_postinstall
|
||||
*/
|
||||
ret = drm_irq_install(dev);
|
||||
if (ret)
|
||||
goto out_fifo;
|
||||
|
||||
ret = drm_vblank_init(dev, 0);
|
||||
if (ret)
|
||||
goto out_irq;
|
||||
|
||||
/* what about PVIDEO/PCRTC/PRAMDAC etc? */
|
||||
|
||||
if (!engine->graph.accel_blocked) {
|
||||
ret = nouveau_card_init_channel(dev);
|
||||
if (ret)
|
||||
goto out_irq;
|
||||
}
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
if (dev_priv->card_type >= NV_50) {
|
||||
if (dev_priv->card_type >= NV_50)
|
||||
ret = nv50_display_create(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
else
|
||||
ret = nv04_display_create(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto out_irq;
|
||||
}
|
||||
|
||||
ret = nouveau_backlight_init(dev);
|
||||
@ -444,6 +457,32 @@ nouveau_card_init(struct drm_device *dev)
|
||||
drm_helper_initial_config(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
out_irq:
|
||||
drm_irq_uninstall(dev);
|
||||
out_fifo:
|
||||
engine->fifo.takedown(dev);
|
||||
out_graph:
|
||||
engine->graph.takedown(dev);
|
||||
out_fb:
|
||||
engine->fb.takedown(dev);
|
||||
out_timer:
|
||||
engine->timer.takedown(dev);
|
||||
out_mc:
|
||||
engine->mc.takedown(dev);
|
||||
out_gpuobj:
|
||||
nouveau_gpuobj_takedown(dev);
|
||||
out_mem:
|
||||
nouveau_mem_close(dev);
|
||||
out_instmem:
|
||||
engine->instmem.takedown(dev);
|
||||
out_gpuobj_early:
|
||||
nouveau_gpuobj_late_takedown(dev);
|
||||
out_bios:
|
||||
nouveau_bios_takedown(dev);
|
||||
out:
|
||||
vga_client_register(dev->pdev, NULL, NULL, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nouveau_card_takedown(struct drm_device *dev)
|
||||
|
@ -143,10 +143,10 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod
|
||||
state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK;
|
||||
|
||||
if (pv->NM2)
|
||||
NV_TRACE(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n",
|
||||
NV_DEBUG_KMS(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n",
|
||||
pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P);
|
||||
else
|
||||
NV_TRACE(dev, "vpll: n %d m %d log2p %d\n",
|
||||
NV_DEBUG_KMS(dev, "vpll: n %d m %d log2p %d\n",
|
||||
pv->N1, pv->M1, pv->log2P);
|
||||
|
||||
nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
|
||||
@ -160,7 +160,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
unsigned char seq1 = 0, crtc17 = 0;
|
||||
unsigned char crtc1A;
|
||||
|
||||
NV_TRACE(dev, "Setting dpms mode %d on CRTC %d\n", mode,
|
||||
NV_DEBUG_KMS(dev, "Setting dpms mode %d on CRTC %d\n", mode,
|
||||
nv_crtc->index);
|
||||
|
||||
if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */
|
||||
@ -603,7 +603,7 @@ nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
NV_DEBUG(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index);
|
||||
NV_DEBUG_KMS(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index);
|
||||
drm_mode_debug_printmodeline(adjusted_mode);
|
||||
|
||||
/* unlock must come after turning off FP_TG_CONTROL in output_prepare */
|
||||
@ -703,7 +703,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
|
||||
NV_DEBUG(crtc->dev, "\n");
|
||||
NV_DEBUG_KMS(crtc->dev, "\n");
|
||||
|
||||
if (!nv_crtc)
|
||||
return;
|
||||
|
@ -205,7 +205,7 @@ out:
|
||||
NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1);
|
||||
|
||||
if (blue == 0x18) {
|
||||
NV_TRACE(dev, "Load detected on head A\n");
|
||||
NV_INFO(dev, "Load detected on head A\n");
|
||||
return connector_status_connected;
|
||||
}
|
||||
|
||||
@ -350,14 +350,10 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
int head = nouveau_crtc(encoder->crtc)->index;
|
||||
|
||||
NV_TRACE(dev, "%s called for encoder %d\n", __func__,
|
||||
nv_encoder->dcb->index);
|
||||
|
||||
if (nv_gf4_disp_arch(dev)) {
|
||||
struct drm_encoder *rebind;
|
||||
uint32_t dac_offset = nv04_dac_output_offset(encoder);
|
||||
@ -466,7 +462,7 @@ static void nv04_dac_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
|
||||
NV_DEBUG(encoder->dev, "\n");
|
||||
NV_DEBUG_KMS(encoder->dev, "\n");
|
||||
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(nv_encoder);
|
||||
|
@ -261,7 +261,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *output_mode = &nv_encoder->mode;
|
||||
uint32_t mode_ratio, panel_ratio;
|
||||
|
||||
NV_DEBUG(dev, "Output mode on CRTC %d:\n", nv_crtc->index);
|
||||
NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index);
|
||||
drm_mode_debug_printmodeline(output_mode);
|
||||
|
||||
/* Initialize the FP registers in this CRTC. */
|
||||
@ -413,7 +413,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
|
||||
struct dcb_entry *dcbe = nv_encoder->dcb;
|
||||
int head = nouveau_crtc(encoder->crtc)->index;
|
||||
|
||||
NV_TRACE(dev, "%s called for encoder %d\n", __func__, nv_encoder->dcb->index);
|
||||
NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
|
||||
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
|
||||
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
|
||||
|
||||
if (dcbe->type == OUTPUT_TMDS)
|
||||
run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
|
||||
@ -550,7 +552,7 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
|
||||
NV_DEBUG(encoder->dev, "\n");
|
||||
NV_DEBUG_KMS(encoder->dev, "\n");
|
||||
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(nv_encoder);
|
||||
|
@ -99,10 +99,11 @@ nv04_display_create(struct drm_device *dev)
|
||||
uint16_t connector[16] = { 0 };
|
||||
int i, ret;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
if (nv_two_heads(dev))
|
||||
nv04_display_store_initial_head_owner(dev);
|
||||
nouveau_hw_save_vga_fonts(dev, 1);
|
||||
|
||||
drm_mode_config_init(dev);
|
||||
drm_mode_create_scaling_mode_property(dev);
|
||||
@ -203,8 +204,6 @@ nv04_display_create(struct drm_device *dev)
|
||||
/* Save previous state */
|
||||
NVLockVgaCrtcs(dev, false);
|
||||
|
||||
nouveau_hw_save_vga_fonts(dev, 1);
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
crtc->funcs->save(crtc);
|
||||
|
||||
@ -223,7 +222,7 @@ nv04_display_destroy(struct drm_device *dev)
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
/* Turn every CRTC off. */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
@ -246,9 +245,9 @@ nv04_display_destroy(struct drm_device *dev)
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
crtc->funcs->restore(crtc);
|
||||
|
||||
nouveau_hw_save_vga_fonts(dev, 0);
|
||||
|
||||
drm_mode_config_cleanup(dev);
|
||||
|
||||
nouveau_hw_save_vga_fonts(dev, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -543,7 +543,7 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass,
|
||||
|
||||
nv_wi32(dev, instance, tmp);
|
||||
nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
|
||||
nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + subc, tmp);
|
||||
nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -389,49 +389,50 @@ struct graph_state {
|
||||
int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
|
||||
int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
|
||||
struct pipe_state pipe_state;
|
||||
uint32_t lma_window[4];
|
||||
};
|
||||
|
||||
#define PIPE_SAVE(dev, state, addr) \
|
||||
do { \
|
||||
int __i; \
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
|
||||
for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
|
||||
state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_RESTORE(dev, state, addr) \
|
||||
do { \
|
||||
int __i; \
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
|
||||
for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \
|
||||
} while (0)
|
||||
|
||||
static void nv10_graph_save_pipe(struct nouveau_channel *chan)
|
||||
{
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct graph_state *pgraph_ctx = chan->pgraph_ctx;
|
||||
struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
|
||||
int i;
|
||||
#define PIPE_SAVE(addr) \
|
||||
do { \
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
|
||||
for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \
|
||||
fifo_pipe_state->pipe_##addr[i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
|
||||
} while (0)
|
||||
struct pipe_state *pipe = &pgraph_ctx->pipe_state;
|
||||
|
||||
PIPE_SAVE(0x4400);
|
||||
PIPE_SAVE(0x0200);
|
||||
PIPE_SAVE(0x6400);
|
||||
PIPE_SAVE(0x6800);
|
||||
PIPE_SAVE(0x6c00);
|
||||
PIPE_SAVE(0x7000);
|
||||
PIPE_SAVE(0x7400);
|
||||
PIPE_SAVE(0x7800);
|
||||
PIPE_SAVE(0x0040);
|
||||
PIPE_SAVE(0x0000);
|
||||
|
||||
#undef PIPE_SAVE
|
||||
PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000);
|
||||
}
|
||||
|
||||
static void nv10_graph_load_pipe(struct nouveau_channel *chan)
|
||||
{
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct graph_state *pgraph_ctx = chan->pgraph_ctx;
|
||||
struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
|
||||
int i;
|
||||
struct pipe_state *pipe = &pgraph_ctx->pipe_state;
|
||||
uint32_t xfmode0, xfmode1;
|
||||
#define PIPE_RESTORE(addr) \
|
||||
do { \
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
|
||||
for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \
|
||||
} while (0)
|
||||
|
||||
int i;
|
||||
|
||||
nouveau_wait_for_idle(dev);
|
||||
/* XXX check haiku comments */
|
||||
@ -457,24 +458,22 @@ static void nv10_graph_load_pipe(struct nouveau_channel *chan)
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
|
||||
|
||||
|
||||
PIPE_RESTORE(0x0200);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
/* restore XFMODE */
|
||||
nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
|
||||
nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
|
||||
PIPE_RESTORE(0x6400);
|
||||
PIPE_RESTORE(0x6800);
|
||||
PIPE_RESTORE(0x6c00);
|
||||
PIPE_RESTORE(0x7000);
|
||||
PIPE_RESTORE(0x7400);
|
||||
PIPE_RESTORE(0x7800);
|
||||
PIPE_RESTORE(0x4400);
|
||||
PIPE_RESTORE(0x0000);
|
||||
PIPE_RESTORE(0x0040);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040);
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
#undef PIPE_RESTORE
|
||||
}
|
||||
|
||||
static void nv10_graph_create_pipe(struct nouveau_channel *chan)
|
||||
@ -832,6 +831,9 @@ int nv10_graph_init(struct drm_device *dev)
|
||||
(1<<31));
|
||||
if (dev_priv->chipset >= 0x17) {
|
||||
nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
|
||||
nv_wr32(dev, 0x400a10, 0x3ff3fb6);
|
||||
nv_wr32(dev, 0x400838, 0x2f8684);
|
||||
nv_wr32(dev, 0x40083c, 0x115f3f);
|
||||
nv_wr32(dev, 0x004006b0, 0x40000020);
|
||||
} else
|
||||
nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
|
||||
@ -867,6 +869,115 @@ void nv10_graph_takedown(struct drm_device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass,
|
||||
int mthd, uint32_t data)
|
||||
{
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct graph_state *ctx = chan->pgraph_ctx;
|
||||
struct pipe_state *pipe = &ctx->pipe_state;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
|
||||
uint32_t xfmode0, xfmode1;
|
||||
int i;
|
||||
|
||||
ctx->lma_window[(mthd - 0x1638) / 4] = data;
|
||||
|
||||
if (mthd != 0x1644)
|
||||
return 0;
|
||||
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
PIPE_SAVE(dev, pipe_0x0040, 0x0040);
|
||||
PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
|
||||
|
||||
PIPE_RESTORE(dev, ctx->lma_window, 0x6790);
|
||||
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
|
||||
xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
|
||||
|
||||
PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
|
||||
PIPE_SAVE(dev, pipe_0x64c0, 0x64c0);
|
||||
PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0);
|
||||
PIPE_SAVE(dev, pipe_0x6a80, 0x6a80);
|
||||
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
|
||||
nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
|
||||
for (i = 0; i < 4; i++)
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
|
||||
for (i = 0; i < 4; i++)
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
|
||||
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
|
||||
for (i = 0; i < 3; i++)
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
|
||||
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
|
||||
for (i = 0; i < 3; i++)
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
|
||||
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
|
||||
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
|
||||
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
PIPE_RESTORE(dev, pipe_0x0040, 0x0040);
|
||||
|
||||
nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
|
||||
nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
|
||||
|
||||
PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0);
|
||||
PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0);
|
||||
PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80);
|
||||
PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
|
||||
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
|
||||
nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
|
||||
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
pgraph->fifo_access(dev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass,
|
||||
int mthd, uint32_t data)
|
||||
{
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
|
||||
nouveau_wait_for_idle(dev);
|
||||
|
||||
nv_wr32(dev, NV10_PGRAPH_DEBUG_4,
|
||||
nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8);
|
||||
nv_wr32(dev, 0x004006b0,
|
||||
nv_rd32(dev, 0x004006b0) | 0x8 << 24);
|
||||
|
||||
pgraph->fifo_access(dev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = {
|
||||
{ 0x1638, nv17_graph_mthd_lma_window },
|
||||
{ 0x163c, nv17_graph_mthd_lma_window },
|
||||
{ 0x1640, nv17_graph_mthd_lma_window },
|
||||
{ 0x1644, nv17_graph_mthd_lma_window },
|
||||
{ 0x1658, nv17_graph_mthd_lma_enable },
|
||||
{}
|
||||
};
|
||||
|
||||
struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
|
||||
{ 0x0030, false, NULL }, /* null */
|
||||
{ 0x0039, false, NULL }, /* m2mf */
|
||||
@ -887,6 +998,6 @@ struct nouveau_pgraph_object_class nv10_graph_grclass[] = {
|
||||
{ 0x0095, false, NULL }, /* multitex_tri */
|
||||
{ 0x0056, false, NULL }, /* celcius (nv10) */
|
||||
{ 0x0096, false, NULL }, /* celcius (nv11) */
|
||||
{ 0x0099, false, NULL }, /* celcius (nv17) */
|
||||
{ 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */
|
||||
{}
|
||||
};
|
||||
|
@ -219,7 +219,7 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode)
|
||||
return;
|
||||
nouveau_encoder(encoder)->last_dpms = mode;
|
||||
|
||||
NV_TRACE(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
|
||||
NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
|
||||
mode, nouveau_encoder(encoder)->dcb->index);
|
||||
|
||||
regs->ptv_200 &= ~1;
|
||||
@ -619,7 +619,7 @@ static void nv17_tv_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
|
||||
|
||||
NV_DEBUG(encoder->dev, "\n");
|
||||
NV_DEBUG_KMS(encoder->dev, "\n");
|
||||
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(tv_enc);
|
||||
|
@ -24,36 +24,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
MODULE_FIRMWARE("nouveau/nv40.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv40.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv41.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv41.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv42.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv42.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv43.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv43.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv44.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv44.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv46.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv46.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv47.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv47.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv49.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv49.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv4a.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv4a.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv4b.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv4b.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv4c.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv4c.ctxvals");
|
||||
MODULE_FIRMWARE("nouveau/nv4e.ctxprog");
|
||||
MODULE_FIRMWARE("nouveau/nv4e.ctxvals");
|
||||
#include "nouveau_grctx.h"
|
||||
|
||||
struct nouveau_channel *
|
||||
nv40_graph_channel(struct drm_device *dev)
|
||||
@ -83,27 +57,30 @@ nv40_graph_create_context(struct nouveau_channel *chan)
|
||||
{
|
||||
struct drm_device *dev = chan->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_gpuobj *ctx;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
int ret;
|
||||
|
||||
/* Allocate a 175KiB block of PRAMIN to store the context. This
|
||||
* is massive overkill for a lot of chipsets, but it should be safe
|
||||
* until we're able to implement this properly (will happen at more
|
||||
* or less the same time we're able to write our own context programs.
|
||||
*/
|
||||
ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&chan->ramin_grctx);
|
||||
ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
|
||||
16, NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&chan->ramin_grctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
ctx = chan->ramin_grctx->gpuobj;
|
||||
|
||||
/* Initialise default context values */
|
||||
dev_priv->engine.instmem.prepare_access(dev, true);
|
||||
nv40_grctx_vals_load(dev, ctx);
|
||||
nv_wo32(dev, ctx, 0, ctx->im_pramin->start);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
if (!pgraph->ctxprog) {
|
||||
struct nouveau_grctx ctx = {};
|
||||
|
||||
ctx.dev = chan->dev;
|
||||
ctx.mode = NOUVEAU_GRCTX_VALS;
|
||||
ctx.data = chan->ramin_grctx->gpuobj;
|
||||
nv40_grctx_init(&ctx);
|
||||
} else {
|
||||
nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj);
|
||||
}
|
||||
nv_wo32(dev, chan->ramin_grctx->gpuobj, 0,
|
||||
chan->ramin_grctx->gpuobj->im_pramin->start);
|
||||
dev_priv->engine.instmem.finish_access(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -204,139 +181,6 @@ nv40_graph_unload_context(struct drm_device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct nouveau_ctxprog {
|
||||
uint32_t signature;
|
||||
uint8_t version;
|
||||
uint16_t length;
|
||||
uint32_t data[];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nouveau_ctxvals {
|
||||
uint32_t signature;
|
||||
uint8_t version;
|
||||
uint32_t length;
|
||||
struct {
|
||||
uint32_t offset;
|
||||
uint32_t value;
|
||||
} data[];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int
|
||||
nv40_grctx_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
const int chipset = dev_priv->chipset;
|
||||
const struct firmware *fw;
|
||||
const struct nouveau_ctxprog *cp;
|
||||
const struct nouveau_ctxvals *cv;
|
||||
char name[32];
|
||||
int ret, i;
|
||||
|
||||
pgraph->accel_blocked = true;
|
||||
|
||||
if (!pgraph->ctxprog) {
|
||||
sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
|
||||
ret = request_firmware(&fw, name, &dev->pdev->dev);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL);
|
||||
if (!pgraph->ctxprog) {
|
||||
NV_ERROR(dev, "OOM copying ctxprog\n");
|
||||
release_firmware(fw);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(pgraph->ctxprog, fw->data, fw->size);
|
||||
|
||||
cp = pgraph->ctxprog;
|
||||
if (le32_to_cpu(cp->signature) != 0x5043564e ||
|
||||
cp->version != 0 ||
|
||||
le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
|
||||
NV_ERROR(dev, "ctxprog invalid\n");
|
||||
release_firmware(fw);
|
||||
nv40_grctx_fini(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
release_firmware(fw);
|
||||
}
|
||||
|
||||
if (!pgraph->ctxvals) {
|
||||
sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
|
||||
ret = request_firmware(&fw, name, &dev->pdev->dev);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
|
||||
nv40_grctx_fini(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL);
|
||||
if (!pgraph->ctxprog) {
|
||||
NV_ERROR(dev, "OOM copying ctxprog\n");
|
||||
release_firmware(fw);
|
||||
nv40_grctx_fini(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(pgraph->ctxvals, fw->data, fw->size);
|
||||
|
||||
cv = (void *)pgraph->ctxvals;
|
||||
if (le32_to_cpu(cv->signature) != 0x5643564e ||
|
||||
cv->version != 0 ||
|
||||
le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
|
||||
NV_ERROR(dev, "ctxvals invalid\n");
|
||||
release_firmware(fw);
|
||||
nv40_grctx_fini(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
release_firmware(fw);
|
||||
}
|
||||
|
||||
cp = pgraph->ctxprog;
|
||||
|
||||
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
|
||||
for (i = 0; i < le16_to_cpu(cp->length); i++)
|
||||
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
|
||||
le32_to_cpu(cp->data[i]));
|
||||
|
||||
pgraph->accel_blocked = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nv40_grctx_fini(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
|
||||
if (pgraph->ctxprog) {
|
||||
kfree(pgraph->ctxprog);
|
||||
pgraph->ctxprog = NULL;
|
||||
}
|
||||
|
||||
if (pgraph->ctxvals) {
|
||||
kfree(pgraph->ctxprog);
|
||||
pgraph->ctxvals = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
|
||||
struct nouveau_ctxvals *cv = pgraph->ctxvals;
|
||||
int i;
|
||||
|
||||
if (!cv)
|
||||
return;
|
||||
|
||||
for (i = 0; i < le32_to_cpu(cv->length); i++)
|
||||
nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
|
||||
le32_to_cpu(cv->data[i].value));
|
||||
}
|
||||
|
||||
/*
|
||||
* G70 0x47
|
||||
* G71 0x49
|
||||
@ -359,7 +203,26 @@ nv40_graph_init(struct drm_device *dev)
|
||||
nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
|
||||
NV_PMC_ENABLE_PGRAPH);
|
||||
|
||||
nv40_grctx_init(dev);
|
||||
if (nouveau_ctxfw) {
|
||||
nouveau_grctx_prog_load(dev);
|
||||
dev_priv->engine.graph.grctx_size = 175 * 1024;
|
||||
}
|
||||
|
||||
if (!dev_priv->engine.graph.ctxprog) {
|
||||
struct nouveau_grctx ctx = {};
|
||||
uint32_t cp[256];
|
||||
|
||||
ctx.dev = dev;
|
||||
ctx.mode = NOUVEAU_GRCTX_PROG;
|
||||
ctx.data = cp;
|
||||
ctx.ctxprog_max = 256;
|
||||
nv40_grctx_init(&ctx);
|
||||
dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
|
||||
|
||||
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
|
||||
for (i = 0; i < ctx.ctxprog_len; i++)
|
||||
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
|
||||
}
|
||||
|
||||
/* No context present currently */
|
||||
nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
|
||||
@ -539,6 +402,7 @@ nv40_graph_init(struct drm_device *dev)
|
||||
|
||||
void nv40_graph_takedown(struct drm_device *dev)
|
||||
{
|
||||
nouveau_grctx_fini(dev);
|
||||
}
|
||||
|
||||
struct nouveau_pgraph_object_class nv40_graph_grclass[] = {
|
||||
|
678
drivers/gpu/drm/nouveau/nv40_grctx.c
Normal file
678
drivers/gpu/drm/nouveau/nv40_grctx.c
Normal file
@ -0,0 +1,678 @@
|
||||
/*
|
||||
* Copyright 2009 Red Hat Inc.
|
||||
*
|
||||
* 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: Ben Skeggs
|
||||
*/
|
||||
|
||||
/* NVIDIA context programs handle a number of other conditions which are
|
||||
* not implemented in our versions. It's not clear why NVIDIA context
|
||||
* programs have this code, nor whether it's strictly necessary for
|
||||
* correct operation. We'll implement additional handling if/when we
|
||||
* discover it's necessary.
|
||||
*
|
||||
* - On context save, NVIDIA set 0x400314 bit 0 to 1 if the "3D state"
|
||||
* flag is set, this gets saved into the context.
|
||||
* - On context save, the context program for all cards load nsource
|
||||
* into a flag register and check for ILLEGAL_MTHD. If it's set,
|
||||
* opcode 0x60000d is called before resuming normal operation.
|
||||
* - Some context programs check more conditions than the above. NV44
|
||||
* checks: ((nsource & 0x0857) || (0x400718 & 0x0100) || (intr & 0x0001))
|
||||
* and calls 0x60000d before resuming normal operation.
|
||||
* - At the very beginning of NVIDIA's context programs, flag 9 is checked
|
||||
* and if true 0x800001 is called with count=0, pos=0, the flag is cleared
|
||||
* and then the ctxprog is aborted. It looks like a complicated NOP,
|
||||
* its purpose is unknown.
|
||||
* - In the section of code that loads the per-vs state, NVIDIA check
|
||||
* flag 10. If it's set, they only transfer the small 0x300 byte block
|
||||
* of state + the state for a single vs as opposed to the state for
|
||||
* all vs units. It doesn't seem likely that it'll occur in normal
|
||||
* operation, especially seeing as it appears NVIDIA may have screwed
|
||||
* up the ctxprogs for some cards and have an invalid instruction
|
||||
* rather than a cp_lsr(ctx, dwords_for_1_vs_unit) instruction.
|
||||
* - There's a number of places where context offset 0 (where we place
|
||||
* the PRAMIN offset of the context) is loaded into either 0x408000,
|
||||
* 0x408004 or 0x408008. Not sure what's up there either.
|
||||
* - The ctxprogs for some cards save 0x400a00 again during the cleanup
|
||||
* path for auto-loadctx.
|
||||
*/
|
||||
|
||||
#define CP_FLAG_CLEAR 0
|
||||
#define CP_FLAG_SET 1
|
||||
#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0)
|
||||
#define CP_FLAG_SWAP_DIRECTION_LOAD 0
|
||||
#define CP_FLAG_SWAP_DIRECTION_SAVE 1
|
||||
#define CP_FLAG_USER_SAVE ((0 * 32) + 5)
|
||||
#define CP_FLAG_USER_SAVE_NOT_PENDING 0
|
||||
#define CP_FLAG_USER_SAVE_PENDING 1
|
||||
#define CP_FLAG_USER_LOAD ((0 * 32) + 6)
|
||||
#define CP_FLAG_USER_LOAD_NOT_PENDING 0
|
||||
#define CP_FLAG_USER_LOAD_PENDING 1
|
||||
#define CP_FLAG_STATUS ((3 * 32) + 0)
|
||||
#define CP_FLAG_STATUS_IDLE 0
|
||||
#define CP_FLAG_STATUS_BUSY 1
|
||||
#define CP_FLAG_AUTO_SAVE ((3 * 32) + 4)
|
||||
#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0
|
||||
#define CP_FLAG_AUTO_SAVE_PENDING 1
|
||||
#define CP_FLAG_AUTO_LOAD ((3 * 32) + 5)
|
||||
#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
|
||||
#define CP_FLAG_AUTO_LOAD_PENDING 1
|
||||
#define CP_FLAG_UNK54 ((3 * 32) + 6)
|
||||
#define CP_FLAG_UNK54_CLEAR 0
|
||||
#define CP_FLAG_UNK54_SET 1
|
||||
#define CP_FLAG_ALWAYS ((3 * 32) + 8)
|
||||
#define CP_FLAG_ALWAYS_FALSE 0
|
||||
#define CP_FLAG_ALWAYS_TRUE 1
|
||||
#define CP_FLAG_UNK57 ((3 * 32) + 9)
|
||||
#define CP_FLAG_UNK57_CLEAR 0
|
||||
#define CP_FLAG_UNK57_SET 1
|
||||
|
||||
#define CP_CTX 0x00100000
|
||||
#define CP_CTX_COUNT 0x000fc000
|
||||
#define CP_CTX_COUNT_SHIFT 14
|
||||
#define CP_CTX_REG 0x00003fff
|
||||
#define CP_LOAD_SR 0x00200000
|
||||
#define CP_LOAD_SR_VALUE 0x000fffff
|
||||
#define CP_BRA 0x00400000
|
||||
#define CP_BRA_IP 0x0000ff00
|
||||
#define CP_BRA_IP_SHIFT 8
|
||||
#define CP_BRA_IF_CLEAR 0x00000080
|
||||
#define CP_BRA_FLAG 0x0000007f
|
||||
#define CP_WAIT 0x00500000
|
||||
#define CP_WAIT_SET 0x00000080
|
||||
#define CP_WAIT_FLAG 0x0000007f
|
||||
#define CP_SET 0x00700000
|
||||
#define CP_SET_1 0x00000080
|
||||
#define CP_SET_FLAG 0x0000007f
|
||||
#define CP_NEXT_TO_SWAP 0x00600007
|
||||
#define CP_NEXT_TO_CURRENT 0x00600009
|
||||
#define CP_SET_CONTEXT_POINTER 0x0060000a
|
||||
#define CP_END 0x0060000e
|
||||
#define CP_LOAD_MAGIC_UNK01 0x00800001 /* unknown */
|
||||
#define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */
|
||||
#define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */
|
||||
|
||||
#include "drmP.h"
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_grctx.h"
|
||||
|
||||
/* TODO:
|
||||
* - get vs count from 0x1540
|
||||
* - document unimplemented bits compared to nvidia
|
||||
* - nsource handling
|
||||
* - R0 & 0x0200 handling
|
||||
* - single-vs handling
|
||||
* - 400314 bit 0
|
||||
*/
|
||||
|
||||
static int
|
||||
nv40_graph_4097(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
if ((dev_priv->chipset & 0xf0) == 0x60)
|
||||
return 0;
|
||||
|
||||
return !!(0x0baf & (1 << dev_priv->chipset));
|
||||
}
|
||||
|
||||
static int
|
||||
nv40_graph_vs_count(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x47:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
return 8;
|
||||
case 0x40:
|
||||
return 6;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
return 5;
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
case 0x46:
|
||||
case 0x4a:
|
||||
return 3;
|
||||
case 0x4c:
|
||||
case 0x4e:
|
||||
case 0x67:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum cp_label {
|
||||
cp_check_load = 1,
|
||||
cp_setup_auto_load,
|
||||
cp_setup_load,
|
||||
cp_setup_save,
|
||||
cp_swap_state,
|
||||
cp_swap_state3d_3_is_save,
|
||||
cp_prepare_exit,
|
||||
cp_exit,
|
||||
};
|
||||
|
||||
static void
|
||||
nv40_graph_construct_general(struct nouveau_grctx *ctx)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
|
||||
int i;
|
||||
|
||||
cp_ctx(ctx, 0x4000a4, 1);
|
||||
gr_def(ctx, 0x4000a4, 0x00000008);
|
||||
cp_ctx(ctx, 0x400144, 58);
|
||||
gr_def(ctx, 0x400144, 0x00000001);
|
||||
cp_ctx(ctx, 0x400314, 1);
|
||||
gr_def(ctx, 0x400314, 0x00000000);
|
||||
cp_ctx(ctx, 0x400400, 10);
|
||||
cp_ctx(ctx, 0x400480, 10);
|
||||
cp_ctx(ctx, 0x400500, 19);
|
||||
gr_def(ctx, 0x400514, 0x00040000);
|
||||
gr_def(ctx, 0x400524, 0x55555555);
|
||||
gr_def(ctx, 0x400528, 0x55555555);
|
||||
gr_def(ctx, 0x40052c, 0x55555555);
|
||||
gr_def(ctx, 0x400530, 0x55555555);
|
||||
cp_ctx(ctx, 0x400560, 6);
|
||||
gr_def(ctx, 0x400568, 0x0000ffff);
|
||||
gr_def(ctx, 0x40056c, 0x0000ffff);
|
||||
cp_ctx(ctx, 0x40057c, 5);
|
||||
cp_ctx(ctx, 0x400710, 3);
|
||||
gr_def(ctx, 0x400710, 0x20010001);
|
||||
gr_def(ctx, 0x400714, 0x0f73ef00);
|
||||
cp_ctx(ctx, 0x400724, 1);
|
||||
gr_def(ctx, 0x400724, 0x02008821);
|
||||
cp_ctx(ctx, 0x400770, 3);
|
||||
if (dev_priv->chipset == 0x40) {
|
||||
cp_ctx(ctx, 0x400814, 4);
|
||||
cp_ctx(ctx, 0x400828, 5);
|
||||
cp_ctx(ctx, 0x400840, 5);
|
||||
gr_def(ctx, 0x400850, 0x00000040);
|
||||
cp_ctx(ctx, 0x400858, 4);
|
||||
gr_def(ctx, 0x400858, 0x00000040);
|
||||
gr_def(ctx, 0x40085c, 0x00000040);
|
||||
gr_def(ctx, 0x400864, 0x80000000);
|
||||
cp_ctx(ctx, 0x40086c, 9);
|
||||
gr_def(ctx, 0x40086c, 0x80000000);
|
||||
gr_def(ctx, 0x400870, 0x80000000);
|
||||
gr_def(ctx, 0x400874, 0x80000000);
|
||||
gr_def(ctx, 0x400878, 0x80000000);
|
||||
gr_def(ctx, 0x400888, 0x00000040);
|
||||
gr_def(ctx, 0x40088c, 0x80000000);
|
||||
cp_ctx(ctx, 0x4009c0, 8);
|
||||
gr_def(ctx, 0x4009cc, 0x80000000);
|
||||
gr_def(ctx, 0x4009dc, 0x80000000);
|
||||
} else {
|
||||
cp_ctx(ctx, 0x400840, 20);
|
||||
if (!nv40_graph_4097(ctx->dev)) {
|
||||
for (i = 0; i < 8; i++)
|
||||
gr_def(ctx, 0x400860 + (i * 4), 0x00000001);
|
||||
}
|
||||
gr_def(ctx, 0x400880, 0x00000040);
|
||||
gr_def(ctx, 0x400884, 0x00000040);
|
||||
gr_def(ctx, 0x400888, 0x00000040);
|
||||
cp_ctx(ctx, 0x400894, 11);
|
||||
gr_def(ctx, 0x400894, 0x00000040);
|
||||
if (nv40_graph_4097(ctx->dev)) {
|
||||
for (i = 0; i < 8; i++)
|
||||
gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000);
|
||||
}
|
||||
cp_ctx(ctx, 0x4008e0, 2);
|
||||
cp_ctx(ctx, 0x4008f8, 2);
|
||||
if (dev_priv->chipset == 0x4c ||
|
||||
(dev_priv->chipset & 0xf0) == 0x60)
|
||||
cp_ctx(ctx, 0x4009f8, 1);
|
||||
}
|
||||
cp_ctx(ctx, 0x400a00, 73);
|
||||
gr_def(ctx, 0x400b0c, 0x0b0b0b0c);
|
||||
cp_ctx(ctx, 0x401000, 4);
|
||||
cp_ctx(ctx, 0x405004, 1);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x47:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
cp_ctx(ctx, 0x403448, 1);
|
||||
gr_def(ctx, 0x403448, 0x00001010);
|
||||
break;
|
||||
default:
|
||||
cp_ctx(ctx, 0x403440, 1);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x40:
|
||||
gr_def(ctx, 0x403440, 0x00000010);
|
||||
break;
|
||||
case 0x44:
|
||||
case 0x46:
|
||||
case 0x4a:
|
||||
gr_def(ctx, 0x403440, 0x00003010);
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x4c:
|
||||
case 0x4e:
|
||||
case 0x67:
|
||||
default:
|
||||
gr_def(ctx, 0x403440, 0x00001010);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
|
||||
int i;
|
||||
|
||||
if (dev_priv->chipset == 0x40) {
|
||||
cp_ctx(ctx, 0x401880, 51);
|
||||
gr_def(ctx, 0x401940, 0x00000100);
|
||||
} else
|
||||
if (dev_priv->chipset == 0x46 || dev_priv->chipset == 0x47 ||
|
||||
dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) {
|
||||
cp_ctx(ctx, 0x401880, 32);
|
||||
for (i = 0; i < 16; i++)
|
||||
gr_def(ctx, 0x401880 + (i * 4), 0x00000111);
|
||||
if (dev_priv->chipset == 0x46)
|
||||
cp_ctx(ctx, 0x401900, 16);
|
||||
cp_ctx(ctx, 0x401940, 3);
|
||||
}
|
||||
cp_ctx(ctx, 0x40194c, 18);
|
||||
gr_def(ctx, 0x401954, 0x00000111);
|
||||
gr_def(ctx, 0x401958, 0x00080060);
|
||||
gr_def(ctx, 0x401974, 0x00000080);
|
||||
gr_def(ctx, 0x401978, 0xffff0000);
|
||||
gr_def(ctx, 0x40197c, 0x00000001);
|
||||
gr_def(ctx, 0x401990, 0x46400000);
|
||||
if (dev_priv->chipset == 0x40) {
|
||||
cp_ctx(ctx, 0x4019a0, 2);
|
||||
cp_ctx(ctx, 0x4019ac, 5);
|
||||
} else {
|
||||
cp_ctx(ctx, 0x4019a0, 1);
|
||||
cp_ctx(ctx, 0x4019b4, 3);
|
||||
}
|
||||
gr_def(ctx, 0x4019bc, 0xffff0000);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
cp_ctx(ctx, 0x4019c0, 18);
|
||||
for (i = 0; i < 16; i++)
|
||||
gr_def(ctx, 0x4019c0 + (i * 4), 0x88888888);
|
||||
break;
|
||||
}
|
||||
cp_ctx(ctx, 0x401a08, 8);
|
||||
gr_def(ctx, 0x401a10, 0x0fff0000);
|
||||
gr_def(ctx, 0x401a14, 0x0fff0000);
|
||||
gr_def(ctx, 0x401a1c, 0x00011100);
|
||||
cp_ctx(ctx, 0x401a2c, 4);
|
||||
cp_ctx(ctx, 0x401a44, 26);
|
||||
for (i = 0; i < 16; i++)
|
||||
gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000);
|
||||
gr_def(ctx, 0x401a8c, 0x4b7fffff);
|
||||
if (dev_priv->chipset == 0x40) {
|
||||
cp_ctx(ctx, 0x401ab8, 3);
|
||||
} else {
|
||||
cp_ctx(ctx, 0x401ab8, 1);
|
||||
cp_ctx(ctx, 0x401ac0, 1);
|
||||
}
|
||||
cp_ctx(ctx, 0x401ad0, 8);
|
||||
gr_def(ctx, 0x401ad0, 0x30201000);
|
||||
gr_def(ctx, 0x401ad4, 0x70605040);
|
||||
gr_def(ctx, 0x401ad8, 0xb8a89888);
|
||||
gr_def(ctx, 0x401adc, 0xf8e8d8c8);
|
||||
cp_ctx(ctx, 0x401b10, dev_priv->chipset == 0x40 ? 2 : 1);
|
||||
gr_def(ctx, 0x401b10, 0x40100000);
|
||||
cp_ctx(ctx, 0x401b18, dev_priv->chipset == 0x40 ? 6 : 5);
|
||||
gr_def(ctx, 0x401b28, dev_priv->chipset == 0x40 ?
|
||||
0x00000004 : 0x00000000);
|
||||
cp_ctx(ctx, 0x401b30, 25);
|
||||
gr_def(ctx, 0x401b34, 0x0000ffff);
|
||||
gr_def(ctx, 0x401b68, 0x435185d6);
|
||||
gr_def(ctx, 0x401b6c, 0x2155b699);
|
||||
gr_def(ctx, 0x401b70, 0xfedcba98);
|
||||
gr_def(ctx, 0x401b74, 0x00000098);
|
||||
gr_def(ctx, 0x401b84, 0xffffffff);
|
||||
gr_def(ctx, 0x401b88, 0x00ff7000);
|
||||
gr_def(ctx, 0x401b8c, 0x0000ffff);
|
||||
if (dev_priv->chipset != 0x44 && dev_priv->chipset != 0x4a &&
|
||||
dev_priv->chipset != 0x4e)
|
||||
cp_ctx(ctx, 0x401b94, 1);
|
||||
cp_ctx(ctx, 0x401b98, 8);
|
||||
gr_def(ctx, 0x401b9c, 0x00ff0000);
|
||||
cp_ctx(ctx, 0x401bc0, 9);
|
||||
gr_def(ctx, 0x401be0, 0x00ffff00);
|
||||
cp_ctx(ctx, 0x401c00, 192);
|
||||
for (i = 0; i < 16; i++) { /* fragment texture units */
|
||||
gr_def(ctx, 0x401c40 + (i * 4), 0x00018488);
|
||||
gr_def(ctx, 0x401c80 + (i * 4), 0x00028202);
|
||||
gr_def(ctx, 0x401d00 + (i * 4), 0x0000aae4);
|
||||
gr_def(ctx, 0x401d40 + (i * 4), 0x01012000);
|
||||
gr_def(ctx, 0x401d80 + (i * 4), 0x00080008);
|
||||
gr_def(ctx, 0x401e00 + (i * 4), 0x00100008);
|
||||
}
|
||||
for (i = 0; i < 4; i++) { /* vertex texture units */
|
||||
gr_def(ctx, 0x401e90 + (i * 4), 0x0001bc80);
|
||||
gr_def(ctx, 0x401ea0 + (i * 4), 0x00000202);
|
||||
gr_def(ctx, 0x401ec0 + (i * 4), 0x00000008);
|
||||
gr_def(ctx, 0x401ee0 + (i * 4), 0x00080008);
|
||||
}
|
||||
cp_ctx(ctx, 0x400f5c, 3);
|
||||
gr_def(ctx, 0x400f5c, 0x00000002);
|
||||
cp_ctx(ctx, 0x400f84, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
|
||||
int i;
|
||||
|
||||
cp_ctx(ctx, 0x402000, 1);
|
||||
cp_ctx(ctx, 0x402404, dev_priv->chipset == 0x40 ? 1 : 2);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x40:
|
||||
gr_def(ctx, 0x402404, 0x00000001);
|
||||
break;
|
||||
case 0x4c:
|
||||
case 0x4e:
|
||||
case 0x67:
|
||||
gr_def(ctx, 0x402404, 0x00000020);
|
||||
break;
|
||||
case 0x46:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
gr_def(ctx, 0x402404, 0x00000421);
|
||||
break;
|
||||
default:
|
||||
gr_def(ctx, 0x402404, 0x00000021);
|
||||
}
|
||||
if (dev_priv->chipset != 0x40)
|
||||
gr_def(ctx, 0x402408, 0x030c30c3);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x44:
|
||||
case 0x46:
|
||||
case 0x4a:
|
||||
case 0x4c:
|
||||
case 0x4e:
|
||||
case 0x67:
|
||||
cp_ctx(ctx, 0x402440, 1);
|
||||
gr_def(ctx, 0x402440, 0x00011001);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cp_ctx(ctx, 0x402480, dev_priv->chipset == 0x40 ? 8 : 9);
|
||||
gr_def(ctx, 0x402488, 0x3e020200);
|
||||
gr_def(ctx, 0x40248c, 0x00ffffff);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x40:
|
||||
gr_def(ctx, 0x402490, 0x60103f00);
|
||||
break;
|
||||
case 0x47:
|
||||
gr_def(ctx, 0x402490, 0x40103f00);
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
gr_def(ctx, 0x402490, 0x20103f00);
|
||||
break;
|
||||
default:
|
||||
gr_def(ctx, 0x402490, 0x0c103f00);
|
||||
break;
|
||||
}
|
||||
gr_def(ctx, 0x40249c, dev_priv->chipset <= 0x43 ?
|
||||
0x00020000 : 0x00040000);
|
||||
cp_ctx(ctx, 0x402500, 31);
|
||||
gr_def(ctx, 0x402530, 0x00008100);
|
||||
if (dev_priv->chipset == 0x40)
|
||||
cp_ctx(ctx, 0x40257c, 6);
|
||||
cp_ctx(ctx, 0x402594, 16);
|
||||
cp_ctx(ctx, 0x402800, 17);
|
||||
gr_def(ctx, 0x402800, 0x00000001);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x47:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
cp_ctx(ctx, 0x402864, 1);
|
||||
gr_def(ctx, 0x402864, 0x00001001);
|
||||
cp_ctx(ctx, 0x402870, 3);
|
||||
gr_def(ctx, 0x402878, 0x00000003);
|
||||
if (dev_priv->chipset != 0x47) { /* belong at end!! */
|
||||
cp_ctx(ctx, 0x402900, 1);
|
||||
cp_ctx(ctx, 0x402940, 1);
|
||||
cp_ctx(ctx, 0x402980, 1);
|
||||
cp_ctx(ctx, 0x4029c0, 1);
|
||||
cp_ctx(ctx, 0x402a00, 1);
|
||||
cp_ctx(ctx, 0x402a40, 1);
|
||||
cp_ctx(ctx, 0x402a80, 1);
|
||||
cp_ctx(ctx, 0x402ac0, 1);
|
||||
}
|
||||
break;
|
||||
case 0x40:
|
||||
cp_ctx(ctx, 0x402844, 1);
|
||||
gr_def(ctx, 0x402844, 0x00000001);
|
||||
cp_ctx(ctx, 0x402850, 1);
|
||||
break;
|
||||
default:
|
||||
cp_ctx(ctx, 0x402844, 1);
|
||||
gr_def(ctx, 0x402844, 0x00001001);
|
||||
cp_ctx(ctx, 0x402850, 2);
|
||||
gr_def(ctx, 0x402854, 0x00000003);
|
||||
break;
|
||||
}
|
||||
|
||||
cp_ctx(ctx, 0x402c00, 4);
|
||||
gr_def(ctx, 0x402c00, dev_priv->chipset == 0x40 ?
|
||||
0x80800001 : 0x00888001);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x47:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
cp_ctx(ctx, 0x402c20, 40);
|
||||
for (i = 0; i < 32; i++)
|
||||
gr_def(ctx, 0x402c40 + (i * 4), 0xffffffff);
|
||||
cp_ctx(ctx, 0x4030b8, 13);
|
||||
gr_def(ctx, 0x4030dc, 0x00000005);
|
||||
gr_def(ctx, 0x4030e8, 0x0000ffff);
|
||||
break;
|
||||
default:
|
||||
cp_ctx(ctx, 0x402c10, 4);
|
||||
if (dev_priv->chipset == 0x40)
|
||||
cp_ctx(ctx, 0x402c20, 36);
|
||||
else
|
||||
if (dev_priv->chipset <= 0x42)
|
||||
cp_ctx(ctx, 0x402c20, 24);
|
||||
else
|
||||
if (dev_priv->chipset <= 0x4a)
|
||||
cp_ctx(ctx, 0x402c20, 16);
|
||||
else
|
||||
cp_ctx(ctx, 0x402c20, 8);
|
||||
cp_ctx(ctx, 0x402cb0, dev_priv->chipset == 0x40 ? 12 : 13);
|
||||
gr_def(ctx, 0x402cd4, 0x00000005);
|
||||
if (dev_priv->chipset != 0x40)
|
||||
gr_def(ctx, 0x402ce0, 0x0000ffff);
|
||||
break;
|
||||
}
|
||||
|
||||
cp_ctx(ctx, 0x403400, dev_priv->chipset == 0x40 ? 4 : 3);
|
||||
cp_ctx(ctx, 0x403410, dev_priv->chipset == 0x40 ? 4 : 3);
|
||||
cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->dev));
|
||||
for (i = 0; i < nv40_graph_vs_count(ctx->dev); i++)
|
||||
gr_def(ctx, 0x403420 + (i * 4), 0x00005555);
|
||||
|
||||
if (dev_priv->chipset != 0x40) {
|
||||
cp_ctx(ctx, 0x403600, 1);
|
||||
gr_def(ctx, 0x403600, 0x00000001);
|
||||
}
|
||||
cp_ctx(ctx, 0x403800, 1);
|
||||
|
||||
cp_ctx(ctx, 0x403c18, 1);
|
||||
gr_def(ctx, 0x403c18, 0x00000001);
|
||||
switch (dev_priv->chipset) {
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
case 0x49:
|
||||
case 0x4b:
|
||||
cp_ctx(ctx, 0x405018, 1);
|
||||
gr_def(ctx, 0x405018, 0x08e00001);
|
||||
cp_ctx(ctx, 0x405c24, 1);
|
||||
gr_def(ctx, 0x405c24, 0x000e3000);
|
||||
break;
|
||||
}
|
||||
if (dev_priv->chipset != 0x4e)
|
||||
cp_ctx(ctx, 0x405800, 11);
|
||||
cp_ctx(ctx, 0x407000, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
|
||||
{
|
||||
int len = nv40_graph_4097(ctx->dev) ? 0x0684 : 0x0084;
|
||||
|
||||
cp_out (ctx, 0x300000);
|
||||
cp_lsr (ctx, len - 4);
|
||||
cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save);
|
||||
cp_lsr (ctx, len);
|
||||
cp_name(ctx, cp_swap_state3d_3_is_save);
|
||||
cp_out (ctx, 0x800001);
|
||||
|
||||
ctx->ctxvals_pos += len;
|
||||
}
|
||||
|
||||
static void
|
||||
nv40_graph_construct_shader(struct nouveau_grctx *ctx)
|
||||
{
|
||||
struct drm_device *dev = ctx->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_gpuobj *obj = ctx->data;
|
||||
int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset;
|
||||
int offset, i;
|
||||
|
||||
vs_nr = nv40_graph_vs_count(ctx->dev);
|
||||
vs_nr_b0 = 363;
|
||||
vs_nr_b1 = dev_priv->chipset == 0x40 ? 128 : 64;
|
||||
if (dev_priv->chipset == 0x40) {
|
||||
b0_offset = 0x2200/4; /* 33a0 */
|
||||
b1_offset = 0x55a0/4; /* 1500 */
|
||||
vs_len = 0x6aa0/4;
|
||||
} else
|
||||
if (dev_priv->chipset == 0x41 || dev_priv->chipset == 0x42) {
|
||||
b0_offset = 0x2200/4; /* 2200 */
|
||||
b1_offset = 0x4400/4; /* 0b00 */
|
||||
vs_len = 0x4f00/4;
|
||||
} else {
|
||||
b0_offset = 0x1d40/4; /* 2200 */
|
||||
b1_offset = 0x3f40/4; /* 0b00 : 0a40 */
|
||||
vs_len = nv40_graph_4097(dev) ? 0x4a40/4 : 0x4980/4;
|
||||
}
|
||||
|
||||
cp_lsr(ctx, vs_len * vs_nr + 0x300/4);
|
||||
cp_out(ctx, nv40_graph_4097(dev) ? 0x800041 : 0x800029);
|
||||
|
||||
offset = ctx->ctxvals_pos;
|
||||
ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len));
|
||||
|
||||
if (ctx->mode != NOUVEAU_GRCTX_VALS)
|
||||
return;
|
||||
|
||||
offset += 0x0280/4;
|
||||
for (i = 0; i < 16; i++, offset += 2)
|
||||
nv_wo32(dev, obj, offset, 0x3f800000);
|
||||
|
||||
for (vs = 0; vs < vs_nr; vs++, offset += vs_len) {
|
||||
for (i = 0; i < vs_nr_b0 * 6; i += 6)
|
||||
nv_wo32(dev, obj, offset + b0_offset + i, 0x00000001);
|
||||
for (i = 0; i < vs_nr_b1 * 4; i += 4)
|
||||
nv_wo32(dev, obj, offset + b1_offset + i, 0x3f800000);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nv40_grctx_init(struct nouveau_grctx *ctx)
|
||||
{
|
||||
/* decide whether we're loading/unloading the context */
|
||||
cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
|
||||
cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save);
|
||||
|
||||
cp_name(ctx, cp_check_load);
|
||||
cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load);
|
||||
cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load);
|
||||
cp_bra (ctx, ALWAYS, TRUE, cp_exit);
|
||||
|
||||
/* setup for context load */
|
||||
cp_name(ctx, cp_setup_auto_load);
|
||||
cp_wait(ctx, STATUS, IDLE);
|
||||
cp_out (ctx, CP_NEXT_TO_SWAP);
|
||||
cp_name(ctx, cp_setup_load);
|
||||
cp_wait(ctx, STATUS, IDLE);
|
||||
cp_set (ctx, SWAP_DIRECTION, LOAD);
|
||||
cp_out (ctx, 0x00910880); /* ?? */
|
||||
cp_out (ctx, 0x00901ffe); /* ?? */
|
||||
cp_out (ctx, 0x01940000); /* ?? */
|
||||
cp_lsr (ctx, 0x20);
|
||||
cp_out (ctx, 0x0060000b); /* ?? */
|
||||
cp_wait(ctx, UNK57, CLEAR);
|
||||
cp_out (ctx, 0x0060000c); /* ?? */
|
||||
cp_bra (ctx, ALWAYS, TRUE, cp_swap_state);
|
||||
|
||||
/* setup for context save */
|
||||
cp_name(ctx, cp_setup_save);
|
||||
cp_set (ctx, SWAP_DIRECTION, SAVE);
|
||||
|
||||
/* general PGRAPH state */
|
||||
cp_name(ctx, cp_swap_state);
|
||||
cp_pos (ctx, 0x00020/4);
|
||||
nv40_graph_construct_general(ctx);
|
||||
cp_wait(ctx, STATUS, IDLE);
|
||||
|
||||
/* 3D state, block 1 */
|
||||
cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit);
|
||||
nv40_graph_construct_state3d(ctx);
|
||||
cp_wait(ctx, STATUS, IDLE);
|
||||
|
||||
/* 3D state, block 2 */
|
||||
nv40_graph_construct_state3d_2(ctx);
|
||||
|
||||
/* Some other block of "random" state */
|
||||
nv40_graph_construct_state3d_3(ctx);
|
||||
|
||||
/* Per-vertex shader state */
|
||||
cp_pos (ctx, ctx->ctxvals_pos);
|
||||
nv40_graph_construct_shader(ctx);
|
||||
|
||||
/* pre-exit state updates */
|
||||
cp_name(ctx, cp_prepare_exit);
|
||||
cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
|
||||
cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
|
||||
cp_out (ctx, CP_NEXT_TO_CURRENT);
|
||||
|
||||
cp_name(ctx, cp_exit);
|
||||
cp_set (ctx, USER_SAVE, NOT_PENDING);
|
||||
cp_set (ctx, USER_LOAD, NOT_PENDING);
|
||||
cp_out (ctx, CP_END);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ nv50_crtc_lut_load(struct drm_crtc *crtc)
|
||||
void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
|
||||
int i;
|
||||
|
||||
NV_DEBUG(crtc->dev, "\n");
|
||||
NV_DEBUG_KMS(crtc->dev, "\n");
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0);
|
||||
@ -68,8 +68,8 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
|
||||
struct nouveau_channel *evo = dev_priv->evo;
|
||||
int index = nv_crtc->index, ret;
|
||||
|
||||
NV_DEBUG(dev, "index %d\n", nv_crtc->index);
|
||||
NV_DEBUG(dev, "%s\n", blanked ? "blanked" : "unblanked");
|
||||
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
||||
NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked");
|
||||
|
||||
if (blanked) {
|
||||
nv_crtc->cursor.hide(nv_crtc, false);
|
||||
@ -139,7 +139,7 @@ nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update)
|
||||
struct nouveau_channel *evo = dev_priv->evo;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
ret = RING_SPACE(evo, 2 + (update ? 2 : 0));
|
||||
if (ret) {
|
||||
@ -193,7 +193,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
|
||||
uint32_t outX, outY, horiz, vert;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
switch (scaling_mode) {
|
||||
case DRM_MODE_SCALE_NONE:
|
||||
@ -301,7 +301,7 @@ nv50_crtc_destroy(struct drm_crtc *crtc)
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
if (!crtc)
|
||||
return;
|
||||
@ -433,7 +433,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_encoder *encoder;
|
||||
|
||||
NV_DEBUG(dev, "index %d\n", nv_crtc->index);
|
||||
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
||||
|
||||
/* Disconnect all unused encoders. */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
@ -458,7 +458,7 @@ nv50_crtc_commit(struct drm_crtc *crtc)
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "index %d\n", nv_crtc->index);
|
||||
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
||||
|
||||
nv50_crtc_blank(nv_crtc, false);
|
||||
|
||||
@ -497,7 +497,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
|
||||
int ret, format;
|
||||
|
||||
NV_DEBUG(dev, "index %d\n", nv_crtc->index);
|
||||
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
||||
|
||||
switch (drm_fb->depth) {
|
||||
case 8:
|
||||
@ -612,7 +612,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
|
||||
*nv_crtc->mode = *adjusted_mode;
|
||||
|
||||
NV_DEBUG(dev, "index %d\n", nv_crtc->index);
|
||||
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
||||
|
||||
hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
|
||||
vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
|
||||
@ -706,7 +706,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
|
||||
struct nouveau_crtc *nv_crtc = NULL;
|
||||
int ret, i;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
|
||||
if (!nv_crtc)
|
||||
|
@ -41,7 +41,7 @@ nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
|
||||
struct drm_device *dev = nv_crtc->base.dev;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
if (update && nv_crtc->cursor.visible)
|
||||
return;
|
||||
@ -76,7 +76,7 @@ nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
|
||||
struct drm_device *dev = nv_crtc->base.dev;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
if (update && !nv_crtc->cursor.visible)
|
||||
return;
|
||||
@ -116,7 +116,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
|
||||
static void
|
||||
nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
|
||||
{
|
||||
NV_DEBUG(nv_crtc->base.dev, "\n");
|
||||
NV_DEBUG_KMS(nv_crtc->base.dev, "\n");
|
||||
if (offset == nv_crtc->cursor.offset)
|
||||
return;
|
||||
|
||||
@ -143,7 +143,7 @@ nv50_cursor_fini(struct nouveau_crtc *nv_crtc)
|
||||
struct drm_device *dev = nv_crtc->base.dev;
|
||||
int idx = nv_crtc->index;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0);
|
||||
if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx),
|
||||
|
@ -44,7 +44,7 @@ nv50_dac_disconnect(struct nouveau_encoder *nv_encoder)
|
||||
struct nouveau_channel *evo = dev_priv->evo;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "Disconnecting DAC %d\n", nv_encoder->or);
|
||||
NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
|
||||
|
||||
ret = RING_SPACE(evo, 2);
|
||||
if (ret) {
|
||||
@ -81,11 +81,11 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
|
||||
/* Use bios provided value if possible. */
|
||||
if (dev_priv->vbios->dactestval) {
|
||||
load_pattern = dev_priv->vbios->dactestval;
|
||||
NV_DEBUG(dev, "Using bios provided load_pattern of %d\n",
|
||||
NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n",
|
||||
load_pattern);
|
||||
} else {
|
||||
load_pattern = 340;
|
||||
NV_DEBUG(dev, "Using default load_pattern of %d\n",
|
||||
NV_DEBUG_KMS(dev, "Using default load_pattern of %d\n",
|
||||
load_pattern);
|
||||
}
|
||||
|
||||
@ -103,9 +103,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
|
||||
status = connector_status_connected;
|
||||
|
||||
if (status == connector_status_connected)
|
||||
NV_DEBUG(dev, "Load was detected on output with or %d\n", or);
|
||||
NV_DEBUG_KMS(dev, "Load was detected on output with or %d\n", or);
|
||||
else
|
||||
NV_DEBUG(dev, "Load was not detected on output with or %d\n", or);
|
||||
NV_DEBUG_KMS(dev, "Load was not detected on output with or %d\n", or);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -118,7 +118,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode)
|
||||
uint32_t val;
|
||||
int or = nv_encoder->or;
|
||||
|
||||
NV_DEBUG(dev, "or %d mode %d\n", or, mode);
|
||||
NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode);
|
||||
|
||||
/* wait for it to be done */
|
||||
if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or),
|
||||
@ -173,7 +173,7 @@ nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
struct nouveau_connector *connector;
|
||||
|
||||
NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or);
|
||||
NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or);
|
||||
|
||||
connector = nouveau_encoder_connector_get(nv_encoder);
|
||||
if (!connector) {
|
||||
@ -213,7 +213,7 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
||||
uint32_t mode_ctl = 0, mode_ctl2 = 0;
|
||||
int ret;
|
||||
|
||||
NV_DEBUG(dev, "or %d\n", nv_encoder->or);
|
||||
NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or);
|
||||
|
||||
nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
|
||||
@ -264,7 +264,7 @@ nv50_dac_destroy(struct drm_encoder *encoder)
|
||||
if (!encoder)
|
||||
return;
|
||||
|
||||
NV_DEBUG(encoder->dev, "\n");
|
||||
NV_DEBUG_KMS(encoder->dev, "\n");
|
||||
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(nv_encoder);
|
||||
@ -280,7 +280,7 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
|
||||
struct nouveau_encoder *nv_encoder;
|
||||
struct drm_encoder *encoder;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
NV_INFO(dev, "Detected a DAC output\n");
|
||||
|
||||
nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
|
||||
|
@ -188,7 +188,7 @@ nv50_display_init(struct drm_device *dev)
|
||||
uint64_t start;
|
||||
int ret, i;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004));
|
||||
/*
|
||||
@ -232,7 +232,7 @@ nv50_display_init(struct drm_device *dev)
|
||||
nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
|
||||
/* RAM is clamped to 256 MiB. */
|
||||
ram_amount = nouveau_mem_fb_amount(dev);
|
||||
NV_DEBUG(dev, "ram_amount %d\n", ram_amount);
|
||||
NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount);
|
||||
if (ram_amount > 256*1024*1024)
|
||||
ram_amount = 256*1024*1024;
|
||||
nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1);
|
||||
@ -398,7 +398,7 @@ static int nv50_display_disable(struct drm_device *dev)
|
||||
struct drm_crtc *drm_crtc;
|
||||
int ret, i;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
|
||||
@ -469,7 +469,7 @@ int nv50_display_create(struct drm_device *dev)
|
||||
uint32_t connector[16] = {};
|
||||
int ret, i;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
/* init basic kernel modesetting */
|
||||
drm_mode_config_init(dev);
|
||||
@ -573,7 +573,7 @@ int nv50_display_destroy(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
NV_DEBUG(dev, "\n");
|
||||
NV_DEBUG_KMS(dev, "\n");
|
||||
|
||||
drm_mode_config_cleanup(dev);
|
||||
|
||||
@ -617,7 +617,7 @@ nv50_display_irq_head(struct drm_device *dev, int *phead,
|
||||
* CRTC separately, and submission will be blocked by the GPU
|
||||
* until we handle each in turn.
|
||||
*/
|
||||
NV_DEBUG(dev, "0x610030: 0x%08x\n", unk30);
|
||||
NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
|
||||
head = ffs((unk30 >> 9) & 3) - 1;
|
||||
if (head < 0)
|
||||
return -EINVAL;
|
||||
@ -661,7 +661,7 @@ nv50_display_irq_head(struct drm_device *dev, int *phead,
|
||||
or = i;
|
||||
}
|
||||
|
||||
NV_DEBUG(dev, "type %d, or %d\n", type, or);
|
||||
NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or);
|
||||
if (type == OUTPUT_ANY) {
|
||||
NV_ERROR(dev, "unknown encoder!!\n");
|
||||
return -1;
|
||||
@ -811,7 +811,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
|
||||
pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
|
||||
script = nv50_display_script_select(dev, dcbent, pclk);
|
||||
|
||||
NV_DEBUG(dev, "head %d pxclk: %dKHz\n", head, pclk);
|
||||
NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk);
|
||||
|
||||
if (dcbent->type != OUTPUT_DP)
|
||||
nouveau_bios_run_display_table(dev, dcbent, 0, -2);
|
||||
@ -870,7 +870,7 @@ nv50_display_irq_handler_bh(struct work_struct *work)
|
||||
uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
|
||||
uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
|
||||
|
||||
NV_DEBUG(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1);
|
||||
NV_DEBUG_KMS(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1);
|
||||
|
||||
if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10)
|
||||
nv50_display_unk10_handler(dev);
|
||||
@ -974,7 +974,7 @@ nv50_display_irq_handler(struct drm_device *dev)
|
||||
uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
|
||||
uint32_t clock;
|
||||
|
||||
NV_DEBUG(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1);
|
||||
NV_DEBUG_KMS(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1);
|
||||
|
||||
if (!intr0 && !(intr1 & ~delayed))
|
||||
break;
|
||||
|
@ -416,7 +416,7 @@ nv50_fifo_unload_context(struct drm_device *dev)
|
||||
NV_DEBUG(dev, "\n");
|
||||
|
||||
chid = pfifo->channel_id(dev);
|
||||
if (chid < 0 || chid >= dev_priv->engine.fifo.channels)
|
||||
if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1)
|
||||
return 0;
|
||||
|
||||
chan = dev_priv->fifos[chid];
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user