Merge reason: Go from -rc1 base to -rc3 base, merge in fixes.
Unified · Split
| @@ -28,6 +28,7 @@ modules.builtin · 27 unmodified lines | ||
| 28 | 28 | *.gz |
| 29 | 29 | *.bz2 |
| 30 | 30 | *.lzma |
| 31 | +*.lzo | |
| 31 | 32 | *.patch |
| 32 | 33 | *.gcno |
| 33 | 34 | |
| @@ -0,0 +1,7 @@ | ||
| 1 | +filesystems/dnotify_test | |
| 2 | +laptops/dslm | |
| 3 | +timers/hpet_example | |
| 4 | +vm/hugepage-mmap | |
| 5 | +vm/hugepage-shm | |
| 6 | +vm/map_hugetlb | |
| 7 | + | |
| @@ -133,46 +133,6 @@ Description: · 132 unmodified lines | ||
| 133 | 133 | The symbolic link points to the PCI device sysfs entry of the |
| 134 | 134 | Physical Function this device associates with. |
| 135 | 135 | |
| 136 | − | |
| 137 | −What: /sys/bus/pci/slots/... | |
| 138 | −Date: April 2005 (possibly older) | |
| 139 | −KernelVersion: 2.6.12 (possibly older) | |
| 140 | −Contact: linux-pci@vger.kernel.org | |
| 141 | −Description: | |
| 142 | − When the appropriate driver is loaded, it will create a | |
| 143 | − directory per claimed physical PCI slot in | |
| 144 | − /sys/bus/pci/slots/. The names of these directories are | |
| 145 | − specific to the driver, which in turn, are specific to the | |
| 146 | − platform, but in general, should match the label on the | |
| 147 | − machine's physical chassis. | |
| 148 | − | |
| 149 | − The drivers that can create slot directories include the | |
| 150 | − PCI hotplug drivers, and as of 2.6.27, the pci_slot driver. | |
| 151 | − | |
| 152 | − The slot directories contain, at a minimum, a file named | |
| 153 | − 'address' which contains the PCI bus:device:function tuple. | |
| 154 | − Other files may appear as well, but are specific to the | |
| 155 | − driver. | |
| 156 | − | |
| 157 | −What: /sys/bus/pci/slots/.../function[0-7] | |
| 158 | −Date: March 2010 | |
| 159 | −KernelVersion: 2.6.35 | |
| 160 | −Contact: linux-pci@vger.kernel.org | |
| 161 | −Description: | |
| 162 | − If PCI slot directories (as described above) are created, | |
| 163 | − and the physical slot is actually populated with a device, | |
| 164 | − symbolic links in the slot directory pointing to the | |
| 165 | − device's PCI functions are created as well. | |
| 166 | − | |
| 167 | −What: /sys/bus/pci/devices/.../slot | |
| 168 | −Date: March 2010 | |
| 169 | −KernelVersion: 2.6.35 | |
| 170 | −Contact: linux-pci@vger.kernel.org | |
| 171 | −Description: | |
| 172 | − If PCI slot directories (as described above) are created, | |
| 173 | − a symbolic link pointing to the slot directory will be | |
| 174 | − created as well. | |
| 175 | − | |
| 176 | 136 | What: /sys/bus/pci/slots/.../module |
| 177 | 137 | Date: June 2009 |
| 178 | 138 | Contact: linux-pci@vger.kernel.org |
| @@ -389,7 +389,7 @@ · 388 unmodified lines | ||
| 389 | 389 | </para> |
| 390 | 390 | <para> |
| 391 | 391 | If your driver supports memory management (it should!), you'll |
| 392 | − need to set that up at load time as well. How you intialize | |
| 392 | + need to set that up at load time as well. How you initialize | |
| 393 | 393 | it depends on which memory manager you're using, TTM or GEM. |
| 394 | 394 | </para> |
| 395 | 395 | <sect3> |
| @@ -399,7 +399,7 @@ · 3 unmodified lines | ||
| 399 | 399 | aperture space for graphics devices. TTM supports both UMA devices |
| 400 | 400 | and devices with dedicated video RAM (VRAM), i.e. most discrete |
| 401 | 401 | graphics devices. If your device has dedicated RAM, supporting |
| 402 | − TTM is desireable. TTM also integrates tightly with your | |
| 402 | + TTM is desirable. TTM also integrates tightly with your | |
| 403 | 403 | driver specific buffer execution function. See the radeon |
| 404 | 404 | driver for examples. |
| 405 | 405 | </para> |
| @@ -443,7 +443,7 @@ · 37 unmodified lines | ||
| 443 | 443 | likely eventually calling ttm_bo_global_init and |
| 444 | 444 | ttm_bo_global_release, respectively. Also like the previous |
| 445 | 445 | object, ttm_global_item_ref is used to create an initial reference |
| 446 | − count for the TTM, which will call your initalization function. | |
| 446 | + count for the TTM, which will call your initialization function. | |
| 447 | 447 | </para> |
| 448 | 448 | </sect3> |
| 449 | 449 | <sect3> |
| @@ -557,7 +557,7 @@ void intel_crt_init(struct drm_device *dev) · 107 unmodified lines | ||
| 557 | 557 | CRT connector and encoder combination is created. A device |
| 558 | 558 | specific i2c bus is also created, for fetching EDID data and |
| 559 | 559 | performing monitor detection. Once the process is complete, |
| 560 | − the new connector is regsitered with sysfs, to make its | |
| 560 | + the new connector is registered with sysfs, to make its | |
| 561 | 561 | properties available to applications. |
| 562 | 562 | </para> |
| 563 | 563 | <sect4> |
| @@ -581,12 +581,12 @@ void intel_crt_init(struct drm_device *dev) · 17 unmodified lines | ||
| 581 | 581 | <para> |
| 582 | 582 | For each encoder, CRTC and connector, several functions must |
| 583 | 583 | be provided, depending on the object type. Encoder objects |
| 584 | − need should provide a DPMS (basically on/off) function, mode fixup | |
| 584 | + need to provide a DPMS (basically on/off) function, mode fixup | |
| 585 | 585 | (for converting requested modes into native hardware timings), |
| 586 | 586 | and prepare, set and commit functions for use by the core DRM |
| 587 | 587 | helper functions. Connector helpers need to provide mode fetch and |
| 588 | 588 | validity functions as well as an encoder matching function for |
| 589 | − returing an ideal encoder for a given connector. The core | |
| 589 | + returning an ideal encoder for a given connector. The core | |
| 590 | 590 | connector functions include a DPMS callback, (deprecated) |
| 591 | 591 | save/restore routines, detection, mode probing, property handling, |
| 592 | 592 | and cleanup functions. |
| @@ -58,7 +58,7 @@ MPEG stream embedded, sliced VBI data format in this specification. · 57 unmodified lines | ||
| 58 | 58 | </contrib> |
| 59 | 59 | <affiliation> |
| 60 | 60 | <address> |
| 61 | − <email>awalls@radix.net</email> | |
| 61 | + <email>awalls@md.metrocast.net</email> | |
| 62 | 62 | </address> |
| 63 | 63 | </affiliation> |
| 64 | 64 | </author> |
| @@ -53,8 +53,10 @@ input</refpurpose> · 52 unmodified lines | ||
| 53 | 53 | automatically, similar to sensing the video standard. To do so, applications |
| 54 | 54 | call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a |
| 55 | 55 | &v4l2-dv-preset; type. Once the hardware detects a preset, that preset is |
| 56 | −returned in the preset field of &v4l2-dv-preset;. When detection is not | |
| 57 | −possible or fails, the value V4L2_DV_INVALID is returned.</para> | |
| 56 | +returned in the preset field of &v4l2-dv-preset;. If the preset could not be | |
| 57 | +detected because there was no signal, or the signal was unreliable, or the | |
| 58 | +signal did not map to a supported preset, then the value V4L2_DV_INVALID is | |
| 59 | +returned.</para> | |
| 58 | 60 | </refsect1> |
| 59 | 61 | |
| 60 | 62 | <refsect1> |
| @@ -6,6 +6,8 @@ Written by Doug Thompson <dougthompson@xmission.com> · 5 unmodified lines | ||
| 6 | 6 | 7 Dec 2005 |
| 7 | 7 | 17 Jul 2007 Updated |
| 8 | 8 | |
| 9 | +(c) Mauro Carvalho Chehab <mchehab@redhat.com> | |
| 10 | +05 Aug 2009 Nehalem interface | |
| 9 | 11 | |
| 10 | 12 | EDAC is maintained and written by: |
| 11 | 13 | |
| @@ -717,3 +719,153 @@ unique drivers for their hardware systems. · 705 unmodified lines | ||
| 717 | 719 | The 'test_device_edac' sample driver is located at the |
| 718 | 720 | bluesmoke.sourceforge.net project site for EDAC. |
| 719 | 721 | |
| 722 | +======================================================================= | |
| 723 | +NEHALEM USAGE OF EDAC APIs | |
| 724 | + | |
| 725 | +This chapter documents some EXPERIMENTAL mappings for EDAC API to handle | |
| 726 | +Nehalem EDAC driver. They will likely be changed on future versions | |
| 727 | +of the driver. | |
| 728 | + | |
| 729 | +Due to the way Nehalem exports Memory Controller data, some adjustments | |
| 730 | +were done at i7core_edac driver. This chapter will cover those differences | |
| 731 | + | |
| 732 | +1) On Nehalem, there are one Memory Controller per Quick Patch Interconnect | |
| 733 | + (QPI). At the driver, the term "socket" means one QPI. This is | |
| 734 | + associated with a physical CPU socket. | |
| 735 | + | |
| 736 | + Each MC have 3 physical read channels, 3 physical write channels and | |
| 737 | + 3 logic channels. The driver currenty sees it as just 3 channels. | |
| 738 | + Each channel can have up to 3 DIMMs. | |
| 739 | + | |
| 740 | + The minimum known unity is DIMMs. There are no information about csrows. | |
| 741 | + As EDAC API maps the minimum unity is csrows, the driver sequencially | |
| 742 | + maps channel/dimm into different csrows. | |
| 743 | + | |
| 744 | + For example, suposing the following layout: | |
| 745 | + Ch0 phy rd0, wr0 (0x063f4031): 2 ranks, UDIMMs | |
| 746 | + dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400 | |
| 747 | + dimm 1 1024 Mb offset: 4, bank: 8, rank: 1, row: 0x4000, col: 0x400 | |
| 748 | + Ch1 phy rd1, wr1 (0x063f4031): 2 ranks, UDIMMs | |
| 749 | + dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400 | |
| 750 | + Ch2 phy rd3, wr3 (0x063f4031): 2 ranks, UDIMMs | |
| 751 | + dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400 | |
| 752 | + The driver will map it as: | |
| 753 | + csrow0: channel 0, dimm0 | |
| 754 | + csrow1: channel 0, dimm1 | |
| 755 | + csrow2: channel 1, dimm0 | |
| 756 | + csrow3: channel 2, dimm0 | |
| 757 | + | |
| 758 | +exports one | |
| 759 | + DIMM per csrow. | |
| 760 | + | |
| 761 | + Each QPI is exported as a different memory controller. | |
| 762 | + | |
| 763 | +2) Nehalem MC has the hability to generate errors. The driver implements this | |
| 764 | + functionality via some error injection nodes: | |
| 765 | + | |
| 766 | + For injecting a memory error, there are some sysfs nodes, under | |
| 767 | + /sys/devices/system/edac/mc/mc?/: | |
| 768 | + | |
| 769 | + inject_addrmatch/*: | |
| 770 | + Controls the error injection mask register. It is possible to specify | |
| 771 | + several characteristics of the address to match an error code: | |
| 772 | + dimm = the affected dimm. Numbers are relative to a channel; | |
| 773 | + rank = the memory rank; | |
| 774 | + channel = the channel that will generate an error; | |
| 775 | + bank = the affected bank; | |
| 776 | + page = the page address; | |
| 777 | + column (or col) = the address column. | |
| 778 | + each of the above values can be set to "any" to match any valid value. | |
| 779 | + | |
| 780 | + At driver init, all values are set to any. | |
| 781 | + | |
| 782 | + For example, to generate an error at rank 1 of dimm 2, for any channel, | |
| 783 | + any bank, any page, any column: | |
| 784 | + echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm | |
| 785 | + echo 1 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank | |
| 786 | + | |
| 787 | + To return to the default behaviour of matching any, you can do: | |
| 788 | + echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm | |
| 789 | + echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank | |
| 790 | + | |
| 791 | + inject_eccmask: | |
| 792 | + specifies what bits will have troubles, | |
| 793 | + | |
| 794 | + inject_section: | |
| 795 | + specifies what ECC cache section will get the error: | |
| 796 | + 3 for both | |
| 797 | + 2 for the highest | |
| 798 | + 1 for the lowest | |
| 799 | + | |
| 800 | + inject_type: | |
| 801 | + specifies the type of error, being a combination of the following bits: | |
| 802 | + bit 0 - repeat | |
| 803 | + bit 1 - ecc | |
| 804 | + bit 2 - parity | |
| 805 | + | |
| 806 | + inject_enable starts the error generation when something different | |
| 807 | + than 0 is written. | |
| 808 | + | |
| 809 | + All inject vars can be read. root permission is needed for write. | |
| 810 | + | |
| 811 | + Datasheet states that the error will only be generated after a write on an | |
| 812 | + address that matches inject_addrmatch. It seems, however, that reading will | |
| 813 | + also produce an error. | |
| 814 | + | |
| 815 | + For example, the following code will generate an error for any write access | |
| 816 | + at socket 0, on any DIMM/address on channel 2: | |
| 817 | + | |
| 818 | + echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/channel | |
| 819 | + echo 2 >/sys/devices/system/edac/mc/mc0/inject_type | |
| 820 | + echo 64 >/sys/devices/system/edac/mc/mc0/inject_eccmask | |
| 821 | + echo 3 >/sys/devices/system/edac/mc/mc0/inject_section | |
| 822 | + echo 1 >/sys/devices/system/edac/mc/mc0/inject_enable | |
| 823 | + dd if=/dev/mem of=/dev/null seek=16k bs=4k count=1 >& /dev/null | |
| 824 | + | |
| 825 | + For socket 1, it is needed to replace "mc0" by "mc1" at the above | |
| 826 | + commands. | |
| 827 | + | |
| 828 | + The generated error message will look like: | |
| 829 | + | |
| 830 | + EDAC MC0: UE row 0, channel-a= 0 channel-b= 0 labels "-": NON_FATAL (addr = 0x0075b980, socket=0, Dimm=0, Channel=2, syndrome=0x00000040, count=1, Err=8c0000400001009f:4000080482 (read error: read ECC error)) | |
| 831 | + | |
| 832 | +3) Nehalem specific Corrected Error memory counters | |
| 833 | + | |
| 834 | + Nehalem have some registers to count memory errors. The driver uses those | |
| 835 | + registers to report Corrected Errors on devices with Registered Dimms. | |
| 836 | + | |
| 837 | + However, those counters don't work with Unregistered Dimms. As the chipset | |
| 838 | + offers some counters that also work with UDIMMS (but with a worse level of | |
| 839 | + granularity than the default ones), the driver exposes those registers for | |
| 840 | + UDIMM memories. | |
| 841 | + | |
| 842 | + They can be read by looking at the contents of all_channel_counts/ | |
| 843 | + | |
| 844 | + $ for i in /sys/devices/system/edac/mc/mc0/all_channel_counts/*; do echo $i; cat $i; done | |
| 845 | + /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm0 | |
| 846 | + 0 | |
| 847 | + /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm1 | |
| 848 | + 0 | |
| 849 | + /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm2 | |
| 850 | + 0 | |
| 851 | + | |
| 852 | + What happens here is that errors on different csrows, but at the same | |
| 853 | + dimm number will increment the same counter. | |
| 854 | + So, in this memory mapping: | |
| 855 | + csrow0: channel 0, dimm0 | |
| 856 | + csrow1: channel 0, dimm1 | |
| 857 | + csrow2: channel 1, dimm0 | |
| 858 | + csrow3: channel 2, dimm0 | |
| 859 | + The hardware will increment udimm0 for an error at the first dimm at either | |
| 860 | + csrow0, csrow2 or csrow3; | |
| 861 | + The hardware will increment udimm1 for an error at the second dimm at either | |
| 862 | + csrow0, csrow2 or csrow3; | |
| 863 | + The hardware will increment udimm2 for an error at the third dimm at either | |
| 864 | + csrow0, csrow2 or csrow3; | |
| 865 | + | |
| 866 | +4) Standard error counters | |
| 867 | + | |
| 868 | + The standard error counters are generated when an mcelog error is received | |
| 869 | + by the driver. Since, with udimm, this is counted by software, it is | |
| 870 | + possible that some errors could be lost. With rdimm's, they displays the | |
| 871 | + contents of the registers | |
| @@ -578,15 +578,6 @@ Who: Avi Kivity <avi@redhat.com> · 577 unmodified lines | ||
| 578 | 578 | |
| 579 | 579 | ---------------------------- |
| 580 | 580 | |
| 581 | −What: "acpi=ht" boot option | |
| 582 | −When: 2.6.35 | |
| 583 | −Why: Useful in 2003, implementation is a hack. | |
| 584 | − Generally invoked by accident today. | |
| 585 | − Seen as doing more harm than good. | |
| 586 | −Who: Len Brown <len.brown@intel.com> | |
| 587 | − | |
| 588 | −---------------------------- | |
| 589 | − | |
| 590 | 581 | What: iwlwifi 50XX module parameters |
| 591 | 582 | When: 2.6.40 |
| 592 | 583 | Why: The "..50" modules parameters were used to configure 5000 series and |
| @@ -794,11 +794,6 @@ designed. · 793 unmodified lines | ||
| 794 | 794 | |
| 795 | 795 | Roadmap: |
| 796 | 796 | |
| 797 | −2.6.35 Inclusion in mainline as an experimental mount option | |
| 798 | − => approximately 2-3 months to merge window | |
| 799 | − => needs to be in xfs-dev tree in 4-6 weeks | |
| 800 | − => code is nearing readiness for review | |
| 801 | − | |
| 802 | 797 | 2.6.37 Remove experimental tag from mount option |
| 803 | 798 | => should be roughly 6 months after initial merge |
| 804 | 799 | => enough time to: |
| @@ -6,12 +6,12 @@ Supported adapters: · 5 unmodified lines | ||
| 6 | 6 | http://www.ali.com.tw/eng/support/datasheet_request.php |
| 7 | 7 | |
| 8 | 8 | Authors: |
| 9 | − Frodo Looijaard <frodol@dds.nl>, | |
| 9 | + Frodo Looijaard <frodol@dds.nl>, | |
| 10 | 10 | Philip Edelbrock <phil@netroedge.com>, |
| 11 | 11 | Mark D. Studebaker <mdsxyz123@yahoo.com>, |
| 12 | 12 | Dan Eaton <dan.eaton@rocketlogix.com>, |
| 13 | 13 | Stephen Rousset<stephen.rousset@rocketlogix.com> |
| 14 | − | |
| 14 | + | |
| 15 | 15 | Description |
| 16 | 16 | ----------- |
| 17 | 17 | |
| @@ -18,7 +18,7 @@ For an overview of these chips see http://www.acerlabs.com · 17 unmodified lines | ||
| 18 | 18 | The M1563 southbridge is deceptively similar to the M1533, with a few |
| 19 | 19 | notable exceptions. One of those happens to be the fact they upgraded the |
| 20 | 20 | i2c core to be SMBus 2.0 compliant, and happens to be almost identical to |
| 21 | −the i2c controller found in the Intel 801 south bridges. | |
| 21 | +the i2c controller found in the Intel 801 south bridges. | |
| 22 | 22 | |
| 23 | 23 | Features |
| 24 | 24 | -------- |
| @@ -6,8 +6,8 @@ Supported adapters: · 5 unmodified lines | ||
| 6 | 6 | http://www.ali.com.tw/eng/support/datasheet_request.php |
| 7 | 7 | |
| 8 | 8 | Authors: |
| 9 | − Frodo Looijaard <frodol@dds.nl>, | |
| 10 | − Philip Edelbrock <phil@netroedge.com>, | |
| 9 | + Frodo Looijaard <frodol@dds.nl>, | |
| 10 | + Philip Edelbrock <phil@netroedge.com>, | |
| 11 | 11 | Mark D. Studebaker <mdsxyz123@yahoo.com> |
| 12 | 12 | |
| 13 | 13 | Module Parameters |
| @@ -40,10 +40,10 @@ M1541 and M1543C South Bridges. · 26 unmodified lines | ||
| 40 | 40 | The M1543C is a South bridge for desktop systems. |
| 41 | 41 | The M1541 is a South bridge for portable systems. |
| 42 | 42 | They are part of the following ALI chipsets: |
| 43 | − | |
| 44 | − * "Aladdin Pro 2" includes the M1621 Slot 1 North bridge with AGP and | |
| 43 | + | |
| 44 | + * "Aladdin Pro 2" includes the M1621 Slot 1 North bridge with AGP and | |
| 45 | 45 | 100MHz CPU Front Side bus |
| 46 | − * "Aladdin V" includes the M1541 Socket 7 North bridge with AGP and 100MHz | |
| 46 | + * "Aladdin V" includes the M1541 Socket 7 North bridge with AGP and 100MHz | |
| 47 | 47 | CPU Front Side bus |
| 48 | 48 | Some Aladdin V motherboards: |
| 49 | 49 | Asus P5A |
| @@ -77,7 +77,7 @@ output of lspci will show something similar to the following: · 27 unmodified lines | ||
| 77 | 77 | ** then run lspci. |
| 78 | 78 | ** If you see the 1533 and 5229 devices but NOT the 7101 device, |
| 79 | 79 | ** then you must enable ACPI, the PMU, SMB, or something similar |
| 80 | −** in the BIOS. | |
| 80 | +** in the BIOS. | |
| 81 | 81 | ** The driver won't work if it can't find the M7101 device. |
| 82 | 82 | |
| 83 | 83 | The SMB controller is part of the M7101 device, which is an ACPI-compliant |
| @@ -87,8 +87,8 @@ The whole M7101 device has to be enabled for the SMB to work. You can't · 3 unmodified lines | ||
| 87 | 87 | just enable the SMB alone. The SMB and the ACPI have separate I/O spaces. |
| 88 | 88 | We make sure that the SMB is enabled. We leave the ACPI alone. |
| 89 | 89 | |
| 90 | −Features | |
| 91 | −-------- | |
| 90 | +Features | |
| 91 | +-------- | |
| 92 | 92 | |
| 93 | 93 | This driver controls the SMB Host only. The SMB Slave |
| 94 | 94 | controller on the M15X3 is not enabled. This driver does not use |
| @@ -1,10 +1,10 @@ | ||
| 1 | 1 | Kernel driver i2c-pca-isa |
| 2 | 2 | |
| 3 | 3 | Supported adapters: |
| 4 | −This driver supports ISA boards using the Philips PCA 9564 | |
| 5 | −Parallel bus to I2C bus controller | |
| 4 | +This driver supports ISA boards using the Philips PCA 9564 | |
| 5 | +Parallel bus to I2C bus controller | |
| 6 | 6 | |
| 7 | −Author: Ian Campbell <icampbell@arcom.com>, Arcom Control Systems | |
| 7 | +Author: Ian Campbell <icampbell@arcom.com>, Arcom Control Systems | |
| 8 | 8 | |
| 9 | 9 | Module Parameters |
| 10 | 10 | ----------------- |
| @@ -12,12 +12,12 @@ Module Parameters · 1 unmodified line | ||
| 12 | 12 | * base int |
| 13 | 13 | I/O base address |
| 14 | 14 | * irq int |
| 15 | − IRQ interrupt | |
| 16 | −* clock int | |
| 15 | + IRQ interrupt | |
| 16 | +* clock int | |
| 17 | 17 | Clock rate as described in table 1 of PCA9564 datasheet |
| 18 | 18 | |
| 19 | 19 | Description |
| 20 | 20 | ----------- |
| 21 | 21 | |
| 22 | −This driver supports ISA boards using the Philips PCA 9564 | |
| 23 | −Parallel bus to I2C bus controller | |
| 22 | +This driver supports ISA boards using the Philips PCA 9564 | |
| 23 | +Parallel bus to I2C bus controller | |
| @@ -1,41 +1,41 @@ | ||
| 1 | 1 | Kernel driver i2c-sis5595 |
| 2 | 2 | |
| 3 | −Authors: | |
| 3 | +Authors: | |
| 4 | 4 | Frodo Looijaard <frodol@dds.nl>, |
| 5 | 5 | Mark D. Studebaker <mdsxyz123@yahoo.com>, |
| 6 | − Philip Edelbrock <phil@netroedge.com> | |
| 6 | + Philip Edelbrock <phil@netroedge.com> | |
| 7 | 7 | |
| 8 | 8 | Supported adapters: |
| 9 | 9 | * Silicon Integrated Systems Corp. SiS5595 Southbridge |
| 10 | 10 | Datasheet: Publicly available at the Silicon Integrated Systems Corp. site. |
| 11 | 11 | |
| 12 | −Note: all have mfr. ID 0x1039. | |
| 13 | − | |
| 14 | − SUPPORTED PCI ID | |
| 15 | − 5595 0008 | |
| 16 | − | |
| 17 | − Note: these chips contain a 0008 device which is incompatible with the | |
| 18 | − 5595. We recognize these by the presence of the listed | |
| 19 | − "blacklist" PCI ID and refuse to load. | |
| 20 | − | |
| 21 | − NOT SUPPORTED PCI ID BLACKLIST PCI ID | |
| 22 | − 540 0008 0540 | |
| 23 | − 550 0008 0550 | |
| 24 | − 5513 0008 5511 | |
| 25 | − 5581 0008 5597 | |
| 26 | − 5582 0008 5597 | |
| 27 | − 5597 0008 5597 | |
| 28 | − 5598 0008 5597/5598 | |
| 29 | − 630 0008 0630 | |
| 30 | − 645 0008 0645 | |
| 31 | − 646 0008 0646 | |
| 32 | − 648 0008 0648 | |
| 33 | − 650 0008 0650 | |
| 34 | − 651 0008 0651 | |
| 35 | − 730 0008 0730 | |
| 36 | − 735 0008 0735 | |
| 37 | − 745 0008 0745 | |
| 38 | − 746 0008 0746 | |
| 12 | +Note: all have mfr. ID 0x1039. | |
| 13 | + | |
| 14 | + SUPPORTED PCI ID | |
| 15 | + 5595 0008 | |
| 16 | + | |
| 17 | + Note: these chips contain a 0008 device which is incompatible with the | |
| 18 | + 5595. We recognize these by the presence of the listed | |
| 19 | + "blacklist" PCI ID and refuse to load. | |
| 20 | + | |
| 21 | + NOT SUPPORTED PCI ID BLACKLIST PCI ID | |
| 22 | + 540 0008 0540 | |
| 23 | + 550 0008 0550 | |
| 24 | + 5513 0008 5511 | |
| 25 | + 5581 0008 5597 | |
| 26 | + 5582 0008 5597 | |
| 27 | + 5597 0008 5597 | |
| 28 | + 5598 0008 5597/5598 | |
| 29 | + 630 0008 0630 | |
| 30 | + 645 0008 0645 | |
| 31 | + 646 0008 0646 | |
| 32 | + 648 0008 0648 | |
| 33 | + 650 0008 0650 | |
| 34 | + 651 0008 0651 | |
| 35 | + 730 0008 0730 | |
| 36 | + 735 0008 0735 | |
| 37 | + 745 0008 0745 | |
| 38 | + 746 0008 0746 | |
| 39 | 39 | |
| 40 | 40 | Module Parameters |
| 41 | 41 | ----------------- |
| @@ -14,9 +14,9 @@ Module Parameters · 13 unmodified lines | ||
| 14 | 14 | * force = [1|0] Forcibly enable the SIS630. DANGEROUS! |
| 15 | 15 | This can be interesting for chipsets not named |
| 16 | 16 | above to check if it works for you chipset, but DANGEROUS! |
| 17 | − | |
| 18 | −* high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default, | |
| 19 | − what your BIOS use). DANGEROUS! This should be a bit | |
| 17 | + | |
| 18 | +* high_clock = [1|0] Forcibly set Host Master Clock to 56KHz (default, | |
| 19 | + what your BIOS use). DANGEROUS! This should be a bit | |
| 20 | 20 | faster, but freeze some systems (i.e. my Laptop). |
| 21 | 21 | |
| 22 | 22 | |
| @@ -44,6 +44,6 @@ Philip Edelbrock <phil@netroedge.com> · 21 unmodified lines | ||
| 44 | 44 | - testing SiS730 support |
| 45 | 45 | Mark M. Hoffman <mhoffman@lightlink.com> |
| 46 | 46 | - bug fixes |
| 47 | − | |
| 47 | + | |
| 48 | 48 | To anyone else which I forgot here ;), thanks! |
| 49 | 49 | |
| @@ -1,17 +1,17 @@ | ||
| 1 | −The I2C protocol knows about two kinds of device addresses: normal 7 bit | |
| 1 | +The I2C protocol knows about two kinds of device addresses: normal 7 bit | |
| 2 | 2 | addresses, and an extended set of 10 bit addresses. The sets of addresses |
| 3 | 3 | do not intersect: the 7 bit address 0x10 is not the same as the 10 bit |
| 4 | 4 | address 0x10 (though a single device could respond to both of them). You |
| 5 | 5 | select a 10 bit address by adding an extra byte after the address |
| 6 | 6 | byte: |
| 7 | − S Addr7 Rd/Wr .... | |
| 7 | + S Addr7 Rd/Wr .... | |
| 8 | 8 | becomes |
| 9 | 9 | S 11110 Addr10 Rd/Wr |
| 10 | 10 | S is the start bit, Rd/Wr the read/write bit, and if you count the number |
| 11 | 11 | of bits, you will see the there are 8 after the S bit for 7 bit addresses, |
| 12 | 12 | and 16 after the S bit for 10 bit addresses. |
| 13 | 13 | |
| 14 | −WARNING! The current 10 bit address support is EXPERIMENTAL. There are | |
| 14 | +WARNING! The current 10 bit address support is EXPERIMENTAL. There are | |
| 15 | 15 | several places in the code that will cause SEVERE PROBLEMS with 10 bit |
| 16 | 16 | addresses, even though there is some basic handling and hooks. Also, |
| 17 | 17 | almost no supported adapter handles the 10 bit addresses correctly. |
| @@ -65,7 +65,7 @@ CROSS_COMPILE · 64 unmodified lines | ||
| 65 | 65 | Specify an optional fixed part of the binutils filename. |
| 66 | 66 | CROSS_COMPILE can be a part of the filename or the full path. |
| 67 | 67 | |
| 68 | −CROSS_COMPILE is also used for ccache is some setups. | |
| 68 | +CROSS_COMPILE is also used for ccache in some setups. | |
| 69 | 69 | |
| 70 | 70 | CF |
| 71 | 71 | -------------------------------------------------- |
| @@ -162,3 +162,7 @@ For tags/TAGS/cscope targets, you can specify more than one arch · 90 unmodified lines | ||
| 162 | 162 | to be included in the databases, separated by blank space. E.g.: |
| 163 | 163 | |
| 164 | 164 | $ make ALLSOURCE_ARCHS="x86 mips arm" tags |
| 165 | + | |
| 166 | +To get all available archs you can also specify all. E.g.: | |
| 167 | + | |
| 168 | + $ make ALLSOURCE_ARCHS=all tags | |
| @@ -66,14 +66,14 @@ of advantages of mutexes: · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | c0377ccb <mutex_lock>: |
| 68 | 68 | c0377ccb: f0 ff 08 lock decl (%eax) |
| 69 | − c0377cce: 78 0e js c0377cde <.text.lock.mutex> | |
| 69 | + c0377cce: 78 0e js c0377cde <.text..lock.mutex> | |
| 70 | 70 | c0377cd0: c3 ret |
| 71 | 71 | |
| 72 | 72 | the unlocking fastpath is equally tight: |
| 73 | 73 | |
| 74 | 74 | c0377cd1 <mutex_unlock>: |
| 75 | 75 | c0377cd1: f0 ff 00 lock incl (%eax) |
| 76 | − c0377cd4: 7e 0f jle c0377ce5 <.text.lock.mutex+0x7> | |
| 76 | + c0377cd4: 7e 0f jle c0377ce5 <.text..lock.mutex+0x7> | |
| 77 | 77 | c0377cd6: c3 ret |
| 78 | 78 | |
| 79 | 79 | - 'struct mutex' semantics are well-defined and are enforced if |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | obj- := dummy.o |
| 3 | 3 | |
| 4 | 4 | # List of programs to build |
| 5 | −hostprogs-y := hpet_example | |
| 5 | +hostprogs-$(CONFIG_X86) := hpet_example | |
| 6 | 6 | |
| 7 | 7 | # Tell kbuild to always build the programs |
| 8 | 8 | always := $(hostprogs-y) |
| @@ -176,5 +176,6 @@ · 175 unmodified lines | ||
| 176 | 176 | 175 -> Leadtek Winfast DTV1000S [107d:6655] |
| 177 | 177 | 176 -> Beholder BeholdTV 505 RDS [0000:5051] |
| 178 | 178 | 177 -> Hawell HW-404M7 |
| 179 | −179 -> Beholder BeholdTV H7 [5ace:7190] | |
| 180 | −180 -> Beholder BeholdTV A7 [5ace:7090] | |
| 179 | +178 -> Beholder BeholdTV H7 [5ace:7190] | |
| 180 | +179 -> Beholder BeholdTV A7 [5ace:7090] | |
| 181 | +180 -> Avermedia M733A [1461:4155,1461:4255] | |
| @@ -290,6 +290,7 @@ sonixb 0c45:602e Genius VideoCam Messenger · 289 unmodified lines | ||
| 290 | 290 | sonixj 0c45:6040 Speed NVC 350K |
| 291 | 291 | sonixj 0c45:607c Sonix sn9c102p Hv7131R |
| 292 | 292 | sonixj 0c45:60c0 Sangha Sn535 |
| 293 | +sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067) | |
| 293 | 294 | sonixj 0c45:60ec SN9C105+MO4000 |
| 294 | 295 | sonixj 0c45:60fb Surfer NoName |
| 295 | 296 | sonixj 0c45:60fc LG-LIC300 |
| @@ -1731,7 +1731,7 @@ S: Maintained · 1730 unmodified lines | ||
| 1731 | 1731 | F: sound/pci/cs5535audio/ |
| 1732 | 1732 | |
| 1733 | 1733 | CX18 VIDEO4LINUX DRIVER |
| 1734 | −M: Andy Walls <awalls@radix.net> | |
| 1734 | +M: Andy Walls <awalls@md.metrocast.net> | |
| 1735 | 1735 | L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) |
| 1736 | 1736 | L: linux-media@vger.kernel.org |
| 1737 | 1737 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
| @@ -2978,7 +2978,6 @@ F: drivers/net/ixgb/ · 1240 unmodified lines | ||
| 2978 | 2978 | F: drivers/net/ixgbe/ |
| 2979 | 2979 | |
| 2980 | 2980 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT |
| 2981 | −M: Zhu Yi <yi.zhu@intel.com> | |
| 2982 | 2981 | M: Reinette Chatre <reinette.chatre@intel.com> |
| 2983 | 2982 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 2984 | 2983 | L: linux-wireless@vger.kernel.org |
| @@ -2988,7 +2987,6 @@ F: Documentation/networking/README.ipw2100 · 3 unmodified lines | ||
| 2988 | 2987 | F: drivers/net/wireless/ipw2x00/ipw2100.* |
| 2989 | 2988 | |
| 2990 | 2989 | INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT |
| 2991 | −M: Zhu Yi <yi.zhu@intel.com> | |
| 2992 | 2990 | M: Reinette Chatre <reinette.chatre@intel.com> |
| 2993 | 2991 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 2994 | 2992 | L: linux-wireless@vger.kernel.org |
| @@ -3019,8 +3017,8 @@ F: drivers/net/wimax/i2400m/ · 24 unmodified lines | ||
| 3019 | 3017 | F: include/linux/wimax/i2400m.h |
| 3020 | 3018 | |
| 3021 | 3019 | INTEL WIRELESS WIFI LINK (iwlwifi) |
| 3022 | −M: Zhu Yi <yi.zhu@intel.com> | |
| 3023 | 3020 | M: Reinette Chatre <reinette.chatre@intel.com> |
| 3021 | +M: Wey-Yi Guy <wey-yi.w.guy@intel.com> | |
| 3024 | 3022 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 3025 | 3023 | L: linux-wireless@vger.kernel.org |
| 3026 | 3024 | W: http://intellinuxwireless.org |
| @@ -3030,7 +3028,6 @@ F: drivers/net/wireless/iwlwifi/ · 3 unmodified lines | ||
| 3030 | 3028 | |
| 3031 | 3029 | INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi) |
| 3032 | 3030 | M: Samuel Ortiz <samuel.ortiz@intel.com> |
| 3033 | −M: Zhu Yi <yi.zhu@intel.com> | |
| 3034 | 3031 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 3035 | 3032 | L: linux-wireless@vger.kernel.org |
| 3036 | 3033 | S: Supported |
| @@ -3165,7 +3162,7 @@ F: Documentation/hwmon/it87 · 128 unmodified lines | ||
| 3165 | 3162 | F: drivers/hwmon/it87.c |
| 3166 | 3163 | |
| 3167 | 3164 | IVTV VIDEO4LINUX DRIVER |
| 3168 | −M: Andy Walls <awalls@radix.net> | |
| 3165 | +M: Andy Walls <awalls@md.metrocast.net> | |
| 3169 | 3166 | L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) |
| 3170 | 3167 | L: linux-media@vger.kernel.org |
| 3171 | 3168 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
| @@ -3242,7 +3239,7 @@ L: autofs@linux.kernel.org · 70 unmodified lines | ||
| 3242 | 3239 | S: Maintained |
| 3243 | 3240 | F: fs/autofs4/ |
| 3244 | 3241 | |
| 3245 | −KERNEL BUILD | |
| 3242 | +KERNEL BUILD + files below scripts/ (unless maintained elsewhere) | |
| 3246 | 3243 | M: Michal Marek <mmarek@suse.cz> |
| 3247 | 3244 | T: git git://repo.or.cz/linux-kbuild.git for-next |
| 3248 | 3245 | T: git git://repo.or.cz/linux-kbuild.git for-linus |
| @@ -3251,6 +3248,9 @@ S: Maintained · 2 unmodified lines | ||
| 3251 | 3248 | F: Documentation/kbuild/ |
| 3252 | 3249 | F: Makefile |
| 3253 | 3250 | F: scripts/Makefile.* |
| 3251 | +F: scripts/basic/ | |
| 3252 | +F: scripts/mk* | |
| 3253 | +F: scripts/package/ | |
| 3254 | 3254 | |
| 3255 | 3255 | KERNEL JANITORS |
| 3256 | 3256 | L: kernel-janitors@vger.kernel.org |
| @@ -3493,9 +3493,8 @@ F: arch/powerpc/platforms/83xx/ · 236 unmodified lines | ||
| 3493 | 3493 | |
| 3494 | 3494 | LINUX FOR POWERPC PA SEMI PWRFICIENT |
| 3495 | 3495 | M: Olof Johansson <olof@lixom.net> |
| 3496 | −W: http://www.pasemi.com/ | |
| 3497 | 3496 | L: linuxppc-dev@ozlabs.org |
| 3498 | −S: Supported | |
| 3497 | +S: Maintained | |
| 3499 | 3498 | F: arch/powerpc/platforms/pasemi/ |
| 3500 | 3499 | F: drivers/*/*pasemi* |
| 3501 | 3500 | F: drivers/*/*/*pasemi* |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 2 |
| 2 | 2 | PATCHLEVEL = 6 |
| 3 | 3 | SUBLEVEL = 35 |
| 4 | −EXTRAVERSION = -rc1 | |
| 4 | +EXTRAVERSION = -rc3 | |
| 5 | 5 | NAME = Sheep on Meth |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -183,11 +183,14 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ · 175 unmodified lines | ||
| 183 | 183 | # CROSS_COMPILE can be set on the command line |
| 184 | 184 | # make CROSS_COMPILE=ia64-linux- |
| 185 | 185 | # Alternatively CROSS_COMPILE can be set in the environment. |
| 186 | +# A third alternative is to store a setting in .config so that plain | |
| 187 | +# "make" in the configured kernel build directory always uses that. | |
| 186 | 188 | # Default value for CROSS_COMPILE is not to prefix executables |
| 187 | 189 | # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile |
| 188 | 190 | export KBUILD_BUILDHOST := $(SUBARCH) |
| 189 | 191 | ARCH ?= $(SUBARCH) |
| 190 | 192 | CROSS_COMPILE ?= |
| 193 | +CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) | |
| 191 | 194 | |
| 192 | 195 | # Architecture as present in compile.h |
| 193 | 196 | UTS_MACHINE := $(ARCH) |
| @@ -576,9 +579,6 @@ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) · 382 unmodified lines | ||
| 576 | 579 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 577 | 580 | KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) |
| 578 | 581 | |
| 579 | −# revert to pre-gcc-4.4 behaviour of .eh_frame | |
| 580 | −KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) | |
| 581 | − | |
| 582 | 582 | # conserve stack if available |
| 583 | 583 | KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) |
| 584 | 584 | |
| @@ -882,9 +882,6 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; · 297 unmodified lines | ||
| 882 | 882 | PHONY += $(vmlinux-dirs) |
| 883 | 883 | $(vmlinux-dirs): prepare scripts |
| 884 | 884 | $(Q)$(MAKE) $(build)=$@ |
| 885 | −ifdef CONFIG_MODULES | |
| 886 | − $(Q)$(MAKE) $(modbuiltin)=$@ | |
| 887 | −endif | |
| 888 | 885 | |
| 889 | 886 | # Build the kernel release string |
| 890 | 887 | # |
| @@ -907,14 +904,19 @@ endif · 16 unmodified lines | ||
| 907 | 904 | # $(localver) |
| 908 | 905 | # localversion* (files without backups, containing '~') |
| 909 | 906 | # $(CONFIG_LOCALVERSION) (from kernel config setting) |
| 910 | −# $(localver-auto) (only if CONFIG_LOCALVERSION_AUTO is set) | |
| 911 | −# ./scripts/setlocalversion (SCM tag, if one exists) | |
| 912 | −# $(LOCALVERSION) (from make command line if provided) | |
| 907 | +# $(LOCALVERSION) (from make command line, if provided) | |
| 908 | +# $(localver-extra) | |
| 909 | +# $(scm-identifier) (unique SCM tag, if one exists) | |
| 910 | +# ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO) | |
| 911 | +# .scmversion (only with CONFIG_LOCALVERSION_AUTO) | |
| 912 | +# + (only without CONFIG_LOCALVERSION_AUTO | |
| 913 | +# and without LOCALVERSION= and | |
| 914 | +# repository is at non-tagged commit) | |
| 913 | 915 | # |
| 914 | −# Note how the final $(localver-auto) string is included *only* if the | |
| 915 | −# kernel config option CONFIG_LOCALVERSION_AUTO is selected. Also, at the | |
| 916 | −# moment, only git is supported but other SCMs can edit the script | |
| 917 | −# scripts/setlocalversion and add the appropriate checks as needed. | |
| 916 | +# For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has | |
| 917 | +# been revised beyond a tagged commit, `+' is appended to the version string | |
| 918 | +# when not overridden by using "make LOCALVERSION=". This indicates that the | |
| 919 | +# kernel is not a vanilla release version and has been modified. | |
| 918 | 920 | |
| 919 | 921 | pattern = ".*/localversion[^~]*" |
| 920 | 922 | string = $(shell cat /dev/null \ |
| @@ -923,26 +925,32 @@ string = $(shell cat /dev/null \ · 2 unmodified lines | ||
| 923 | 925 | localver = $(subst $(space),, $(string) \ |
| 924 | 926 | $(patsubst "%",%,$(CONFIG_LOCALVERSION))) |
| 925 | 927 | |
| 926 | −# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called | |
| 927 | −# and if the SCM is know a tag from the SCM is appended. | |
| 928 | −# The appended tag is determined by the SCM used. | |
| 928 | +# scripts/setlocalversion is called to create a unique identifier if the source | |
| 929 | +# is managed by a known SCM and the repository has been revised since the last | |
| 930 | +# tagged (release) commit. The format of the identifier is determined by the | |
| 931 | +# SCM's implementation. | |
| 929 | 932 | # |
| 930 | 933 | # .scmversion is used when generating rpm packages so we do not loose |
| 931 | 934 | # the version information from the SCM when we do the build of the kernel |
| 932 | 935 | # from the copied source |
| 933 | −ifdef CONFIG_LOCALVERSION_AUTO | |
| 934 | − | |
| 935 | 936 | ifeq ($(wildcard .scmversion),) |
| 936 | − _localver-auto = $(shell $(CONFIG_SHELL) \ | |
| 937 | + scm-identifier = $(shell $(CONFIG_SHELL) \ | |
| 937 | 938 | $(srctree)/scripts/setlocalversion $(srctree)) |
| 938 | 939 | else |
| 939 | − _localver-auto = $(shell cat .scmversion 2> /dev/null) | |
| 940 | + scm-identifier = $(shell cat .scmversion 2> /dev/null) | |
| 940 | 941 | endif |
| 941 | 942 | |
| 942 | − localver-auto = $(LOCALVERSION)$(_localver-auto) | |
| 943 | +ifdef CONFIG_LOCALVERSION_AUTO | |
| 944 | + localver-extra = $(scm-identifier) | |
| 945 | +else | |
| 946 | + ifneq ($(scm-identifier),) | |
| 947 | + ifeq ($(LOCALVERSION),) | |
| 948 | + localver-extra = + | |
| 949 | + endif | |
| 950 | + endif | |
| 943 | 951 | endif |
| 944 | 952 | |
| 945 | −localver-full = $(localver)$(localver-auto) | |
| 953 | +localver-full = $(localver)$(LOCALVERSION)$(localver-extra) | |
| 946 | 954 | |
| 947 | 955 | # Store (new) KERNELRELASE string in include/config/kernel.release |
| 948 | 956 | kernelrelease = $(KERNELVERSION)$(localver-full) |
| @@ -1087,13 +1095,18 @@ all: modules · 138 unmodified lines | ||
| 1087 | 1095 | # using awk while concatenating to the final file. |
| 1088 | 1096 | |
| 1089 | 1097 | PHONY += modules |
| 1090 | −modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) | |
| 1098 | +modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin | |
| 1091 | 1099 | $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order |
| 1092 | − $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.builtin) > $(objtree)/modules.builtin | |
| 1093 | 1100 | @$(kecho) ' Building modules, stage 2.'; |
| 1094 | 1101 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost |
| 1095 | 1102 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild |
| 1096 | 1103 | |
| 1104 | +modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) | |
| 1105 | + $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin | |
| 1106 | + | |
| 1107 | +%/modules.builtin: include/config/auto.conf | |
| 1108 | + $(Q)$(MAKE) $(modbuiltin)=$* | |
| 1109 | + | |
| 1097 | 1110 | |
| 1098 | 1111 | # Target to prepare building external modules |
| 1099 | 1112 | PHONY += modules_prepare |
| @@ -1249,7 +1262,9 @@ help: · 149 unmodified lines | ||
| 1249 | 1262 | @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH' |
| 1250 | 1263 | @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)' |
| 1251 | 1264 | @echo ' dir/ - Build all files in dir and below' |
| 1252 | − @echo ' dir/file.[ois] - Build specified target only' | |
| 1265 | + @echo ' dir/file.[oisS] - Build specified target only' | |
| 1266 | + @echo ' dir/file.lst - Build specified mixed source/assembly target only' | |
| 1267 | + @echo ' (requires a recent binutils and recent build (System.map))' | |
| 1253 | 1268 | @echo ' dir/file.ko - Build module including final link' |
| 1254 | 1269 | @echo ' modules_prepare - Set up for building external modules' |
| 1255 | 1270 | @echo ' tags/TAGS - Generate tags file for editors' |
| @@ -951,8 +951,6 @@ static int sa1111_resume(struct platform_device *dev) · 950 unmodified lines | ||
| 951 | 951 | if (!save) |
| 952 | 952 | return 0; |
| 953 | 953 | |
| 954 | − spin_lock_irqsave(&sachip->lock, flags); | |
| 955 | − | |
| 956 | 954 | /* |
| 957 | 955 | * Ensure that the SA1111 is still here. |
| 958 | 956 | * FIXME: shouldn't do this here. |
| @@ -969,6 +967,13 @@ static int sa1111_resume(struct platform_device *dev) · 10 unmodified lines | ||
| 969 | 967 | * First of all, wake up the chip. |
| 970 | 968 | */ |
| 971 | 969 | sa1111_wake(sachip); |
| 970 | + | |
| 971 | + /* | |
| 972 | + * Only lock for write ops. Also, sa1111_wake must be called with | |
| 973 | + * released spinlock! | |
| 974 | + */ | |
| 975 | + spin_lock_irqsave(&sachip->lock, flags); | |
| 976 | + | |
| 972 | 977 | sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0); |
| 973 | 978 | sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1); |
| 974 | 979 | |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/err.h> |
| 18 | 18 | #include <linux/io.h> |
| 19 | 19 | #include <linux/interrupt.h> |
| 20 | +#include <linux/completion.h> | |
| 20 | 21 | #include <mach/dma.h> |
| 21 | 22 | |
| 22 | 23 | #define MSM_DMOV_CHANNEL_COUNT 16 |
| @@ -32,7 +32,10 @@ void clk_disable(struct clk *clk) · 31 unmodified lines | ||
| 32 | 32 | } |
| 33 | 33 | EXPORT_SYMBOL(clk_disable); |
| 34 | 34 | |
| 35 | −/* We have a fixed clock alone, for now */ | |
| 35 | +static struct clk clk_24 = { | |
| 36 | + .rate = 2400000, | |
| 37 | +}; | |
| 38 | + | |
| 36 | 39 | static struct clk clk_48 = { |
| 37 | 40 | .rate = 48 * 1000 * 1000, |
| 38 | 41 | }; |
| @@ -50,6 +53,8 @@ static struct clk clk_default; · 11 unmodified lines | ||
| 50 | 53 | } |
| 51 | 54 | |
| 52 | 55 | static struct clk_lookup lookups[] = { |
| 56 | + CLK(&clk_24, "mtu0"), | |
| 57 | + CLK(&clk_24, "mtu1"), | |
| 53 | 58 | CLK(&clk_48, "uart0"), |
| 54 | 59 | CLK(&clk_48, "uart1"), |
| 55 | 60 | CLK(&clk_default, "gpio.0"), |
| @@ -59,10 +64,8 @@ static struct clk_lookup lookups[] = { · 3 unmodified lines | ||
| 59 | 64 | CLK(&clk_default, "rng"), |
| 60 | 65 | }; |
| 61 | 66 | |
| 62 | −static int __init clk_init(void) | |
| 67 | +int __init clk_init(void) | |
| 63 | 68 | { |
| 64 | 69 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
| 65 | 70 | return 0; |
| 66 | 71 | } |
| 67 | − | |
| 68 | −arch_initcall(clk_init); | |
| @@ -11,3 +11,5 @@ · 10 unmodified lines | ||
| 11 | 11 | struct clk { |
| 12 | 12 | unsigned long rate; |
| 13 | 13 | }; |
| 14 | + | |
| 15 | +int __init clk_init(void); | |
| @@ -31,6 +31,8 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <asm/cacheflush.h> |
| 32 | 32 | #include <asm/hardware/cache-l2x0.h> |
| 33 | 33 | |
| 34 | +#include "clock.h" | |
| 35 | + | |
| 34 | 36 | #define __MEM_4K_RESOURCE(x) \ |
| 35 | 37 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} |
| 36 | 38 | |
| @@ -143,6 +145,12 @@ void __init cpu8815_init_irq(void) · 106 unmodified lines | ||
| 143 | 145 | /* This modified VIC cell has two register blocks, at 0 and 0x20 */ |
| 144 | 146 | vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0); |
| 145 | 147 | vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0); |
| 148 | + | |
| 149 | + /* | |
| 150 | + * Init clocks here so that they are available for system timer | |
| 151 | + * initialization. | |
| 152 | + */ | |
| 153 | + clk_init(); | |
| 146 | 154 | } |
| 147 | 155 | |
| 148 | 156 | /* |
| @@ -263,11 +263,11 @@ const struct matrix_keymap_data palmtc_keymap_data = { · 262 unmodified lines | ||
| 263 | 263 | .keymap_size = ARRAY_SIZE(palmtc_matrix_keys), |
| 264 | 264 | }; |
| 265 | 265 | |
| 266 | −const static unsigned int palmtc_keypad_row_gpios[] = { | |
| 266 | +static const unsigned int palmtc_keypad_row_gpios[] = { | |
| 267 | 267 | 0, 9, 10, 11 |
| 268 | 268 | }; |
| 269 | 269 | |
| 270 | −const static unsigned int palmtc_keypad_col_gpios[] = { | |
| 270 | +static const unsigned int palmtc_keypad_col_gpios[] = { | |
| 271 | 271 | 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80 |
| 272 | 272 | }; |
| 273 | 273 | |
| @@ -818,6 +818,9 @@ static struct i2c_board_info akita_i2c_board_info[] = { · 817 unmodified lines | ||
| 818 | 818 | .type = "max7310", |
| 819 | 819 | .addr = 0x18, |
| 820 | 820 | .platform_data = &akita_ioexp, |
| 821 | + }, { | |
| 822 | + .type = "wm8750", | |
| 823 | + .addr = 0x1b, | |
| 821 | 824 | }, |
| 822 | 825 | }; |
| 823 | 826 | |
| @@ -7,4 +7,5 @@ obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o · 6 unmodified lines | ||
| 7 | 7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o |
| 8 | 8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o |
| 9 | 9 | obj-$(CONFIG_MACH_U5500) += board-u5500.o |
| 10 | −obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o | |
| 10 | +obj-$(CONFIG_SMP) += platsmp.o headsmp.o | |
| 11 | +obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | #include <asm/clkdev.h> |
| 18 | 18 | |
| 19 | +#include <plat/mtu.h> | |
| 19 | 20 | #include <mach/hardware.h> |
| 20 | 21 | #include "clock.h" |
| 21 | 22 | |
| @@ -59,6 +60,9 @@ · 37 unmodified lines | ||
| 59 | 60 | #define PRCM_DMACLK_MGT 0x074 |
| 60 | 61 | #define PRCM_B2R2CLK_MGT 0x078 |
| 61 | 62 | #define PRCM_TVCLK_MGT 0x07C |
| 63 | +#define PRCM_TCR 0x1C8 | |
| 64 | +#define PRCM_TCR_STOPPED (1 << 16) | |
| 65 | +#define PRCM_TCR_DOZE_MODE (1 << 17) | |
| 62 | 66 | #define PRCM_UNIPROCLK_MGT 0x278 |
| 63 | 67 | #define PRCM_SSPCLK_MGT 0x280 |
| 64 | 68 | #define PRCM_RNGCLK_MGT 0x284 |
| @@ -120,10 +124,95 @@ void clk_disable(struct clk *clk) · 55 unmodified lines | ||
| 120 | 124 | } |
| 121 | 125 | EXPORT_SYMBOL(clk_disable); |
| 122 | 126 | |
| 127 | +/* | |
| 128 | + * The MTU has a separate, rather complex muxing setup | |
| 129 | + * with alternative parents (peripheral cluster or | |
| 130 | + * ULP or fixed 32768 Hz) depending on settings | |
| 131 | + */ | |
| 132 | +static unsigned long clk_mtu_get_rate(struct clk *clk) | |
| 133 | +{ | |
| 134 | + void __iomem *addr = __io_address(U8500_PRCMU_BASE) | |
| 135 | + + PRCM_TCR; | |
| 136 | + u32 tcr = readl(addr); | |
| 137 | + int mtu = (int) clk->data; | |
| 138 | + /* | |
| 139 | + * One of these is selected eventually | |
| 140 | + * TODO: Replace the constant with a reference | |
| 141 | + * to the ULP source once this is modeled. | |
| 142 | + */ | |
| 143 | + unsigned long clk32k = 32768; | |
| 144 | + unsigned long mturate; | |
| 145 | + unsigned long retclk; | |
| 146 | + | |
| 147 | + /* Get the rate from the parent as a default */ | |
| 148 | + if (clk->parent_periph) | |
| 149 | + mturate = clk_get_rate(clk->parent_periph); | |
| 150 | + else if (clk->parent_cluster) | |
| 151 | + mturate = clk_get_rate(clk->parent_cluster); | |
| 152 | + else | |
| 153 | + /* We need to be connected SOMEWHERE */ | |
| 154 | + BUG(); | |
| 155 | + | |
| 156 | + /* | |
| 157 | + * Are we in doze mode? | |
| 158 | + * In this mode the parent peripheral or the fixed 32768 Hz | |
| 159 | + * clock is fed into the block. | |
| 160 | + */ | |
| 161 | + if (!(tcr & PRCM_TCR_DOZE_MODE)) { | |
| 162 | + /* | |
| 163 | + * Here we're using the clock input from the APE ULP | |
| 164 | + * clock domain. But first: are the timers stopped? | |
| 165 | + */ | |
| 166 | + if (tcr & PRCM_TCR_STOPPED) { | |
| 167 | + clk32k = 0; | |
| 168 | + mturate = 0; | |
| 169 | + } else { | |
| 170 | + /* Else default mode: 0 and 2.4 MHz */ | |
| 171 | + clk32k = 0; | |
| 172 | + if (cpu_is_u5500()) | |
| 173 | + /* DB5500 divides by 8 */ | |
| 174 | + mturate /= 8; | |
| 175 | + else if (cpu_is_u8500ed()) { | |
| 176 | + /* | |
| 177 | + * This clocking setting must not be used | |
| 178 | + * in the ED chip, it is simply not | |
| 179 | + * connected anywhere! | |
| 180 | + */ | |
| 181 | + mturate = 0; | |
| 182 | + BUG(); | |
| 183 | + } else | |
| 184 | + /* | |
| 185 | + * In this mode the ulp38m4 clock is divided | |
| 186 | + * by a factor 16, on the DB8500 typically | |
| 187 | + * 38400000 / 16 ~ 2.4 MHz. | |
| 188 | + * TODO: Replace the constant with a reference | |
| 189 | + * to the ULP source once this is modeled. | |
| 190 | + */ | |
| 191 | + mturate = 38400000 / 16; | |
| 192 | + } | |
| 193 | + } | |
| 194 | + | |
| 195 | + /* Return the clock selected for this MTU */ | |
| 196 | + if (tcr & (1 << mtu)) | |
| 197 | + retclk = clk32k; | |
| 198 | + else | |
| 199 | + retclk = mturate; | |
| 200 | + | |
| 201 | + pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk); | |
| 202 | + return retclk; | |
| 203 | +} | |
| 204 | + | |
| 123 | 205 | unsigned long clk_get_rate(struct clk *clk) |
| 124 | 206 | { |
| 125 | 207 | unsigned long rate; |
| 126 | 208 | |
| 209 | + /* | |
| 210 | + * If there is a custom getrate callback for this clock, | |
| 211 | + * it will take precedence. | |
| 212 | + */ | |
| 213 | + if (clk->get_rate) | |
| 214 | + return clk->get_rate(clk); | |
| 215 | + | |
| 127 | 216 | if (clk->ops && clk->ops->get_rate) |
| 128 | 217 | return clk->ops->get_rate(clk); |
| 129 | 218 | |
| @@ -341,8 +430,9 @@ static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); · 211 unmodified lines | ||
| 341 | 430 | |
| 342 | 431 | /* Peripheral Cluster #6 */ |
| 343 | 432 | |
| 344 | −static DEFINE_PRCC_CLK(6, mtu1_v1, 8, -1, NULL); | |
| 345 | −static DEFINE_PRCC_CLK(6, mtu0_v1, 7, -1, NULL); | |
| 433 | +/* MTU ID in data */ | |
| 434 | +static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); | |
| 435 | +static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); | |
| 346 | 436 | static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); |
| 347 | 437 | static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); |
| 348 | 438 | static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); |
| @@ -357,8 +447,9 @@ static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); · 8 unmodified lines | ||
| 357 | 447 | /* Peripheral Cluster #7 */ |
| 358 | 448 | |
| 359 | 449 | static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); |
| 360 | −static DEFINE_PRCC_CLK(7, mtu1_ed, 3, -1, NULL); | |
| 361 | −static DEFINE_PRCC_CLK(7, mtu0_ed, 2, -1, NULL); | |
| 450 | +/* MTU ID in data */ | |
| 451 | +static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); | |
| 452 | +static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); | |
| 362 | 453 | static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); |
| 363 | 454 | static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); |
| 364 | 455 | |
| @@ -503,15 +594,17 @@ static struct clk_lookup u8500_v1_clks[] = { · 138 unmodified lines | ||
| 503 | 594 | CLK(uiccclk, "uicc", NULL), |
| 504 | 595 | }; |
| 505 | 596 | |
| 506 | −static int __init clk_init(void) | |
| 597 | +int __init clk_init(void) | |
| 507 | 598 | { |
| 508 | 599 | if (cpu_is_u8500ed()) { |
| 509 | 600 | clk_prcmu_ops.enable = clk_prcmu_ed_enable; |
| 510 | 601 | clk_prcmu_ops.disable = clk_prcmu_ed_disable; |
| 602 | + clk_per6clk.rate = 100000000; | |
| 511 | 603 | } else if (cpu_is_u5500()) { |
| 512 | 604 | /* Clock tree for U5500 not implemented yet */ |
| 513 | 605 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; |
| 514 | 606 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; |
| 607 | + clk_per6clk.rate = 26000000; | |
| 515 | 608 | } |
| 516 | 609 | |
| 517 | 610 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); |
| @@ -522,4 +615,3 @@ static int __init clk_init(void) · 4 unmodified lines | ||
| 522 | 615 | |
| 523 | 616 | return 0; |
| 524 | 617 | } |
| 525 | −arch_initcall(clk_init); | |
| @@ -28,6 +28,9 @@ struct clkops { · 27 unmodified lines | ||
| 28 | 28 | * @ops: pointer to clkops struct used to control this clock |
| 29 | 29 | * @name: name, for debugging |
| 30 | 30 | * @enabled: refcount. positive if enabled, zero if disabled |
| 31 | + * @get_rate: custom callback for getting the clock rate | |
| 32 | + * @data: custom per-clock data for example for the get_rate | |
| 33 | + * callback | |
| 31 | 34 | * @rate: fixed rate for clocks which don't implement |
| 32 | 35 | * ops->getrate |
| 33 | 36 | * @prcmu_cg_off: address offset of the combined enable/disable register |
| @@ -67,6 +70,8 @@ struct clk { · 33 unmodified lines | ||
| 67 | 70 | const struct clkops *ops; |
| 68 | 71 | const char *name; |
| 69 | 72 | unsigned int enabled; |
| 73 | + unsigned long (*get_rate)(struct clk *); | |
| 74 | + void *data; | |
| 70 | 75 | |
| 71 | 76 | unsigned long rate; |
| 72 | 77 | struct list_head list; |
| @@ -117,9 +122,26 @@ struct clk clk_##_name = { \ · 44 unmodified lines | ||
| 117 | 122 | .parent_periph = _kernclk \ |
| 118 | 123 | } |
| 119 | 124 | |
| 125 | +#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \ | |
| 126 | +struct clk clk_##_name = { \ | |
| 127 | + .name = #_name, \ | |
| 128 | + .ops = &clk_prcc_ops, \ | |
| 129 | + .cluster = _pclust, \ | |
| 130 | + .prcc_bus = _bus_en, \ | |
| 131 | + .prcc_kernel = _kernel_en, \ | |
| 132 | + .parent_cluster = &clk_per##_pclust##clk, \ | |
| 133 | + .parent_periph = _kernclk, \ | |
| 134 | + .get_rate = _callback, \ | |
| 135 | + .data = (void *) _data \ | |
| 136 | + } | |
| 137 | + | |
| 138 | + | |
| 120 | 139 | #define CLK(_clk, _devname, _conname) \ |
| 121 | 140 | { \ |
| 122 | 141 | .clk = &clk_##_clk, \ |
| 123 | 142 | .dev_id = _devname, \ |
| 124 | 143 | .con_id = _conname, \ |
| 125 | 144 | } |
| 145 | + | |
| 146 | +int __init clk_db8500_ed_fixup(void); | |
| 147 | +int __init clk_init(void); | |
| @@ -62,6 +62,12 @@ void __init ux500_init_irq(void) · 61 unmodified lines | ||
| 62 | 62 | { |
| 63 | 63 | gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); |
| 64 | 64 | gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); |
| 65 | + | |
| 66 | + /* | |
| 67 | + * Init clocks here so that they are available for system timer | |
| 68 | + * initialization. | |
| 69 | + */ | |
| 70 | + clk_init(); | |
| 65 | 71 | } |
| 66 | 72 | |
| 67 | 73 | #ifdef CONFIG_CACHE_L2X0 |
| @@ -18,7 +18,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom) · 17 unmodified lines | ||
| 18 | 18 | { |
| 19 | 19 | asm("\ |
| 20 | 20 | stmfd sp!, {r4-r9, lr} \n\ |
| 21 | − mov ip, %0 \n\ | |
| 21 | + mov ip, %2 \n\ | |
| 22 | 22 | 1: mov lr, r1 \n\ |
| 23 | 23 | ldmia r1!, {r2 - r9} \n\ |
| 24 | 24 | pld [lr, #32] \n\ |
| @@ -64,7 +64,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom) · 39 unmodified lines | ||
| 64 | 64 | mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\ |
| 65 | 65 | ldmfd sp!, {r4-r9, pc}" |
| 66 | 66 | : |
| 67 | − : "I" (PAGE_SIZE)); | |
| 67 | + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE)); | |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | void feroceon_copy_user_highpage(struct page *to, struct page *from, |
| @@ -27,7 +27,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom) · 26 unmodified lines | ||
| 27 | 27 | { |
| 28 | 28 | asm("\ |
| 29 | 29 | stmfd sp!, {r4, lr} @ 2\n\ |
| 30 | − mov r2, %0 @ 1\n\ | |
| 30 | + mov r2, %2 @ 1\n\ | |
| 31 | 31 | ldmia r1!, {r3, r4, ip, lr} @ 4\n\ |
| 32 | 32 | 1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ |
| 33 | 33 | stmia r0!, {r3, r4, ip, lr} @ 4\n\ |
| @@ -44,7 +44,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom) · 10 unmodified lines | ||
| 44 | 44 | mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\ |
| 45 | 45 | ldmfd sp!, {r4, pc} @ 3" |
| 46 | 46 | : |
| 47 | − : "I" (PAGE_SIZE / 64)); | |
| 47 | + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); | |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | void v4wb_copy_user_highpage(struct page *to, struct page *from, |
| @@ -25,7 +25,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom) · 24 unmodified lines | ||
| 25 | 25 | { |
| 26 | 26 | asm("\ |
| 27 | 27 | stmfd sp!, {r4, lr} @ 2\n\ |
| 28 | − mov r2, %0 @ 1\n\ | |
| 28 | + mov r2, %2 @ 1\n\ | |
| 29 | 29 | ldmia r1!, {r3, r4, ip, lr} @ 4\n\ |
| 30 | 30 | 1: stmia r0!, {r3, r4, ip, lr} @ 4\n\ |
| 31 | 31 | ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\ |
| @@ -40,7 +40,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom) · 8 unmodified lines | ||
| 40 | 40 | mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\ |
| 41 | 41 | ldmfd sp!, {r4, pc} @ 3" |
| 42 | 42 | : |
| 43 | − : "I" (PAGE_SIZE / 64)); | |
| 43 | + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); | |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | void v4wt_copy_user_highpage(struct page *to, struct page *from, |
| @@ -34,7 +34,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom) · 33 unmodified lines | ||
| 34 | 34 | { |
| 35 | 35 | asm("\ |
| 36 | 36 | stmfd sp!, {r4, r5, lr} \n\ |
| 37 | − mov lr, %0 \n\ | |
| 37 | + mov lr, %2 \n\ | |
| 38 | 38 | \n\ |
| 39 | 39 | pld [r1, #0] \n\ |
| 40 | 40 | pld [r1, #32] \n\ |
| @@ -67,7 +67,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom) · 26 unmodified lines | ||
| 67 | 67 | \n\ |
| 68 | 68 | ldmfd sp!, {r4, r5, pc}" |
| 69 | 69 | : |
| 70 | − : "I" (PAGE_SIZE / 64 - 1)); | |
| 70 | + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1)); | |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | void xsc3_mc_copy_user_highpage(struct page *to, struct page *from, |
| @@ -393,6 +393,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, · 392 unmodified lines | ||
| 393 | 393 | if (addr < TASK_SIZE) |
| 394 | 394 | return do_page_fault(addr, fsr, regs); |
| 395 | 395 | |
| 396 | + if (user_mode(regs)) | |
| 397 | + goto bad_area; | |
| 398 | + | |
| 396 | 399 | index = pgd_index(addr); |
| 397 | 400 | |
| 398 | 401 | /* |
| @@ -48,7 +48,16 @@ void *kmap_atomic(struct page *page, enum km_type type) · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | debug_kmap_atomic(type); |
| 50 | 50 | |
| 51 | − kmap = kmap_high_get(page); | |
| 51 | +#ifdef CONFIG_DEBUG_HIGHMEM | |
| 52 | + /* | |
| 53 | + * There is no cache coherency issue when non VIVT, so force the | |
| 54 | + * dedicated kmap usage for better debugging purposes in that case. | |
| 55 | + */ | |
| 56 | + if (!cache_is_vivt()) | |
| 57 | + kmap = NULL; | |
| 58 | + else | |
| 59 | +#endif | |
| 60 | + kmap = kmap_high_get(page); | |
| 52 | 61 | if (kmap) |
| 53 | 62 | return kmap; |
| 54 | 63 | |
| @@ -678,10 +678,10 @@ void __init mem_init(void) · 677 unmodified lines | ||
| 678 | 678 | void free_initmem(void) |
| 679 | 679 | { |
| 680 | 680 | #ifdef CONFIG_HAVE_TCM |
| 681 | − extern char *__tcm_start, *__tcm_end; | |
| 681 | + extern char __tcm_start, __tcm_end; | |
| 682 | 682 | |
| 683 | − totalram_pages += free_area(__phys_to_pfn(__pa(__tcm_start)), | |
| 684 | − __phys_to_pfn(__pa(__tcm_end)), | |
| 683 | + totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), | |
| 684 | + __phys_to_pfn(__pa(&__tcm_end)), | |
| 685 | 685 | "TCM link"); |
| 686 | 686 | #endif |
| 687 | 687 | |
| @@ -13,7 +13,9 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/irq.h> |
| 14 | 14 | #include <linux/io.h> |
| 15 | 15 | #include <linux/clockchips.h> |
| 16 | +#include <linux/clk.h> | |
| 16 | 17 | #include <linux/jiffies.h> |
| 18 | +#include <linux/err.h> | |
| 17 | 19 | #include <asm/mach/time.h> |
| 18 | 20 | |
| 19 | 21 | #include <plat/mtu.h> |
| @@ -124,13 +126,25 @@ static struct irqaction nmdk_timer_irq = { · 104 unmodified lines | ||
| 124 | 126 | void __init nmdk_timer_init(void) |
| 125 | 127 | { |
| 126 | 128 | unsigned long rate; |
| 127 | − u32 cr = MTU_CRn_32BITS;; | |
| 129 | + struct clk *clk0; | |
| 130 | + struct clk *clk1; | |
| 131 | + u32 cr; | |
| 132 | + | |
| 133 | + clk0 = clk_get_sys("mtu0", NULL); | |
| 134 | + BUG_ON(IS_ERR(clk0)); | |
| 135 | + | |
| 136 | + clk1 = clk_get_sys("mtu1", NULL); | |
| 137 | + BUG_ON(IS_ERR(clk1)); | |
| 138 | + | |
| 139 | + clk_enable(clk0); | |
| 140 | + clk_enable(clk1); | |
| 128 | 141 | |
| 129 | 142 | /* |
| 130 | 143 | * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: |
| 131 | 144 | * use a divide-by-16 counter if it's more than 16MHz |
| 132 | 145 | */ |
| 133 | − rate = CLOCK_TICK_RATE; | |
| 146 | + cr = MTU_CRn_32BITS;; | |
| 147 | + rate = clk_get_rate(clk0); | |
| 134 | 148 | if (rate > 16 << 20) { |
| 135 | 149 | rate /= 16; |
| 136 | 150 | cr |= MTU_CRn_PRESCALE_16; |
| @@ -153,6 +167,14 @@ void __init nmdk_timer_init(void) · 16 unmodified lines | ||
| 153 | 167 | nmdk_clksrc.name); |
| 154 | 168 | |
| 155 | 169 | /* Timer 1 is used for events, fix according to rate */ |
| 170 | + cr = MTU_CRn_32BITS; | |
| 171 | + rate = clk_get_rate(clk1); | |
| 172 | + if (rate > 16 << 20) { | |
| 173 | + rate /= 16; | |
| 174 | + cr |= MTU_CRn_PRESCALE_16; | |
| 175 | + } else { | |
| 176 | + cr |= MTU_CRn_PRESCALE_1; | |
| 177 | + } | |
| 156 | 178 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ |
| 157 | 179 | nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift); |
| 158 | 180 | nmdk_clkevt.max_delta_ns = |
| @@ -277,7 +277,7 @@ ENTRY(vfp_put_double) · 276 unmodified lines | ||
| 277 | 277 | #ifdef CONFIG_VFPv3 |
| 278 | 278 | @ d16 - d31 registers |
| 279 | 279 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 280 | −1: mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr | |
| 280 | +1: mcrr p11, 3, r0, r1, c\dr @ fmdrr r0, r1, d\dr | |
| 281 | 281 | mov pc, lr |
| 282 | 282 | .org 1b + 8 |
| 283 | 283 | .endr |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/module.h> |
| 20 | 20 | #include <linux/miscdevice.h> |
| 21 | 21 | #include <linux/delay.h> |
| 22 | +#include <linux/smp_lock.h> | |
| 22 | 23 | #include <linux/bcd.h> |
| 23 | 24 | #include <linux/capability.h> |
| 24 | 25 | |
| @@ -238,9 +239,7 @@ static unsigned char days_in_mo[] = · 213 unmodified lines | ||
| 238 | 239 | |
| 239 | 240 | /* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */ |
| 240 | 241 | |
| 241 | −static int | |
| 242 | −rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |
| 243 | − unsigned long arg) | |
| 242 | +static int rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
| 244 | 243 | { |
| 245 | 244 | unsigned long flags; |
| 246 | 245 | |
| @@ -354,6 +353,17 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, · 107 unmodified lines | ||
| 354 | 353 | } |
| 355 | 354 | } |
| 356 | 355 | |
| 356 | +static long rtc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
| 357 | +{ | |
| 358 | + int ret; | |
| 359 | + | |
| 360 | + lock_kernel(); | |
| 361 | + ret = rtc_ioctl(file, cmd, arg); | |
| 362 | + unlock_kernel(); | |
| 363 | + | |
| 364 | + return ret; | |
| 365 | +} | |
| 366 | + | |
| 357 | 367 | static void |
| 358 | 368 | print_rtc_status(void) |
| 359 | 369 | { |
| @@ -375,8 +385,8 @@ print_rtc_status(void) · 15 unmodified lines | ||
| 375 | 385 | /* The various file operations we support. */ |
| 376 | 386 | |
| 377 | 387 | static const struct file_operations rtc_fops = { |
| 378 | − .owner = THIS_MODULE, | |
| 379 | − .ioctl = rtc_ioctl, | |
| 388 | + .owner = THIS_MODULE, | |
| 389 | + .unlocked_ioctl = rtc_unlocked_ioctl, | |
| 380 | 390 | }; |
| 381 | 391 | |
| 382 | 392 | /* Probe for the chip by writing something to its RAM and try reading it back. */ |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/delay.h> |
| 28 | 28 | #include <linux/bcd.h> |
| 29 | 29 | #include <linux/mutex.h> |
| 30 | +#include <linux/smp_lock.h> | |
| 30 | 31 | |
| 31 | 32 | #include <asm/uaccess.h> |
| 32 | 33 | #include <asm/system.h> |
| @@ -53,7 +54,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ · 20 unmodified lines | ||
| 53 | 54 | static const unsigned char days_in_month[] = |
| 54 | 55 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
| 55 | 56 | |
| 56 | −int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | |
| 57 | +static long pcf8563_unlocked_ioctl(struct file *, unsigned int, unsigned long); | |
| 57 | 58 | |
| 58 | 59 | /* Cache VL bit value read at driver init since writing the RTC_SECOND |
| 59 | 60 | * register clears the VL status. |
| @@ -62,7 +63,7 @@ static int voltage_low; · 2 unmodified lines | ||
| 62 | 63 | |
| 63 | 64 | static const struct file_operations pcf8563_fops = { |
| 64 | 65 | .owner = THIS_MODULE, |
| 65 | − .ioctl = pcf8563_ioctl, | |
| 66 | + .unlocked_ioctl = pcf8563_unlocked_ioctl, | |
| 66 | 67 | }; |
| 67 | 68 | |
| 68 | 69 | unsigned char |
| @@ -212,8 +213,7 @@ pcf8563_exit(void) · 143 unmodified lines | ||
| 212 | 213 | * ioctl calls for this driver. Why return -ENOTTY upon error? Because |
| 213 | 214 | * POSIX says so! |
| 214 | 215 | */ |
| 215 | −int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |
| 216 | − unsigned long arg) | |
| 216 | +static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |
| 217 | 217 | { |
| 218 | 218 | /* Some sanity checks. */ |
| 219 | 219 | if (_IOC_TYPE(cmd) != RTC_MAGIC) |
| @@ -339,6 +339,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, · 119 unmodified lines | ||
| 339 | 339 | return 0; |
| 340 | 340 | } |
| 341 | 341 | |
| 342 | +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |
| 343 | +{ | |
| 344 | + int ret; | |
| 345 | + | |
| 346 | + lock_kernel(); | |
| 347 | + return pcf8563_ioctl(filp, cmd, arg); | |
| 348 | + unlock_kernel(); | |
| 349 | + | |
| 350 | + return ret; | |
| 351 | +} | |
| 352 | + | |
| 342 | 353 | static int __init pcf8563_register(void) |
| 343 | 354 | { |
| 344 | 355 | if (pcf8563_init() < 0) { |
| @@ -17,8 +17,8 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/kernel.h> |
| 18 | 18 | #include <linux/init.h> |
| 19 | 19 | |
| 20 | −#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); | |
| 21 | −#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); | |
| 20 | +#define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); | |
| 21 | +#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); | |
| 22 | 22 | |
| 23 | 23 | /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is |
| 24 | 24 | * global just so that the kernel gdb can use it. |
| @@ -116,12 +116,12 @@ static unsigned int startup_crisv10_irq(unsigned int irq) · 91 unmodified lines | ||
| 116 | 116 | |
| 117 | 117 | static void enable_crisv10_irq(unsigned int irq) |
| 118 | 118 | { |
| 119 | − unmask_irq(irq); | |
| 119 | + crisv10_unmask_irq(irq); | |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | static void disable_crisv10_irq(unsigned int irq) |
| 123 | 123 | { |
| 124 | − mask_irq(irq); | |
| 124 | + crisv10_mask_irq(irq); | |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | static void ack_crisv10_irq(unsigned int irq) |
| @@ -1,5 +1,4 @@ | ||
| 1 | −/* $Id: dmacopy.c,v 1.1 2001/12/17 13:59:27 bjornw Exp $ | |
| 2 | − * | |
| 1 | +/* | |
| 3 | 2 | * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax |
| 4 | 3 | */ |
| 5 | 4 | |
| @@ -13,11 +12,11 @@ void *dma_memcpy(void *pdst, · 7 unmodified lines | ||
| 13 | 12 | unsigned int pn) |
| 14 | 13 | { |
| 15 | 14 | static etrax_dma_descr indma, outdma; |
| 16 | − | |
| 17 | − D(printk("dma_memcpy %d bytes... ", pn)); | |
| 15 | + | |
| 16 | + D(printk(KERN_DEBUG "dma_memcpy %d bytes... ", pn)); | |
| 18 | 17 | |
| 19 | 18 | #if 0 |
| 20 | − *R_GEN_CONFIG = genconfig_shadow = | |
| 19 | + *R_GEN_CONFIG = genconfig_shadow = | |
| 21 | 20 | (genconfig_shadow & ~0x3c0000) | |
| 22 | 21 | IO_STATE(R_GEN_CONFIG, dma6, intdma7) | |
| 23 | 22 | IO_STATE(R_GEN_CONFIG, dma7, intdma6); |
| @@ -32,11 +31,11 @@ void *dma_memcpy(void *pdst, · 8 unmodified lines | ||
| 32 | 31 | *R_DMA_CH7_FIRST = &outdma; |
| 33 | 32 | *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start); |
| 34 | 33 | *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start); |
| 35 | − | |
| 36 | − while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ; | |
| 37 | 34 | |
| 38 | − D(printk("done\n")); | |
| 35 | + while (*R_DMA_CH7_CMD == 1) | |
| 36 | + /* wait for completion */; | |
| 39 | 37 | |
| 38 | + D(printk(KERN_DEBUG "done\n")); | |
| 40 | 39 | } |
| 41 | 40 | |
| 42 | 41 | |
| @@ -1,13 +1,11 @@ | ||
| 1 | 1 | /* |
| 2 | − * $Id: hw_settings.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $ | |
| 3 | − * | |
| 4 | 2 | * This table is used by some tools to extract hardware parameters. |
| 5 | 3 | * The table should be included in the kernel and the decompressor. |
| 6 | 4 | * Don't forget to update the tools if you change this table. |
| 7 | 5 | * |
| 8 | 6 | * Copyright (C) 2001 Axis Communications AB |
| 9 | 7 | * |
| 10 | − * Authors: Mikael Starvik (starvik@axis.com) | |
| 8 | + * Authors: Mikael Starvik (starvik@axis.com) | |
| 11 | 9 | */ |
| 12 | 10 | |
| 13 | 11 | #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \ |
| @@ -15,13 +13,13 @@ · 1 unmodified line | ||
| 15 | 13 | #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \ |
| 16 | 14 | (CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \ |
| 17 | 15 | (CONFIG_ETRAX_DEF_R_PORT_PB_DATA)) |
| 18 | − | |
| 16 | + | |
| 19 | 17 | .ascii "HW_PARAM_MAGIC" ; Magic number |
| 20 | 18 | .dword 0xc0004000 ; Kernel start address |
| 21 | 19 | |
| 22 | 20 | ; Debug port |
| 23 | 21 | #ifdef CONFIG_ETRAX_DEBUG_PORT0 |
| 24 | − .dword 0 | |
| 22 | + .dword 0 | |
| 25 | 23 | #elif defined(CONFIG_ETRAX_DEBUG_PORT1) |
| 26 | 24 | .dword 1 |
| 27 | 25 | #elif defined(CONFIG_ETRAX_DEBUG_PORT2) |
| @@ -30,7 +28,7 @@ · 2 unmodified lines | ||
| 30 | 28 | .dword 3 |
| 31 | 29 | #else |
| 32 | 30 | .dword 4 ; No debug |
| 33 | −#endif | |
| 31 | +#endif | |
| 34 | 32 | |
| 35 | 33 | ; SDRAM or EDO DRAM? |
| 36 | 34 | #ifdef CONFIG_ETRAX_SDRAM |
| @@ -39,7 +37,7 @@ · 2 unmodified lines | ||
| 39 | 37 | .dword 0 |
| 40 | 38 | #endif |
| 41 | 39 | |
| 42 | − ; Register values | |
| 40 | + ; Register values | |
| 43 | 41 | .dword R_WAITSTATES |
| 44 | 42 | .dword CONFIG_ETRAX_DEF_R_WAITSTATES |
| 45 | 43 | .dword R_BUS_CONFIG |
| @@ -56,7 +54,7 @@ · 10 unmodified lines | ||
| 56 | 54 | .dword CONFIG_ETRAX_DEF_R_DRAM_TIMING |
| 57 | 55 | #endif |
| 58 | 56 | .dword R_PORT_PA_SET |
| 59 | − .dword PA_SET_VALUE | |
| 57 | + .dword PA_SET_VALUE | |
| 60 | 58 | .dword R_PORT_PB_SET |
| 61 | 59 | .dword PB_SET_VALUE |
| 62 | 60 | .dword 0 ; No more register values |
| @@ -360,24 +360,10 @@ config ETRAX_SER4_DSR_BIT · 359 unmodified lines | ||
| 360 | 360 | string "Ser 4 DSR bit (empty = not used)" |
| 361 | 361 | depends on ETRAX_SERIAL_PORT4 |
| 362 | 362 | |
| 363 | −config ETRAX_SER3_CD_BIT | |
| 363 | +config ETRAX_SER4_CD_BIT | |
| 364 | 364 | string "Ser 4 CD bit (empty = not used)" |
| 365 | 365 | depends on ETRAX_SERIAL_PORT4 |
| 366 | 366 | |
| 367 | −config ETRAX_RS485 | |
| 368 | − bool "RS-485 support" | |
| 369 | − depends on ETRAXFS_SERIAL | |
| 370 | − help | |
| 371 | − Enables support for RS-485 serial communication. For a primer on | |
| 372 | − RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>. | |
| 373 | − | |
| 374 | −config ETRAX_RS485_DISABLE_RECEIVER | |
| 375 | − bool "Disable serial receiver" | |
| 376 | − depends on ETRAX_RS485 | |
| 377 | − help | |
| 378 | − It is necessary to disable the serial receiver to avoid serial | |
| 379 | − loopback. Not all products are able to do this in software only. | |
| 380 | − | |
| 381 | 367 | config ETRAX_SYNCHRONOUS_SERIAL |
| 382 | 368 | bool "Synchronous serial-port support" |
| 383 | 369 | depends on ETRAX_ARCH_V32 |
| @@ -649,10 +649,10 @@ i2c_release(struct inode *inode, struct file *filp) · 648 unmodified lines | ||
| 649 | 649 | /* Main device API. ioctl's to write or read to/from i2c registers. |
| 650 | 650 | */ |
| 651 | 651 | |
| 652 | −static int | |
| 653 | −i2c_ioctl(struct inode *inode, struct file *file, | |
| 654 | − unsigned int cmd, unsigned long arg) | |
| 652 | +static long | |
| 653 | +i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
| 655 | 654 | { |
| 655 | + int ret; | |
| 656 | 656 | if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { |
| 657 | 657 | return -ENOTTY; |
| 658 | 658 | } |
| @@ -665,9 +665,13 @@ i2c_ioctl(struct inode *inode, struct file *file, · 6 unmodified lines | ||
| 665 | 665 | I2C_ARGREG(arg), |
| 666 | 666 | I2C_ARGVALUE(arg))); |
| 667 | 667 | |
| 668 | − return i2c_writereg(I2C_ARGSLAVE(arg), | |
| 668 | + lock_kernel(); | |
| 669 | + ret = i2c_writereg(I2C_ARGSLAVE(arg), | |
| 669 | 670 | I2C_ARGREG(arg), |
| 670 | 671 | I2C_ARGVALUE(arg)); |
| 672 | + unlock_kernel(); | |
| 673 | + return ret; | |
| 674 | + | |
| 671 | 675 | case I2C_READREG: |
| 672 | 676 | { |
| 673 | 677 | unsigned char val; |
| @@ -675,7 +679,9 @@ i2c_ioctl(struct inode *inode, struct file *file, · 1 unmodified line | ||
| 675 | 679 | D(printk("i2cr %d %d ", |
| 676 | 680 | I2C_ARGSLAVE(arg), |
| 677 | 681 | I2C_ARGREG(arg))); |
| 682 | + lock_kernel(); | |
| 678 | 683 | val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg)); |
| 684 | + unlock_kernel(); | |
| 679 | 685 | D(printk("= %d\n", val)); |
| 680 | 686 | return val; |
| 681 | 687 | } |
| @@ -688,10 +694,10 @@ i2c_ioctl(struct inode *inode, struct file *file, · 6 unmodified lines | ||
| 688 | 694 | } |
| 689 | 695 | |
| 690 | 696 | static const struct file_operations i2c_fops = { |
| 691 | − .owner = THIS_MODULE, | |
| 692 | − .ioctl = i2c_ioctl, | |
| 693 | − .open = i2c_open, | |
| 694 | − .release = i2c_release, | |
| 697 | + .owner = THIS_MODULE, | |
| 698 | + .unlocked_ioctl = i2c_ioctl, | |
| 699 | + .open = i2c_open, | |
| 700 | + .release = i2c_release, | |
| 695 | 701 | }; |
| 696 | 702 | |
| 697 | 703 | static int __init i2c_init(void) |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/init.h> |
| 25 | 25 | #include <linux/fs.h> |
| 26 | 26 | #include <linux/ioctl.h> |
| 27 | +#include <linux/smp_lock.h> | |
| 27 | 28 | #include <linux/delay.h> |
| 28 | 29 | #include <linux/bcd.h> |
| 29 | 30 | #include <linux/mutex.h> |
| @@ -49,7 +50,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ · 19 unmodified lines | ||
| 49 | 50 | static const unsigned char days_in_month[] = |
| 50 | 51 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
| 51 | 52 | |
| 52 | −int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | |
| 53 | +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); | |
| 53 | 54 | |
| 54 | 55 | /* Cache VL bit value read at driver init since writing the RTC_SECOND |
| 55 | 56 | * register clears the VL status. |
| @@ -57,8 +58,8 @@ int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); · 1 unmodified line | ||
| 57 | 58 | static int voltage_low; |
| 58 | 59 | |
| 59 | 60 | static const struct file_operations pcf8563_fops = { |
| 60 | − .owner = THIS_MODULE, | |
| 61 | − .ioctl = pcf8563_ioctl | |
| 61 | + .owner = THIS_MODULE, | |
| 62 | + .unlocked_ioctl = pcf8563_unlocked_ioctl, | |
| 62 | 63 | }; |
| 63 | 64 | |
| 64 | 65 | unsigned char |
| @@ -208,8 +209,7 @@ pcf8563_exit(void) · 143 unmodified lines | ||
| 208 | 209 | * ioctl calls for this driver. Why return -ENOTTY upon error? Because |
| 209 | 210 | * POSIX says so! |
| 210 | 211 | */ |
| 211 | −int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |
| 212 | − unsigned long arg) | |
| 212 | +static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |
| 213 | 213 | { |
| 214 | 214 | /* Some sanity checks. */ |
| 215 | 215 | if (_IOC_TYPE(cmd) != RTC_MAGIC) |
| @@ -335,6 +335,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, · 119 unmodified lines | ||
| 335 | 335 | return 0; |
| 336 | 336 | } |
| 337 | 337 | |
| 338 | +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |
| 339 | +{ | |
| 340 | + int ret; | |
| 341 | + | |
| 342 | + lock_kernel(); | |
| 343 | + return pcf8563_ioctl(filp, cmd, arg); | |
| 344 | + unlock_kernel(); | |
| 345 | + | |
| 346 | + return ret; | |
| 347 | +} | |
| 348 | + | |
| 338 | 349 | static int __init pcf8563_register(void) |
| 339 | 350 | { |
| 340 | 351 | if (pcf8563_init() < 0) { |
| @@ -24,5 +24,5 @@ EXPORT_SYMBOL(crisv32_io_get_name); · 23 unmodified lines | ||
| 24 | 24 | EXPORT_SYMBOL(crisv32_io_get); |
| 25 | 25 | |
| 26 | 26 | /* Functions masking/unmasking interrupts */ |
| 27 | −EXPORT_SYMBOL(mask_irq); | |
| 28 | −EXPORT_SYMBOL(unmask_irq); | |
| 27 | +EXPORT_SYMBOL(crisv32_mask_irq); | |
| 28 | +EXPORT_SYMBOL(crisv32_unmask_irq); | |
| @@ -280,8 +280,7 @@ out: · 279 unmodified lines | ||
| 280 | 280 | return cpu; |
| 281 | 281 | } |
| 282 | 282 | |
| 283 | −void | |
| 284 | −mask_irq(int irq) | |
| 283 | +void crisv32_mask_irq(int irq) | |
| 285 | 284 | { |
| 286 | 285 | int cpu; |
| 287 | 286 | |
| @@ -289,8 +288,7 @@ mask_irq(int irq) · 1 unmodified line | ||
| 289 | 288 | block_irq(irq, cpu); |
| 290 | 289 | } |
| 291 | 290 | |
| 292 | −void | |
| 293 | −unmask_irq(int irq) | |
| 291 | +void crisv32_unmask_irq(int irq) | |
| 294 | 292 | { |
| 295 | 293 | unblock_irq(irq, irq_cpu(irq)); |
| 296 | 294 | } |
| @@ -298,23 +296,23 @@ unmask_irq(int irq) · 1 unmodified line | ||
| 298 | 296 | |
| 299 | 297 | static unsigned int startup_crisv32_irq(unsigned int irq) |
| 300 | 298 | { |
| 301 | − unmask_irq(irq); | |
| 299 | + crisv32_unmask_irq(irq); | |
| 302 | 300 | return 0; |
| 303 | 301 | } |
| 304 | 302 | |
| 305 | 303 | static void shutdown_crisv32_irq(unsigned int irq) |
| 306 | 304 | { |
| 307 | − mask_irq(irq); | |
| 305 | + crisv32_mask_irq(irq); | |
| 308 | 306 | } |
| 309 | 307 | |
| 310 | 308 | static void enable_crisv32_irq(unsigned int irq) |
| 311 | 309 | { |
| 312 | − unmask_irq(irq); | |
| 310 | + crisv32_unmask_irq(irq); | |
| 313 | 311 | } |
| 314 | 312 | |
| 315 | 313 | static void disable_crisv32_irq(unsigned int irq) |
| 316 | 314 | { |
| 317 | − mask_irq(irq); | |
| 315 | + crisv32_mask_irq(irq); | |
| 318 | 316 | } |
| 319 | 317 | |
| 320 | 318 | static void ack_crisv32_irq(unsigned int irq) |
| @@ -168,8 +168,8 @@ void __init smp_callin(void) · 167 unmodified lines | ||
| 168 | 168 | |
| 169 | 169 | /* Enable IRQ and idle */ |
| 170 | 170 | REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); |
| 171 | − unmask_irq(IPI_INTR_VECT); | |
| 172 | − unmask_irq(TIMER0_INTR_VECT); | |
| 171 | + crisv32_unmask_irq(IPI_INTR_VECT); | |
| 172 | + crisv32_unmask_irq(TIMER0_INTR_VECT); | |
| 173 | 173 | preempt_disable(); |
| 174 | 174 | notify_cpu_starting(cpu); |
| 175 | 175 | local_irq_enable(); |
| @@ -93,15 +93,16 @@ void set_break_vector(int n, irqvectptr addr); · 92 unmodified lines | ||
| 93 | 93 | "push $r10\n\t" /* push orig_r10 */ \ |
| 94 | 94 | "clear.d [$sp=$sp-4]\n\t" /* frametype - this is a normal stackframe */ |
| 95 | 95 | |
| 96 | − /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq */ | |
| 96 | +/* BLOCK_IRQ and UNBLOCK_IRQ do the same as | |
| 97 | + * crisv10_mask_irq and crisv10_unmask_irq */ | |
| 97 | 98 | |
| 98 | 99 | #define BLOCK_IRQ(mask,nr) \ |
| 99 | 100 | "move.d " #mask ",$r0\n\t" \ |
| 100 | − "move.d $r0,[0xb00000d8]\n\t" | |
| 101 | − | |
| 101 | + "move.d $r0,[0xb00000d8]\n\t" | |
| 102 | + | |
| 102 | 103 | #define UNBLOCK_IRQ(mask) \ |
| 103 | 104 | "move.d " #mask ",$r0\n\t" \ |
| 104 | − "move.d $r0,[0xb00000dc]\n\t" | |
| 105 | + "move.d $r0,[0xb00000dc]\n\t" | |
| 105 | 106 | |
| 106 | 107 | #define IRQ_NAME2(nr) nr##_interrupt(void) |
| 107 | 108 | #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) |
| @@ -23,8 +23,8 @@ struct etrax_interrupt_vector { · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | extern struct etrax_interrupt_vector *etrax_irv; /* head.S */ |
| 25 | 25 | |
| 26 | −void mask_irq(int irq); | |
| 27 | −void unmask_irq(int irq); | |
| 26 | +void crisv32_mask_irq(int irq); | |
| 27 | +void crisv32_unmask_irq(int irq); | |
| 28 | 28 | |
| 29 | 29 | void set_exception_vector(int n, irqvectptr addr); |
| 30 | 30 | |
| @@ -2,22 +2,9 @@ · 1 unmodified line | ||
| 2 | 2 | #define _ASMCRIS_PARAM_H |
| 3 | 3 | |
| 4 | 4 | /* Currently we assume that HZ=100 is good for CRIS. */ |
| 5 | −#ifdef __KERNEL__ | |
| 6 | −# define HZ CONFIG_HZ /* Internal kernel timer frequency */ | |
| 7 | −# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ | |
| 8 | −# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ | |
| 9 | −#endif | |
| 10 | − | |
| 11 | −#ifndef HZ | |
| 12 | −#define HZ 100 | |
| 13 | −#endif | |
| 14 | 5 | |
| 15 | 6 | #define EXEC_PAGESIZE 8192 |
| 16 | 7 | |
| 17 | −#ifndef NOGROUP | |
| 18 | −#define NOGROUP (-1) | |
| 19 | −#endif | |
| 20 | − | |
| 21 | −#define MAXHOSTNAMELEN 64 /* max length of hostname */ | |
| 8 | +#include <asm-generic/param.h> | |
| 22 | 9 | |
| 23 | −#endif | |
| 10 | +#endif /* _ASMCRIS_PARAM_H */ | |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | # |
| 22 | 22 | # the break handler has its own stack |
| 23 | 23 | # |
| 24 | − .section .bss.stack | |
| 24 | + .section .bss..stack | |
| 25 | 25 | .globl __break_user_context |
| 26 | 26 | .balign THREAD_SIZE |
| 27 | 27 | __break_stack: |
| @@ -63,7 +63,7 @@ __break_trace_through_exceptions: · 35 unmodified lines | ||
| 63 | 63 | # entry point for Break Exceptions/Interrupts |
| 64 | 64 | # |
| 65 | 65 | ############################################################################### |
| 66 | − .section .text.break | |
| 66 | + .section .text..break | |
| 67 | 67 | .balign 4 |
| 68 | 68 | .globl __entry_break |
| 69 | 69 | __entry_break: |
| @@ -38,7 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | #define nr_syscalls ((syscall_table_size)/4) |
| 40 | 40 | |
| 41 | − .section .text.entry | |
| 41 | + .section .text..entry | |
| 42 | 42 | .balign 4 |
| 43 | 43 | |
| 44 | 44 | .macro LEDS val |
| @@ -1789,6 +1789,12 @@ void gdbstub(int sigval) · 1788 unmodified lines | ||
| 1789 | 1789 | flush_cache = 1; |
| 1790 | 1790 | break; |
| 1791 | 1791 | |
| 1792 | + /* pNN: Read value of reg N and return it */ | |
| 1793 | + case 'p': | |
| 1794 | + /* return no value, indicating that we don't support | |
| 1795 | + * this command and that gdb should use 'g' instead */ | |
| 1796 | + break; | |
| 1797 | + | |
| 1792 | 1798 | /* PNN,=RRRRRRRR: Write value R to reg N return OK */ |
| 1793 | 1799 | case 'P': |
| 1794 | 1800 | ptr = &input_buffer[1]; |
| @@ -542,7 +542,7 @@ __head_end: · 541 unmodified lines | ||
| 542 | 542 | .size _boot, .-_boot |
| 543 | 543 | |
| 544 | 544 | # provide a point for GDB to place a break |
| 545 | − .section .text.start,"ax" | |
| 545 | + .section .text..start,"ax" | |
| 546 | 546 | .globl _start |
| 547 | 547 | .balign 4 |
| 548 | 548 | _start: |
| @@ -57,10 +57,10 @@ SECTIONS · 56 unmodified lines | ||
| 57 | 57 | _text = .; |
| 58 | 58 | _stext = .; |
| 59 | 59 | .text : { |
| 60 | − *(.text.start) | |
| 61 | − *(.text.entry) | |
| 62 | − *(.text.break) | |
| 63 | − *(.text.tlbmiss) | |
| 60 | + *(.text..start) | |
| 61 | + *(.text..entry) | |
| 62 | + *(.text..break) | |
| 63 | + *(.text..tlbmiss) | |
| 64 | 64 | TEXT_TEXT |
| 65 | 65 | SCHED_TEXT |
| 66 | 66 | LOCK_TEXT |
| @@ -114,7 +114,7 @@ SECTIONS · 47 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | .sbss : { *(.sbss .sbss.*) } |
| 116 | 116 | .bss : { *(.bss .bss.*) } |
| 117 | − .bss.stack : { *(.bss) } | |
| 117 | + .bss..stack : { *(.bss) } | |
| 118 | 118 | |
| 119 | 119 | __bss_stop = .; |
| 120 | 120 | _end = . ; |
| @@ -257,10 +257,10 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear · 256 unmodified lines | ||
| 257 | 257 | */ |
| 258 | 258 | out_of_memory: |
| 259 | 259 | up_read(&mm->mmap_sem); |
| 260 | − printk("VM: killing process %s\n", current->comm); | |
| 261 | − if (user_mode(__frame)) | |
| 262 | − do_group_exit(SIGKILL); | |
| 263 | − goto no_context; | |
| 260 | + if (!user_mode(__frame)) | |
| 261 | + goto no_context; | |
| 262 | + pagefault_out_of_memory(); | |
| 263 | + return; | |
| 264 | 264 | |
| 265 | 265 | do_sigbus: |
| 266 | 266 | up_read(&mm->mmap_sem); |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <asm/pgtable.h> |
| 16 | 16 | #include <asm/spr-regs.h> |
| 17 | 17 | |
| 18 | − .section .text.tlbmiss | |
| 18 | + .section .text..tlbmiss | |
| 19 | 19 | .balign 4 |
| 20 | 20 | |
| 21 | 21 | .globl __entry_insn_mmu_miss |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #define SRAM_START 0xff4000 |
| 11 | 11 | |
| 12 | − .section .text.startup | |
| 12 | + .section .text..startup | |
| 13 | 13 | .global startup |
| 14 | 14 | startup: |
| 15 | 15 | mov.l #SRAM_START+0x8000, sp |
| @@ -4,7 +4,7 @@ SECTIONS · 3 unmodified lines | ||
| 4 | 4 | { |
| 5 | 5 | __stext = . ; |
| 6 | 6 | __text = .; |
| 7 | − *(.text.startup) | |
| 7 | + *(.text..startup) | |
| 8 | 8 | *(.text) |
| 9 | 9 | __etext = . ; |
| 10 | 10 | } |
| @@ -70,12 +70,12 @@ name: · 69 unmodified lines | ||
| 70 | 70 | * path (ivt.S - TLB miss processing) or in places where it might not be |
| 71 | 71 | * safe to use a "tpa" instruction (mca_asm.S - error recovery). |
| 72 | 72 | */ |
| 73 | − .section ".data.patch.vtop", "a" // declare section & section attributes | |
| 73 | + .section ".data..patch.vtop", "a" // declare section & section attributes | |
| 74 | 74 | .previous |
| 75 | 75 | |
| 76 | 76 | #define LOAD_PHYSICAL(pr, reg, obj) \ |
| 77 | 77 | [1:](pr)movl reg = obj; \ |
| 78 | − .xdata4 ".data.patch.vtop", 1b-. | |
| 78 | + .xdata4 ".data..patch.vtop", 1b-. | |
| 79 | 79 | |
| 80 | 80 | /* |
| 81 | 81 | * For now, we always put in the McKinley E9 workaround. On CPUs that don't need it, |
| @@ -84,11 +84,11 @@ name: · 2 unmodified lines | ||
| 84 | 84 | #define DO_MCKINLEY_E9_WORKAROUND |
| 85 | 85 | |
| 86 | 86 | #ifdef DO_MCKINLEY_E9_WORKAROUND |
| 87 | − .section ".data.patch.mckinley_e9", "a" | |
| 87 | + .section ".data..patch.mckinley_e9", "a" | |
| 88 | 88 | .previous |
| 89 | 89 | /* workaround for Itanium 2 Errata 9: */ |
| 90 | 90 | # define FSYS_RETURN \ |
| 91 | − .xdata4 ".data.patch.mckinley_e9", 1f-.; \ | |
| 91 | + .xdata4 ".data..patch.mckinley_e9", 1f-.; \ | |
| 92 | 92 | 1:{ .mib; \ |
| 93 | 93 | nop.m 0; \ |
| 94 | 94 | mov r16=ar.pfs; \ |
| @@ -107,11 +107,11 @@ name: · 12 unmodified lines | ||
| 107 | 107 | * If physical stack register size is different from DEF_NUM_STACK_REG, |
| 108 | 108 | * dynamically patch the kernel for correct size. |
| 109 | 109 | */ |
| 110 | − .section ".data.patch.phys_stack_reg", "a" | |
| 110 | + .section ".data..patch.phys_stack_reg", "a" | |
| 111 | 111 | .previous |
| 112 | 112 | #define LOAD_PHYS_STACK_REG_SIZE(reg) \ |
| 113 | 113 | [1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \ |
| 114 | − .xdata4 ".data.patch.phys_stack_reg", 1b-. | |
| 114 | + .xdata4 ".data..patch.phys_stack_reg", 1b-. | |
| 115 | 115 | |
| 116 | 116 | /* |
| 117 | 117 | * Up until early 2004, use of .align within a function caused bad unwind info. |
| @@ -24,6 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | # define SMP_CACHE_BYTES (1 << 3) |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 27 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 28 | 28 | |
| 29 | 29 | #endif /* _ASM_IA64_CACHE_H */ |
| @@ -31,7 +31,7 @@ extern void *per_cpu_init(void); · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | #endif /* SMP */ |
| 33 | 33 | |
| 34 | −#define PER_CPU_BASE_SECTION ".data.percpu" | |
| 34 | +#define PER_CPU_BASE_SECTION ".data..percpu" | |
| 35 | 35 | |
| 36 | 36 | /* |
| 37 | 37 | * Be extremely careful when taking the address of this variable! Due to virtual |
| @@ -21,7 +21,7 @@ GATECFLAGS_gate-syms.o = -r · 20 unmodified lines | ||
| 21 | 21 | $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE |
| 22 | 22 | $(call if_changed,gate) |
| 23 | 23 | |
| 24 | −# gate-data.o contains the gate DSO image as data in section .data.gate. | |
| 24 | +# gate-data.o contains the gate DSO image as data in section .data..gate. | |
| 25 | 25 | # We must build gate.so before we can assemble it. |
| 26 | 26 | # Note: kbuild does not track this dependency due to usage of .incbin |
| 27 | 27 | $(obj)/gate-data.o: $(obj)/gate.so |
| @@ -1,3 +1,3 @@ | ||
| 1 | − .section .data.gate, "aw" | |
| 1 | + .section .data..gate, "aw" | |
| 2 | 2 | |
| 3 | 3 | .incbin "arch/ia64/kernel/gate.so" |
| @@ -21,18 +21,18 @@ · 20 unmodified lines | ||
| 21 | 21 | * to targets outside the shared object) and to avoid multi-phase kernel builds, we |
| 22 | 22 | * simply create minimalistic "patch lists" in special ELF sections. |
| 23 | 23 | */ |
| 24 | − .section ".data.patch.fsyscall_table", "a" | |
| 24 | + .section ".data..patch.fsyscall_table", "a" | |
| 25 | 25 | .previous |
| 26 | 26 | #define LOAD_FSYSCALL_TABLE(reg) \ |
| 27 | 27 | [1:] movl reg=0; \ |
| 28 | − .xdata4 ".data.patch.fsyscall_table", 1b-. | |
| 28 | + .xdata4 ".data..patch.fsyscall_table", 1b-. | |
| 29 | 29 | |
| 30 | − .section ".data.patch.brl_fsys_bubble_down", "a" | |
| 30 | + .section ".data..patch.brl_fsys_bubble_down", "a" | |
| 31 | 31 | .previous |
| 32 | 32 | #define BRL_COND_FSYS_BUBBLE_DOWN(pr) \ |
| 33 | 33 | [1:](pr)brl.cond.sptk 0; \ |
| 34 | 34 | ;; \ |
| 35 | − .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-. | |
| 35 | + .xdata4 ".data..patch.brl_fsys_bubble_down", 1b-. | |
| 36 | 36 | |
| 37 | 37 | GLOBAL_ENTRY(__kernel_syscall_via_break) |
| 38 | 38 | .prologue |
| @@ -33,21 +33,21 @@ SECTIONS · 32 unmodified lines | ||
| 33 | 33 | */ |
| 34 | 34 | . = GATE_ADDR + 0x600; |
| 35 | 35 | |
| 36 | − .data.patch : { | |
| 36 | + .data..patch : { | |
| 37 | 37 | __paravirt_start_gate_mckinley_e9_patchlist = .; |
| 38 | − *(.data.patch.mckinley_e9) | |
| 38 | + *(.data..patch.mckinley_e9) | |
| 39 | 39 | __paravirt_end_gate_mckinley_e9_patchlist = .; |
| 40 | 40 | |
| 41 | 41 | __paravirt_start_gate_vtop_patchlist = .; |
| 42 | − *(.data.patch.vtop) | |
| 42 | + *(.data..patch.vtop) | |
| 43 | 43 | __paravirt_end_gate_vtop_patchlist = .; |
| 44 | 44 | |
| 45 | 45 | __paravirt_start_gate_fsyscall_patchlist = .; |
| 46 | − *(.data.patch.fsyscall_table) | |
| 46 | + *(.data..patch.fsyscall_table) | |
| 47 | 47 | __paravirt_end_gate_fsyscall_patchlist = .; |
| 48 | 48 | |
| 49 | 49 | __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .; |
| 50 | − *(.data.patch.brl_fsys_bubble_down) | |
| 50 | + *(.data..patch.brl_fsys_bubble_down) | |
| 51 | 51 | __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .; |
| 52 | 52 | } :readable |
| 53 | 53 | |
| @@ -23,7 +23,7 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); · 22 unmodified lines | ||
| 23 | 23 | * Initial task structure. |
| 24 | 24 | * |
| 25 | 25 | * We need to make sure that this is properly aligned due to the way process stacks are |
| 26 | − * handled. This is done by having a special ".data.init_task" section... | |
| 26 | + * handled. This is done by having a special ".data..init_task" section... | |
| 27 | 27 | */ |
| 28 | 28 | #define init_thread_info init_task_mem.s.thread_info |
| 29 | 29 | |
| @@ -82,7 +82,7 @@ · 81 unmodified lines | ||
| 82 | 82 | mov r19=n;; /* prepare to save predicates */ \ |
| 83 | 83 | br.sptk.many dispatch_to_fault_handler |
| 84 | 84 | |
| 85 | − .section .text.ivt,"ax" | |
| 85 | + .section .text..ivt,"ax" | |
| 86 | 86 | |
| 87 | 87 | .align 32768 // align on 32KB boundary |
| 88 | 88 | .global ia64_ivt |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #define ACCOUNT_SYS_ENTER |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | −.section ".data.patch.rse", "a" | |
| 19 | +.section ".data..patch.rse", "a" | |
| 20 | 20 | .previous |
| 21 | 21 | |
| 22 | 22 | /* |
| @@ -215,7 +215,7 @@ · 192 unmodified lines | ||
| 215 | 215 | (pUStk) extr.u r17=r18,3,6; \ |
| 216 | 216 | (pUStk) sub r16=r18,r22; \ |
| 217 | 217 | [1:](pKStk) br.cond.sptk.many 1f; \ |
| 218 | − .xdata4 ".data.patch.rse",1b-. \ | |
| 218 | + .xdata4 ".data..patch.rse",1b-. \ | |
| 219 | 219 | ;; \ |
| 220 | 220 | cmp.ge p6,p7 = 33,r17; \ |
| 221 | 221 | ;; \ |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "entry.h" |
| 29 | 29 | |
| 30 | 30 | #define DATA8(sym, init_value) \ |
| 31 | − .pushsection .data.read_mostly ; \ | |
| 31 | + .pushsection .data..read_mostly ; \ | |
| 32 | 32 | .align 8 ; \ |
| 33 | 33 | .global sym ; \ |
| 34 | 34 | sym: ; \ |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #define IVT_TEXT \ |
| 10 | 10 | VMLINUX_SYMBOL(__start_ivt_text) = .; \ |
| 11 | − *(.text.ivt) \ | |
| 11 | + *(.text..ivt) \ | |
| 12 | 12 | VMLINUX_SYMBOL(__end_ivt_text) = .; |
| 13 | 13 | |
| 14 | 14 | OUTPUT_FORMAT("elf64-ia64-little") |
| @@ -54,8 +54,8 @@ SECTIONS · 39 unmodified lines | ||
| 54 | 54 | .text2 : AT(ADDR(.text2) - LOAD_OFFSET) |
| 55 | 55 | { *(.text2) } |
| 56 | 56 | #ifdef CONFIG_SMP |
| 57 | − .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) | |
| 58 | − { *(.text.lock) } | |
| 57 | + .text..lock : AT(ADDR(.text..lock) - LOAD_OFFSET) | |
| 58 | + { *(.text..lock) } | |
| 59 | 59 | #endif |
| 60 | 60 | _etext = .; |
| 61 | 61 | |
| @@ -75,10 +75,10 @@ SECTIONS · 13 unmodified lines | ||
| 75 | 75 | __stop___mca_table = .; |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | − .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET) | |
| 78 | + .data..patch.phys_stack_reg : AT(ADDR(.data..patch.phys_stack_reg) - LOAD_OFFSET) | |
| 79 | 79 | { |
| 80 | 80 | __start___phys_stack_reg_patchlist = .; |
| 81 | − *(.data.patch.phys_stack_reg) | |
| 81 | + *(.data..patch.phys_stack_reg) | |
| 82 | 82 | __end___phys_stack_reg_patchlist = .; |
| 83 | 83 | } |
| 84 | 84 | |
| @@ -110,24 +110,24 @@ SECTIONS · 25 unmodified lines | ||
| 110 | 110 | INIT_TEXT_SECTION(PAGE_SIZE) |
| 111 | 111 | INIT_DATA_SECTION(16) |
| 112 | 112 | |
| 113 | − .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) | |
| 113 | + .data..patch.vtop : AT(ADDR(.data..patch.vtop) - LOAD_OFFSET) | |
| 114 | 114 | { |
| 115 | 115 | __start___vtop_patchlist = .; |
| 116 | − *(.data.patch.vtop) | |
| 116 | + *(.data..patch.vtop) | |
| 117 | 117 | __end___vtop_patchlist = .; |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | − .data.patch.rse : AT(ADDR(.data.patch.rse) - LOAD_OFFSET) | |
| 120 | + .data..patch.rse : AT(ADDR(.data..patch.rse) - LOAD_OFFSET) | |
| 121 | 121 | { |
| 122 | 122 | __start___rse_patchlist = .; |
| 123 | − *(.data.patch.rse) | |
| 123 | + *(.data..patch.rse) | |
| 124 | 124 | __end___rse_patchlist = .; |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | − .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET) | |
| 127 | + .data..patch.mckinley_e9 : AT(ADDR(.data..patch.mckinley_e9) - LOAD_OFFSET) | |
| 128 | 128 | { |
| 129 | 129 | __start___mckinley_e9_bundles = .; |
| 130 | − *(.data.patch.mckinley_e9) | |
| 130 | + *(.data..patch.mckinley_e9) | |
| 131 | 131 | __end___mckinley_e9_bundles = .; |
| 132 | 132 | } |
| 133 | 133 | |
| @@ -175,17 +175,17 @@ SECTIONS · 41 unmodified lines | ||
| 175 | 175 | . = ALIGN(PAGE_SIZE); |
| 176 | 176 | __init_end = .; |
| 177 | 177 | |
| 178 | − .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) | |
| 178 | + .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) | |
| 179 | 179 | { |
| 180 | 180 | PAGE_ALIGNED_DATA(PAGE_SIZE) |
| 181 | 181 | . = ALIGN(PAGE_SIZE); |
| 182 | 182 | __start_gate_section = .; |
| 183 | − *(.data.gate) | |
| 183 | + *(.data..gate) | |
| 184 | 184 | __stop_gate_section = .; |
| 185 | 185 | #ifdef CONFIG_XEN |
| 186 | 186 | . = ALIGN(PAGE_SIZE); |
| 187 | 187 | __xen_start_gate_section = .; |
| 188 | − *(.data.gate.xen) | |
| 188 | + *(.data..gate.xen) | |
| 189 | 189 | __xen_stop_gate_section = .; |
| 190 | 190 | #endif |
| 191 | 191 | } |
| @@ -144,6 +144,7 @@ int kvm_arch_hardware_enable(void *garbage) · 143 unmodified lines | ||
| 144 | 144 | VP_INIT_ENV : VP_INIT_ENV_INITALIZE, |
| 145 | 145 | __pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base); |
| 146 | 146 | if (status != 0) { |
| 147 | + spin_unlock(&vp_lock); | |
| 147 | 148 | printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n"); |
| 148 | 149 | return -EINVAL; |
| 149 | 150 | } |
| @@ -104,7 +104,7 @@ GLOBAL_ENTRY(kvm_vmm_panic) · 103 unmodified lines | ||
| 104 | 104 | br.call.sptk.many b6=vmm_panic_handler; |
| 105 | 105 | END(kvm_vmm_panic) |
| 106 | 106 | |
| 107 | − .section .text.ivt,"ax" | |
| 107 | + .section .text..ivt,"ax" | |
| 108 | 108 | |
| 109 | 109 | .align 32768 // align on 32KB boundary |
| 110 | 110 | .global kvm_ia64_ivt |
| @@ -1,4 +1,4 @@ | ||
| 1 | −#!/usr/bin/env python | |
| 1 | +#!/usr/bin/python | |
| 2 | 2 | # |
| 3 | 3 | # Usage: unwcheck.py FILE |
| 4 | 4 | # |
| @@ -1,3 +1,3 @@ | ||
| 1 | − .section .data.gate.xen, "aw" | |
| 1 | + .section .data..gate.xen, "aw" | |
| 2 | 2 | |
| 3 | 3 | .incbin "arch/ia64/xen/gate.so" |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/init.h> |
| 15 | 15 | #include <xen/interface/elfnote.h> |
| 16 | 16 | |
| 17 | − .section .data.read_mostly | |
| 17 | + .section .data..read_mostly | |
| 18 | 18 | .align 8 |
| 19 | 19 | .global xen_domain_type |
| 20 | 20 | xen_domain_type: |
| @@ -188,7 +188,6 @@ good_area: · 187 unmodified lines | ||
| 188 | 188 | if ((error_code & ACE_INSTRUCTION) && !(vma->vm_flags & VM_EXEC)) |
| 189 | 189 | goto bad_area; |
| 190 | 190 | |
| 191 | −survive: | |
| 192 | 191 | /* |
| 193 | 192 | * If for any reason at all we couldn't handle the fault, |
| 194 | 193 | * make sure we exit gracefully rather than endlessly redo |
| @@ -271,15 +270,10 @@ no_context: · 76 unmodified lines | ||
| 271 | 270 | */ |
| 272 | 271 | out_of_memory: |
| 273 | 272 | up_read(&mm->mmap_sem); |
| 274 | − if (is_global_init(tsk)) { | |
| 275 | − yield(); | |
| 276 | − down_read(&mm->mmap_sem); | |
| 277 | − goto survive; | |
| 278 | − } | |
| 279 | − printk("VM: killing process %s\n", tsk->comm); | |
| 280 | − if (error_code & ACE_USERMODE) | |
| 281 | − do_group_exit(SIGKILL); | |
| 282 | − goto no_context; | |
| 273 | + if (!(error_code & ACE_USERMODE)) | |
| 274 | + goto no_context; | |
| 275 | + pagefault_out_of_memory(); | |
| 276 | + return; | |
| 283 | 277 | |
| 284 | 278 | do_sigbus: |
| 285 | 279 | up_read(&mm->mmap_sem); |
| @@ -57,7 +57,7 @@ SECTIONS { · 56 unmodified lines | ||
| 57 | 57 | .romvec : { |
| 58 | 58 | __rom_start = . ; |
| 59 | 59 | _romvec = .; |
| 60 | − *(.data.initvect) | |
| 60 | + *(.data..initvect) | |
| 61 | 61 | } > romvec |
| 62 | 62 | #endif |
| 63 | 63 | |
| @@ -68,7 +68,7 @@ SECTIONS { · 4 unmodified lines | ||
| 68 | 68 | TEXT_TEXT |
| 69 | 69 | SCHED_TEXT |
| 70 | 70 | LOCK_TEXT |
| 71 | − *(.text.lock) | |
| 71 | + *(.text..lock) | |
| 72 | 72 | |
| 73 | 73 | . = ALIGN(16); /* Exception table */ |
| 74 | 74 | __start___ex_table = .; |
| @@ -280,7 +280,7 @@ _dprbase: · 279 unmodified lines | ||
| 280 | 280 | * and then overwritten as needed. |
| 281 | 281 | */ |
| 282 | 282 | |
| 283 | −.section ".data.initvect","awx" | |
| 283 | +.section ".data..initvect","awx" | |
| 284 | 284 | .long RAMEND /* Reset: Initial Stack Pointer - 0. */ |
| 285 | 285 | .long _start /* Reset: Initial Program Counter - 1. */ |
| 286 | 286 | .long buserr /* Bus Error - 2. */ |
| @@ -291,7 +291,7 @@ _dprbase: · 290 unmodified lines | ||
| 291 | 291 | * and then overwritten as needed. |
| 292 | 292 | */ |
| 293 | 293 | |
| 294 | −.section ".data.initvect","awx" | |
| 294 | +.section ".data..initvect","awx" | |
| 295 | 295 | .long RAMEND /* Reset: Initial Stack Pointer - 0. */ |
| 296 | 296 | .long _start /* Reset: Initial Program Counter - 1. */ |
| 297 | 297 | .long buserr /* Bus Error - 2. */ |
| @@ -34,6 +34,8 @@ · 33 unmodified lines | ||
| 34 | 34 | /* MS be sure that SLAB allocates aligned objects */ |
| 35 | 35 | #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES |
| 36 | 36 | |
| 37 | +#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES | |
| 38 | + | |
| 37 | 39 | #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) |
| 38 | 40 | #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) |
| 39 | 41 | |
| @@ -90,7 +90,6 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, · 89 unmodified lines | ||
| 90 | 90 | /* FIXME this part of code is untested */ |
| 91 | 91 | for_each_sg(sgl, sg, nents, i) { |
| 92 | 92 | sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); |
| 93 | − sg->dma_length = sg->length; | |
| 94 | 93 | __dma_sync_page(page_to_phys(sg_page(sg)), sg->offset, |
| 95 | 94 | sg->length, direction); |
| 96 | 95 | } |
| @@ -1277,6 +1277,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) · 1276 unmodified lines | ||
| 1277 | 1277 | printk(KERN_WARNING "PCI: Cannot allocate resource region " |
| 1278 | 1278 | "%d of PCI bridge %d, will remap\n", i, bus->number); |
| 1279 | 1279 | clear_resource: |
| 1280 | + res->start = res->end = 0; | |
| 1280 | 1281 | res->flags = 0; |
| 1281 | 1282 | } |
| 1282 | 1283 | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | #include <asm/lasat/head.h> |
| 2 | 2 | |
| 3 | 3 | .text |
| 4 | − .section .text.start, "ax" | |
| 4 | + .section .text..start, "ax" | |
| 5 | 5 | .set noreorder |
| 6 | 6 | .set mips3 |
| 7 | 7 | |
| @@ -4,7 +4,7 @@ SECTIONS · 3 unmodified lines | ||
| 4 | 4 | { |
| 5 | 5 | .text : |
| 6 | 6 | { |
| 7 | − *(.text.start) | |
| 7 | + *(.text..start) | |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | /* Data in ROM */ |
| @@ -338,11 +338,10 @@ no_context: · 337 unmodified lines | ||
| 338 | 338 | */ |
| 339 | 339 | out_of_memory: |
| 340 | 340 | up_read(&mm->mmap_sem); |
| 341 | − monitor_signal(regs); | |
| 342 | − printk(KERN_ALERT "VM: killing process %s\n", tsk->comm); | |
| 343 | − if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) | |
| 344 | − do_exit(SIGKILL); | |
| 345 | − goto no_context; | |
| 341 | + if ((fault_code & MMUFCR_xFC_ACCESS) != MMUFCR_xFC_ACCESS_USR) | |
| 342 | + goto no_context; | |
| 343 | + pagefault_out_of_memory(); | |
| 344 | + return; | |
| 346 | 345 | |
| 347 | 346 | do_sigbus: |
| 348 | 347 | up_read(&mm->mmap_sem); |
| @@ -117,6 +117,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) · 116 unmodified lines | ||
| 117 | 117 | * Invalidate the resource to prevent |
| 118 | 118 | * child resource allocations in this |
| 119 | 119 | * range. */ |
| 120 | + r->start = r->end = 0; | |
| 120 | 121 | r->flags = 0; |
| 121 | 122 | } |
| 122 | 123 | } |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #define SMP_CACHE_BYTES L1_CACHE_BYTES |
| 30 | 30 | |
| 31 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 31 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 32 | 32 | |
| 33 | 33 | void parisc_cache_init(void); /* initializes cache-flushing */ |
| 34 | 34 | void disable_sr_hashing_asm(int); /* low level support for above */ |
| @@ -174,7 +174,7 @@ static inline void set_eiem(unsigned long val) · 173 unmodified lines | ||
| 174 | 174 | }) |
| 175 | 175 | |
| 176 | 176 | #ifdef CONFIG_SMP |
| 177 | −# define __lock_aligned __attribute__((__section__(".data.lock_aligned"))) | |
| 177 | +# define __lock_aligned __attribute__((__section__(".data..lock_aligned"))) | |
| 178 | 178 | #endif |
| 179 | 179 | |
| 180 | 180 | #define arch_align_stack(x) (x) |
| @@ -345,7 +345,7 @@ smp_slave_stext: · 344 unmodified lines | ||
| 345 | 345 | ENDPROC(stext) |
| 346 | 346 | |
| 347 | 347 | #ifndef CONFIG_64BIT |
| 348 | − .section .data.read_mostly | |
| 348 | + .section .data..read_mostly | |
| 349 | 349 | |
| 350 | 350 | .align 4 |
| 351 | 351 | .export $global$,data |
| @@ -53,11 +53,11 @@ union thread_union init_thread_union __init_task_data · 52 unmodified lines | ||
| 53 | 53 | * guarantee that global objects will be laid out in memory in the same order |
| 54 | 54 | * as the order of declaration, so put these in different sections and use |
| 55 | 55 | * the linker script to order them. */ |
| 56 | −pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data.vm0.pmd"), aligned(PAGE_SIZE))); | |
| 56 | +pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned(PAGE_SIZE))); | |
| 57 | 57 | #endif |
| 58 | 58 | |
| 59 | −pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data.vm0.pgd"), aligned(PAGE_SIZE))); | |
| 60 | −pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data.vm0.pte"), aligned(PAGE_SIZE))); | |
| 59 | +pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE))); | |
| 60 | +pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE))); | |
| 61 | 61 | |
| 62 | 62 | /* |
| 63 | 63 | * Initial task structure. |
| @@ -94,8 +94,8 @@ SECTIONS · 93 unmodified lines | ||
| 94 | 94 | |
| 95 | 95 | /* PA-RISC locks requires 16-byte alignment */ |
| 96 | 96 | . = ALIGN(16); |
| 97 | − .data.lock_aligned : { | |
| 98 | − *(.data.lock_aligned) | |
| 97 | + .data..lock_aligned : { | |
| 98 | + *(.data..lock_aligned) | |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 101 | /* End of data section */ |
| @@ -105,10 +105,10 @@ SECTIONS · 3 unmodified lines | ||
| 105 | 105 | __bss_start = .; |
| 106 | 106 | /* page table entries need to be PAGE_SIZE aligned */ |
| 107 | 107 | . = ALIGN(PAGE_SIZE); |
| 108 | − .data.vmpages : { | |
| 109 | − *(.data.vm0.pmd) | |
| 110 | − *(.data.vm0.pgd) | |
| 111 | − *(.data.vm0.pte) | |
| 108 | + .data..vmpages : { | |
| 109 | + *(.data..vm0.pmd) | |
| 110 | + *(.data..vm0.pgd) | |
| 111 | + *(.data..vm0.pte) | |
| 112 | 112 | } |
| 113 | 113 | .bss : { |
| 114 | 114 | *(.bss) |
| @@ -351,7 +351,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE · 350 unmodified lines | ||
| 351 | 351 | |
| 352 | 352 | config KEXEC |
| 353 | 353 | bool "kexec system call (EXPERIMENTAL)" |
| 354 | − depends on PPC_BOOK3S && EXPERIMENTAL | |
| 354 | + depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL | |
| 355 | 355 | help |
| 356 | 356 | kexec is a system call that implements the ability to shutdown your |
| 357 | 357 | current kernel, and to start another kernel. It is like a reboot |
| @@ -112,6 +112,11 @@ KBUILD_CFLAGS += $(call cc-option,-mspe=no) · 111 unmodified lines | ||
| 112 | 112 | # kernel considerably. |
| 113 | 113 | KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) |
| 114 | 114 | |
| 115 | +# FIXME: the module load should be taught about the additional relocs | |
| 116 | +# generated by this. | |
| 117 | +# revert to pre-gcc-4.4 behaviour of .eh_frame | |
| 118 | +KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) | |
| 119 | + | |
| 115 | 120 | # Never use string load/store instructions as they are |
| 116 | 121 | # often slow when they are implemented at all |
| 117 | 122 | KBUILD_CFLAGS += -mno-string |
| @@ -519,7 +519,7 @@ void ibm440ep_fixup_clocks(unsigned int sys_clk, · 518 unmodified lines | ||
| 519 | 519 | { |
| 520 | 520 | unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0); |
| 521 | 521 | |
| 522 | − /* serial clocks beed fixup based on int/ext */ | |
| 522 | + /* serial clocks need fixup based on int/ext */ | |
| 523 | 523 | eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk); |
| 524 | 524 | eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk); |
| 525 | 525 | eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk); |
| @@ -532,7 +532,7 @@ void ibm440gx_fixup_clocks(unsigned int sys_clk, · 6 unmodified lines | ||
| 532 | 532 | { |
| 533 | 533 | unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); |
| 534 | 534 | |
| 535 | − /* serial clocks beed fixup based on int/ext */ | |
| 535 | + /* serial clocks need fixup based on int/ext */ | |
| 536 | 536 | eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk); |
| 537 | 537 | eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk); |
| 538 | 538 | } |
| @@ -543,10 +543,10 @@ void ibm440spe_fixup_clocks(unsigned int sys_clk, · 4 unmodified lines | ||
| 543 | 543 | { |
| 544 | 544 | unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); |
| 545 | 545 | |
| 546 | − /* serial clocks beed fixup based on int/ext */ | |
| 547 | − eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk); | |
| 548 | − eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk); | |
| 549 | − eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk); | |
| 546 | + /* serial clocks need fixup based on int/ext */ | |
| 547 | + eplike_fixup_uart_clk(0, "/plb/opb/serial@f0000200", ser_clk, plb_clk); | |
| 548 | + eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk, plb_clk); | |
| 549 | + eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk, plb_clk); | |
| 550 | 550 | } |
| 551 | 551 | |
| 552 | 552 | void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) |
| @@ -0,0 +1,447 @@ | ||
| 1 | +/* | |
| 2 | + * Device Tree Source for Mosaix Technologies, Inc. ICON board | |
| 3 | + * | |
| 4 | + * Copyright 2010 DENX Software Engineering, Stefan Roese <sr@denx.de> | |
| 5 | + * | |
| 6 | + * This file is licensed under the terms of the GNU General Public | |
| 7 | + * License version 2. This program is licensed "as is" without | |
| 8 | + * any warranty of any kind, whether express or implied. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +/dts-v1/; | |
| 12 | + | |
| 13 | +/ { | |
| 14 | + #address-cells = <2>; | |
| 15 | + #size-cells = <2>; | |
| 16 | + model = "mosaixtech,icon"; | |
| 17 | + compatible = "mosaixtech,icon"; | |
| 18 | + dcr-parent = <&{/cpus/cpu@0}>; | |
| 19 | + | |
| 20 | + aliases { | |
| 21 | + ethernet0 = &EMAC0; | |
| 22 | + serial0 = &UART0; | |
| 23 | + serial1 = &UART1; | |
| 24 | + serial2 = &UART2; | |
| 25 | + }; | |
| 26 | + | |
| 27 | + cpus { | |
| 28 | + #address-cells = <1>; | |
| 29 | + #size-cells = <0>; | |
| 30 | + | |
| 31 | + cpu@0 { | |
| 32 | + device_type = "cpu"; | |
| 33 | + model = "PowerPC,440SPe"; | |
| 34 | + reg = <0x00000000>; | |
| 35 | + clock-frequency = <0>; /* Filled in by U-Boot */ | |
| 36 | + timebase-frequency = <0>; /* Filled in by U-Boot */ | |
| 37 | + i-cache-line-size = <32>; | |
| 38 | + d-cache-line-size = <32>; | |
| 39 | + i-cache-size = <32768>; | |
| 40 | + d-cache-size = <32768>; | |
| 41 | + dcr-controller; | |
| 42 | + dcr-access-method = "native"; | |
| 43 | + reset-type = <2>; /* Use chip-reset */ | |
| 44 | + }; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + memory { | |
| 48 | + device_type = "memory"; | |
| 49 | + reg = <0x0 0x00000000 0x0 0x00000000>; /* Filled in by U-Boot */ | |
| 50 | + }; | |
| 51 | + | |
| 52 | + UIC0: interrupt-controller0 { | |
| 53 | + compatible = "ibm,uic-440spe","ibm,uic"; | |
| 54 | + interrupt-controller; | |
| 55 | + cell-index = <0>; | |
| 56 | + dcr-reg = <0x0c0 0x009>; | |
| 57 | + #address-cells = <0>; | |
| 58 | + #size-cells = <0>; | |
| 59 | + #interrupt-cells = <2>; | |
| 60 | + }; | |
| 61 | + | |
| 62 | + UIC1: interrupt-controller1 { | |
| 63 | + compatible = "ibm,uic-440spe","ibm,uic"; | |
| 64 | + interrupt-controller; | |
| 65 | + cell-index = <1>; | |
| 66 | + dcr-reg = <0x0d0 0x009>; | |
| 67 | + #address-cells = <0>; | |
| 68 | + #size-cells = <0>; | |
| 69 | + #interrupt-cells = <2>; | |
| 70 | + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ | |
| 71 | + interrupt-parent = <&UIC0>; | |
| 72 | + }; | |
| 73 | + | |
| 74 | + UIC2: interrupt-controller2 { | |
| 75 | + compatible = "ibm,uic-440spe","ibm,uic"; | |
| 76 | + interrupt-controller; | |
| 77 | + cell-index = <2>; | |
| 78 | + dcr-reg = <0x0e0 0x009>; | |
| 79 | + #address-cells = <0>; | |
| 80 | + #size-cells = <0>; | |
| 81 | + #interrupt-cells = <2>; | |
| 82 | + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ | |
| 83 | + interrupt-parent = <&UIC0>; | |
| 84 | + }; | |
| 85 | + | |
| 86 | + UIC3: interrupt-controller3 { | |
| 87 | + compatible = "ibm,uic-440spe","ibm,uic"; | |
| 88 | + interrupt-controller; | |
| 89 | + cell-index = <3>; | |
| 90 | + dcr-reg = <0x0f0 0x009>; | |
| 91 | + #address-cells = <0>; | |
| 92 | + #size-cells = <0>; | |
| 93 | + #interrupt-cells = <2>; | |
| 94 | + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ | |
| 95 | + interrupt-parent = <&UIC0>; | |
| 96 | + }; | |
| 97 | + | |
| 98 | + SDR0: sdr { | |
| 99 | + compatible = "ibm,sdr-440spe"; | |
| 100 | + dcr-reg = <0x00e 0x002>; | |
| 101 | + }; | |
| 102 | + | |
| 103 | + CPR0: cpr { | |
| 104 | + compatible = "ibm,cpr-440spe"; | |
| 105 | + dcr-reg = <0x00c 0x002>; | |
| 106 | + }; | |
| 107 | + | |
| 108 | + MQ0: mq { | |
| 109 | + compatible = "ibm,mq-440spe"; | |
| 110 | + dcr-reg = <0x040 0x020>; | |
| 111 | + }; | |
| 112 | + | |
| 113 | + plb { | |
| 114 | + compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4"; | |
| 115 | + #address-cells = <2>; | |
| 116 | + #size-cells = <1>; | |
| 117 | + /* addr-child addr-parent size */ | |
| 118 | + ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000 | |
| 119 | + 0x4 0x00200000 0x4 0x00200000 0x00000400 | |
| 120 | + 0x4 0xe0000000 0x4 0xe0000000 0x20000000 | |
| 121 | + 0xc 0x00000000 0xc 0x00000000 0x20000000 | |
| 122 | + 0xd 0x00000000 0xd 0x00000000 0x80000000 | |
| 123 | + 0xd 0x80000000 0xd 0x80000000 0x80000000 | |
| 124 | + 0xe 0x00000000 0xe 0x00000000 0x80000000 | |
| 125 | + 0xe 0x80000000 0xe 0x80000000 0x80000000 | |
| 126 | + 0xf 0x00000000 0xf 0x00000000 0x80000000 | |
| 127 | + 0xf 0x80000000 0xf 0x80000000 0x80000000>; | |
| 128 | + clock-frequency = <0>; /* Filled in by U-Boot */ | |
| 129 | + | |
| 130 | + SDRAM0: sdram { | |
| 131 | + compatible = "ibm,sdram-440spe", "ibm,sdram-405gp"; | |
| 132 | + dcr-reg = <0x010 0x002>; | |
| 133 | + }; | |
| 134 | + | |
| 135 | + MAL0: mcmal { | |
| 136 | + compatible = "ibm,mcmal-440spe", "ibm,mcmal2"; | |
| 137 | + dcr-reg = <0x180 0x062>; | |
| 138 | + num-tx-chans = <2>; | |
| 139 | + num-rx-chans = <1>; | |
| 140 | + interrupt-parent = <&MAL0>; | |
| 141 | + interrupts = <0x0 0x1 0x2 0x3 0x4>; | |
| 142 | + #interrupt-cells = <1>; | |
| 143 | + #address-cells = <0>; | |
| 144 | + #size-cells = <0>; | |
| 145 | + interrupt-map = </*TXEOB*/ 0x0 &UIC1 0x6 0x4 | |
| 146 | + /*RXEOB*/ 0x1 &UIC1 0x7 0x4 | |
| 147 | + /*SERR*/ 0x2 &UIC1 0x1 0x4 | |
| 148 | + /*TXDE*/ 0x3 &UIC1 0x2 0x4 | |
| 149 | + /*RXDE*/ 0x4 &UIC1 0x3 0x4>; | |
| 150 | + }; | |
| 151 | + | |
| 152 | + POB0: opb { | |
| 153 | + compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; | |
| 154 | + #address-cells = <1>; | |
| 155 | + #size-cells = <1>; | |
| 156 | + ranges = <0xe0000000 0x00000004 0xe0000000 0x20000000>; | |
| 157 | + clock-frequency = <0>; /* Filled in by U-Boot */ | |
| 158 | + | |
| 159 | + EBC0: ebc { | |
| 160 | + compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; | |
| 161 | + dcr-reg = <0x012 0x002>; | |
| 162 | + #address-cells = <2>; | |
| 163 | + #size-cells = <1>; | |
| 164 | + clock-frequency = <0>; /* Filled in by U-Boot */ | |
| 165 | + /* ranges property is supplied by U-Boot */ | |
| 166 | + interrupts = <0x5 0x1>; | |
| 167 | + interrupt-parent = <&UIC1>; | |
| 168 | + | |
| 169 | + nor_flash@0,0 { | |
| 170 | + compatible = "cfi-flash"; | |
| 171 | + bank-width = <2>; | |
| 172 | + reg = <0x00000000 0x00000000 0x01000000>; | |
| 173 | + #address-cells = <1>; | |
| 174 | + #size-cells = <1>; | |
| 175 | + partition@0 { | |
| 176 | + label = "kernel"; | |
| 177 | + reg = <0x00000000 0x001e0000>; | |
| 178 | + }; | |
| 179 | + partition@1e0000 { | |
| 180 | + label = "dtb"; | |
| 181 | + reg = <0x001e0000 0x00020000>; | |
| 182 | + }; | |
| 183 | + partition@200000 { | |
| 184 | + label = "root"; | |
| 185 | + reg = <0x00200000 0x00200000>; | |
| 186 | + }; | |
| 187 | + partition@400000 { | |
| 188 | + label = "user"; | |
| 189 | + reg = <0x00400000 0x00b60000>; | |
| 190 | + }; | |
| 191 | + partition@f60000 { | |
| 192 | + label = "env"; | |
| 193 | + reg = <0x00f60000 0x00040000>; | |
| 194 | + }; | |
| 195 | + partition@fa0000 { | |
| 196 | + label = "u-boot"; | |
| 197 | + reg = <0x00fa0000 0x00060000>; | |
| 198 | + }; | |
| 199 | + }; | |
| 200 | + | |
| 201 | + SysACE_CompactFlash: sysace@1,0 { | |
| 202 | + compatible = "xlnx,sysace"; | |
| 203 | + interrupt-parent = <&UIC2>; | |
| 204 | + interrupts = <24 0x4>; | |
| 205 | + reg = <0x00000001 0x00000000 0x10000>; | |
| 206 | + }; | |
| 207 | + }; | |
| 208 | + | |
| 209 | + UART0: serial@f0000200 { | |
| 210 | + device_type = "serial"; | |
| 211 | + compatible = "ns16550"; | |
| 212 | + reg = <0xf0000200 0x00000008>; | |
| 213 | + virtual-reg = <0xa0000200>; | |
| 214 | + clock-frequency = <0>; /* Filled in by U-Boot */ | |
| 215 | + current-speed = <115200>; | |
| 216 | + interrupt-parent = <&UIC0>; | |
| 217 | + interrupts = <0x0 0x4>; | |
| 218 | + }; | |
| 219 | + | |
| 220 | + UART1: serial@f0000300 { | |
| 221 | + device_type = "serial"; | |
| 222 | + compatible = "ns16550"; | |
| 223 | + reg = <0xf0000300 0x00000008>; | |
| 224 | + virtual-reg = <0xa0000300>; | |
| 225 | + clock-frequency = <0>; | |
| 226 | + current-speed = <0>; | |
| 227 | + interrupt-parent = <&UIC0>; | |
| 228 | + interrupts = <0x1 0x4>; | |
| 229 | + }; | |
| 230 | + | |
| 231 | + | |
| 232 | + UART2: serial@f0000600 { | |
| 233 | + device_type = "serial"; | |
| 234 | + compatible = "ns16550"; | |
| 235 | + reg = <0xf0000600 0x00000008>; | |
| 236 | + virtual-reg = <0xa0000600>; | |
| 237 | + clock-frequency = <0>; | |
| 238 | + current-speed = <0>; | |
| 239 | + interrupt-parent = <&UIC1>; | |
| 240 | + interrupts = <0x5 0x4>; | |
| 241 | + }; | |
| 242 | + | |
| 243 | + IIC0: i2c@f0000400 { | |
| 244 | + compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; | |
| 245 | + reg = <0xf0000400 0x00000014>; | |
| 246 | + interrupt-parent = <&UIC0>; | |
| 247 | + interrupts = <0x2 0x4>; | |
| 248 | + }; | |
| 249 | + | |
| 250 | + IIC1: i2c@f0000500 { | |
| 251 | + compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; | |
| 252 | + reg = <0xf0000500 0x00000014>; | |
| 253 | + interrupt-parent = <&UIC0>; | |
| 254 | + interrupts = <0x3 0x4>; | |
| 255 | + #address-cells = <1>; | |
| 256 | + #size-cells = <0>; | |
| 257 | + | |
| 258 | + rtc@68 { | |
| 259 | + compatible = "stm,m41t00"; | |
| 260 | + reg = <0x68>; | |
| 261 | + }; | |
| 262 | + }; | |
| 263 | + | |
| 264 | + EMAC0: ethernet@f0000800 { | |
| 265 | + linux,network-index = <0x0>; | |
| 266 | + device_type = "network"; | |
| 267 | + compatible = "ibm,emac-440spe", "ibm,emac4"; | |
| 268 | + interrupt-parent = <&UIC1>; | |
| 269 | + interrupts = <0x1c 0x4 0x1d 0x4>; | |
| 270 | + reg = <0xf0000800 0x00000074>; | |
| 271 | + local-mac-address = [000000000000]; | |
| 272 | + mal-device = <&MAL0>; | |
| 273 | + mal-tx-channel = <0>; | |
| 274 | + mal-rx-channel = <0>; | |
| 275 | + cell-index = <0>; | |
| 276 | + max-frame-size = <9000>; | |
| 277 | + rx-fifo-size = <4096>; | |
| 278 | + tx-fifo-size = <2048>; | |
| 279 | + phy-mode = "gmii"; | |
| 280 | + phy-map = <0x00000000>; | |
| 281 | + has-inverted-stacr-oc; | |
| 282 | + has-new-stacr-staopc; | |
| 283 | + }; | |
| 284 | + }; | |
| 285 | + | |
| 286 | + PCIX0: pci@c0ec00000 { | |
| 287 | + device_type = "pci"; | |
| 288 | + #interrupt-cells = <1>; | |
| 289 | + #size-cells = <2>; | |
| 290 | + #address-cells = <3>; | |
| 291 | + compatible = "ibm,plb-pcix-440spe", "ibm,plb-pcix"; | |
| 292 | + primary; | |
| 293 | + large-inbound-windows; | |
| 294 | + enable-msi-hole; | |
| 295 | + reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */ | |
| 296 | + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ | |
| 297 | + 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */ | |
| 298 | + 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */ | |
| 299 | + 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */ | |
| 300 | + | |
| 301 | + /* Outbound ranges, one memory and one IO, | |
| 302 | + * later cannot be changed | |
| 303 | + */ | |
| 304 | + ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 | |
| 305 | + 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; | |
| 306 | + | |
| 307 | + /* Inbound 4GB range starting at 0 */ | |
| 308 | + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>; | |
| 309 | + | |
| 310 | + /* This drives busses 0 to 0xf */ | |
| 311 | + bus-range = <0x0 0xf>; | |
| 312 | + | |
| 313 | + /* PCI-X interrupt (SM502) is routed to extIRQ10 (UIC1, 19) */ | |
| 314 | + interrupt-map-mask = <0x0 0x0 0x0 0x0>; | |
| 315 | + interrupt-map = <0x0 0x0 0x0 0x0 &UIC1 19 0x8>; | |
| 316 | + }; | |
| 317 | + | |
| 318 | + PCIE0: pciex@d00000000 { | |
| 319 | + device_type = "pci"; | |
| 320 | + #interrupt-cells = <1>; | |
| 321 | + #size-cells = <2>; | |
| 322 | + #address-cells = <3>; | |
| 323 | + compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; | |
| 324 | + primary; | |
| 325 | + port = <0x0>; /* port number */ | |
| 326 | + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ | |
| 327 | + 0x0000000c 0x10000000 0x00001000>; /* Registers */ | |
| 328 | + dcr-reg = <0x100 0x020>; | |
| 329 | + sdr-base = <0x300>; | |
| 330 | + | |
| 331 | + /* Outbound ranges, one memory and one IO, | |
| 332 | + * later cannot be changed | |
| 333 | + */ | |
| 334 | + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 | |
| 335 | + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; | |
| 336 | + | |
| 337 | + /* Inbound 4GB range starting at 0 */ | |
| 338 | + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>; | |
| 339 | + | |
| 340 | + /* This drives busses 0x10 to 0x1f */ | |
| 341 | + bus-range = <0x10 0x1f>; | |
| 342 | + | |
| 343 | + /* Legacy interrupts (note the weird polarity, the bridge seems | |
| 344 | + * to invert PCIe legacy interrupts). | |
| 345 | + * We are de-swizzling here because the numbers are actually for | |
| 346 | + * port of the root complex virtual P2P bridge. But I want | |
| 347 | + * to avoid putting a node for it in the tree, so the numbers | |
| 348 | + * below are basically de-swizzled numbers. | |
| 349 | + * The real slot is on idsel 0, so the swizzling is 1:1 | |
| 350 | + */ | |
| 351 | + interrupt-map-mask = <0x0 0x0 0x0 0x7>; | |
| 352 | + interrupt-map = < | |
| 353 | + 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */ | |
| 354 | + 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */ | |
| 355 | + 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */ | |
| 356 | + 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>; | |
| 357 | + }; | |
| 358 | + | |
| 359 | + PCIE1: pciex@d20000000 { | |
| 360 | + device_type = "pci"; | |
| 361 | + #interrupt-cells = <1>; | |
| 362 | + #size-cells = <2>; | |
| 363 | + #address-cells = <3>; | |
| 364 | + compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; | |
| 365 | + primary; | |
| 366 | + port = <0x1>; /* port number */ | |
| 367 | + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ | |
| 368 | + 0x0000000c 0x10001000 0x00001000>; /* Registers */ | |
| 369 | + dcr-reg = <0x120 0x020>; | |
| 370 | + sdr-base = <0x340>; | |
| 371 | + | |
| 372 | + /* Outbound ranges, one memory and one IO, | |
| 373 | + * later cannot be changed | |
| 374 | + */ | |
| 375 | + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 | |
| 376 | + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; | |
| 377 | + | |
| 378 | + /* Inbound 4GB range starting at 0 */ | |
| 379 | + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>; | |
| 380 | + | |
| 381 | + /* This drives busses 0x20 to 0x2f */ | |
| 382 | + bus-range = <0x20 0x2f>; | |
| 383 | + | |
| 384 | + /* Legacy interrupts (note the weird polarity, the bridge seems | |
| 385 | + * to invert PCIe legacy interrupts). | |
| 386 | + * We are de-swizzling here because the numbers are actually for | |
| 387 | + * port of the root complex virtual P2P bridge. But I want | |
| 388 | + * to avoid putting a node for it in the tree, so the numbers | |
| 389 | + * below are basically de-swizzled numbers. | |
| 390 | + * The real slot is on idsel 0, so the swizzling is 1:1 | |
| 391 | + */ | |
| 392 | + interrupt-map-mask = <0x0 0x0 0x0 0x7>; | |
| 393 | + interrupt-map = < | |
| 394 | + 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */ | |
| 395 | + 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */ | |
| 396 | + 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */ | |
| 397 | + 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>; | |
| 398 | + }; | |
| 399 | + | |
| 400 | + I2O: i2o@400100000 { | |
| 401 | + compatible = "ibm,i2o-440spe"; | |
| 402 | + reg = <0x00000004 0x00100000 0x100>; | |
| 403 | + dcr-reg = <0x060 0x020>; | |
| 404 | + }; | |
| 405 | + | |
| 406 | + DMA0: dma0@400100100 { | |
| 407 | + compatible = "ibm,dma-440spe"; | |
| 408 | + cell-index = <0>; | |
| 409 | + reg = <0x00000004 0x00100100 0x100>; | |
| 410 | + dcr-reg = <0x060 0x020>; | |
| 411 | + interrupt-parent = <&DMA0>; | |
| 412 | + interrupts = <0 1>; | |
| 413 | + #interrupt-cells = <1>; | |
| 414 | + #address-cells = <0>; | |
| 415 | + #size-cells = <0>; | |
| 416 | + interrupt-map = < | |
| 417 | + 0 &UIC0 0x14 4 | |
| 418 | + 1 &UIC1 0x16 4>; | |
| 419 | + }; | |
| 420 | + | |
| 421 | + DMA1: dma1@400100200 { | |
| 422 | + compatible = "ibm,dma-440spe"; | |
| 423 | + cell-index = <1>; | |
| 424 | + reg = <0x00000004 0x00100200 0x100>; | |
| 425 | + dcr-reg = <0x060 0x020>; | |
| 426 | + interrupt-parent = <&DMA1>; | |
| 427 | + interrupts = <0 1>; | |
| 428 | + #interrupt-cells = <1>; | |
| 429 | + #address-cells = <0>; | |
| 430 | + #size-cells = <0>; | |
| 431 | + interrupt-map = < | |
| 432 | + 0 &UIC0 0x16 4 | |
| 433 | + 1 &UIC1 0x16 4>; | |
| 434 | + }; | |
| 435 | + | |
| 436 | + xor-accel@400200000 { | |
| 437 | + compatible = "amcc,xor-accelerator"; | |
| 438 | + reg = <0x00000004 0x00200000 0x400>; | |
| 439 | + interrupt-parent = <&UIC1>; | |
| 440 | + interrupts = <0x1f 4>; | |
| 441 | + }; | |
| 442 | + }; | |
| 443 | + | |
| 444 | + chosen { | |
| 445 | + linux,stdout-path = "/plb/opb/serial@f0000200"; | |
| 446 | + }; | |
| 447 | +}; | |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | d-cache-size = <32768>; |
| 45 | 45 | dcr-controller; |
| 46 | 46 | dcr-access-method = "native"; |
| 47 | + reset-type = <2>; /* Use chip-reset */ | |
| 47 | 48 | }; |
| 48 | 49 | }; |
| 49 | 50 | |
| @@ -20,10 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | aliases { |
| 21 | 21 | ethernet0 = &enet0; |
| 22 | 22 | ethernet1 = &enet1; |
| 23 | −/* | |
| 24 | 23 | ethernet2 = &enet2; |
| 25 | 24 | ethernet3 = &enet3; |
| 26 | −*/ | |
| 27 | 25 | serial0 = &serial0; |
| 28 | 26 | serial1 = &serial1; |
| 29 | 27 | pci0 = &pci0; |
| @@ -254,7 +252,6 @@ · 224 unmodified lines | ||
| 254 | 252 | }; |
| 255 | 253 | }; |
| 256 | 254 | |
| 257 | −/* eTSEC 3/4 are currently broken | |
| 258 | 255 | enet2: ethernet@26000 { |
| 259 | 256 | #address-cells = <1>; |
| 260 | 257 | #size-cells = <1>; |
| @@ -310,7 +307,6 @@ · 49 unmodified lines | ||
| 310 | 307 | }; |
| 311 | 308 | }; |
| 312 | 309 | }; |
| 313 | − */ | |
| 314 | 310 | |
| 315 | 311 | serial0: serial@4500 { |
| 316 | 312 | cell-index = <0>; |
| @@ -215,6 +215,18 @@ · 214 unmodified lines | ||
| 215 | 215 | clock-frequency = <0>; |
| 216 | 216 | }; |
| 217 | 217 | |
| 218 | + msi@41600 { | |
| 219 | + compatible = "fsl,mpc8572-msi", "fsl,mpic-msi"; | |
| 220 | + reg = <0x41600 0x80>; | |
| 221 | + msi-available-ranges = <0 0x80>; | |
| 222 | + interrupts = < | |
| 223 | + 0xe0 0 | |
| 224 | + 0xe1 0 | |
| 225 | + 0xe2 0 | |
| 226 | + 0xe3 0>; | |
| 227 | + interrupt-parent = <&mpic>; | |
| 228 | + }; | |
| 229 | + | |
| 218 | 230 | global-utilities@e0000 { //global utilities block |
| 219 | 231 | compatible = "fsl,mpc8572-guts"; |
| 220 | 232 | reg = <0xe0000 0x1000>; |
| @@ -243,8 +255,7 @@ · 22 unmodified lines | ||
| 243 | 255 | protected-sources = < |
| 244 | 256 | 31 32 33 37 38 39 /* enet2 enet3 */ |
| 245 | 257 | 76 77 78 79 26 42 /* dma2 pci2 serial*/ |
| 246 | − 0xe0 0xe1 0xe2 0xe3 /* msi */ | |
| 247 | − 0xe4 0xe5 0xe6 0xe7 | |
| 258 | + 0xe4 0xe5 0xe6 0xe7 /* msi */ | |
| 248 | 259 | >; |
| 249 | 260 | }; |
| 250 | 261 | }; |
| @@ -154,12 +154,8 @@ · 153 unmodified lines | ||
| 154 | 154 | msi@41600 { |
| 155 | 155 | compatible = "fsl,mpc8572-msi", "fsl,mpic-msi"; |
| 156 | 156 | reg = <0x41600 0x80>; |
| 157 | − msi-available-ranges = <0 0x100>; | |
| 157 | + msi-available-ranges = <0x80 0x80>; | |
| 158 | 158 | interrupts = < |
| 159 | − 0xe0 0 | |
| 160 | − 0xe1 0 | |
| 161 | − 0xe2 0 | |
| 162 | − 0xe3 0 | |
| 163 | 159 | 0xe4 0 |
| 164 | 160 | 0xe5 0 |
| 165 | 161 | 0xe6 0 |
| @@ -190,6 +186,7 @@ · 24 unmodified lines | ||
| 190 | 186 | 0x1 0x2 0x3 0x4 /* pci slot */ |
| 191 | 187 | 0x9 0xa 0xb 0xc /* usb */ |
| 192 | 188 | 0x6 0x7 0xe 0x5 /* Audio elgacy SATA */ |
| 189 | + 0xe0 0xe1 0xe2 0xe3 /* msi */ | |
| 193 | 190 | >; |
| 194 | 191 | }; |
| 195 | 192 | }; |
| @@ -0,0 +1,698 @@ | ||
| 1 | +/* | |
| 2 | + * P1021 MDS Device Tree Source | |
| 3 | + * | |
| 4 | + * Copyright 2010 Freescale Semiconductor Inc. | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify it | |
| 7 | + * under the terms of the GNU General Public License as published by the | |
| 8 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 9 | + * option) any later version. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +/dts-v1/; | |
| 13 | +/ { | |
| 14 | + model = "fsl,P1021"; | |
| 15 | + compatible = "fsl,P1021MDS"; | |
| 16 | + #address-cells = <2>; | |
| 17 | + #size-cells = <2>; | |
| 18 | + | |
| 19 | + aliases { | |
| 20 | + serial0 = &serial0; | |
| 21 | + serial1 = &serial1; | |
| 22 | + ethernet0 = &enet0; | |
| 23 | + ethernet1 = &enet1; | |
| 24 | + ethernet2 = &enet2; | |
| 25 | + ethernet3 = &enet3; | |
| 26 | + ethernet4 = &enet4; | |
| 27 | + pci0 = &pci0; | |
| 28 | + pci1 = &pci1; | |
| 29 | + }; | |
| 30 | + | |
| 31 | + cpus { | |
| 32 | + #address-cells = <1>; | |
| 33 | + #size-cells = <0>; | |
| 34 | + | |
| 35 | + PowerPC,P1021@0 { | |
| 36 | + device_type = "cpu"; | |
| 37 | + reg = <0x0>; | |
| 38 | + next-level-cache = <&L2>; | |
| 39 | + }; | |
| 40 | + | |
| 41 | + PowerPC,P1021@1 { | |
| 42 | + device_type = "cpu"; | |
| 43 | + reg = <0x1>; | |
| 44 | + next-level-cache = <&L2>; | |
| 45 | + }; | |
| 46 | + }; | |
| 47 | + | |
| 48 | + memory { | |
| 49 | + device_type = "memory"; | |
| 50 | + }; | |
| 51 | + | |
| 52 | + localbus@ffe05000 { | |
| 53 | + #address-cells = <2>; | |
| 54 | + #size-cells = <1>; | |
| 55 | + compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus"; | |
| 56 | + reg = <0 0xffe05000 0 0x1000>; | |
| 57 | + interrupts = <19 2>; | |
| 58 | + interrupt-parent = <&mpic>; | |
| 59 | + | |
| 60 | + /* NAND Flash, BCSR, PMC0/1*/ | |
| 61 | + ranges = <0x0 0x0 0x0 0xfc000000 0x02000000 | |
| 62 | + 0x1 0x0 0x0 0xf8000000 0x00008000 | |
| 63 | + 0x2 0x0 0x0 0xf8010000 0x00020000 | |
| 64 | + 0x3 0x0 0x0 0xf8020000 0x00020000>; | |
| 65 | + | |
| 66 | + nand@0,0 { | |
| 67 | + #address-cells = <1>; | |
| 68 | + #size-cells = <1>; | |
| 69 | + compatible = "fsl,p1021-fcm-nand", | |
| 70 | + "fsl,elbc-fcm-nand"; | |
| 71 | + reg = <0x0 0x0 0x40000>; | |
| 72 | + | |
| 73 | + partition@0 { | |
| 74 | + /* This location must not be altered */ | |
| 75 | + /* 1MB for u-boot Bootloader Image */ | |
| 76 | + reg = <0x0 0x00100000>; | |
| 77 | + label = "NAND (RO) U-Boot Image"; | |
| 78 | + read-only; | |
| 79 | + }; | |
| 80 | + | |
| 81 | + partition@100000 { | |
| 82 | + /* 1MB for DTB Image */ | |
| 83 | + reg = <0x00100000 0x00100000>; | |
| 84 | + label = "NAND (RO) DTB Image"; | |
| 85 | + read-only; | |
| 86 | + }; | |
| 87 | + | |
| 88 | + partition@200000 { | |
| 89 | + /* 4MB for Linux Kernel Image */ | |
| 90 | + reg = <0x00200000 0x00400000>; | |
| 91 | + label = "NAND (RO) Linux Kernel Image"; | |
| 92 | + read-only; | |
| 93 | + }; | |
| 94 | + | |
| 95 | + partition@600000 { | |
| 96 | + /* 5MB for Compressed Root file System Image */ | |
| 97 | + reg = <0x00600000 0x00500000>; | |
| 98 | + label = "NAND (RO) Compressed RFS Image"; | |
| 99 | + read-only; | |
| 100 | + }; | |
| 101 | + | |
| 102 | + partition@b00000 { | |
| 103 | + /* 6MB for JFFS2 based Root file System */ | |
| 104 | + reg = <0x00a00000 0x00600000>; | |
| 105 | + label = "NAND (RW) JFFS2 Root File System"; | |
| 106 | + }; | |
| 107 | + | |
| 108 | + partition@1100000 { | |
| 109 | + /* 14MB for JFFS2 based Root file System */ | |
| 110 | + reg = <0x01100000 0x00e00000>; | |
| 111 | + label = "NAND (RW) Writable User area"; | |
| 112 | + }; | |
| 113 | + | |
| 114 | + partition@1f00000 { | |
| 115 | + /* 1MB for microcode */ | |
| 116 | + reg = <0x01f00000 0x00100000>; | |
| 117 | + label = "NAND (RO) QE Ucode"; | |
| 118 | + read-only; | |
| 119 | + }; | |
| 120 | + }; | |
| 121 | + | |
| 122 | + bcsr@1,0 { | |
| 123 | + #address-cells = <1>; | |
| 124 | + #size-cells = <1>; | |
| 125 | + compatible = "fsl,p1021mds-bcsr"; | |
| 126 | + reg = <1 0 0x8000>; | |
| 127 | + ranges = <0 1 0 0x8000>; | |
| 128 | + }; | |
| 129 | + | |
| 130 | + pib@2,0 { | |
| 131 | + compatible = "fsl,p1021mds-pib"; | |
| 132 | + reg = <2 0 0x10000>; | |
| 133 | + }; | |
| 134 | + | |
| 135 | + pib@3,0 { | |
| 136 | + compatible = "fsl,p1021mds-pib"; | |
| 137 | + reg = <3 0 0x10000>; | |
| 138 | + }; | |
| 139 | + }; | |
| 140 | + | |
| 141 | + soc@ffe00000 { | |
| 142 | + | |
| 143 | + #address-cells = <1>; | |
| 144 | + #size-cells = <1>; | |
| 145 | + device_type = "soc"; | |
| 146 | + compatible = "fsl,p1021-immr", "simple-bus"; | |
| 147 | + ranges = <0x0 0x0 0xffe00000 0x100000>; | |
| 148 | + bus-frequency = <0>; // Filled out by uboot. | |
| 149 | + | |
| 150 | + ecm-law@0 { | |
| 151 | + compatible = "fsl,ecm-law"; | |
| 152 | + reg = <0x0 0x1000>; | |
| 153 | + fsl,num-laws = <12>; | |
| 154 | + }; | |
| 155 | + | |
| 156 | + ecm@1000 { | |
| 157 | + compatible = "fsl,p1021-ecm", "fsl,ecm"; | |
| 158 | + reg = <0x1000 0x1000>; | |
| 159 | + interrupts = <16 2>; | |
| 160 | + interrupt-parent = <&mpic>; | |
| 161 | + }; | |
| 162 | + | |
| 163 | + memory-controller@2000 { | |
| 164 | + compatible = "fsl,p1021-memory-controller"; | |
| 165 | + reg = <0x2000 0x1000>; | |
| 166 | + interrupt-parent = <&mpic>; | |
| 167 | + interrupts = <16 2>; | |
| 168 | + }; | |
| 169 | + | |
| 170 | + i2c@3000 { | |
| 171 | + #address-cells = <1>; | |
| 172 | + #size-cells = <0>; | |
| 173 | + cell-index = <0>; | |
| 174 | + compatible = "fsl-i2c"; | |
| 175 | + reg = <0x3000 0x100>; | |
| 176 | + interrupts = <43 2>; | |
| 177 | + interrupt-parent = <&mpic>; | |
| 178 | + dfsrr; | |
| 179 | + rtc@68 { | |
| 180 | + compatible = "dallas,ds1374"; | |
| 181 | + reg = <0x68>; | |
| 182 | + }; | |
| 183 | + }; | |
| 184 | + | |
| 185 | + i2c@3100 { | |
| 186 | + #address-cells = <1>; | |
| 187 | + #size-cells = <0>; | |
| 188 | + cell-index = <1>; | |
| 189 | + compatible = "fsl-i2c"; | |
| 190 | + reg = <0x3100 0x100>; | |
| 191 | + interrupts = <43 2>; | |
| 192 | + interrupt-parent = <&mpic>; | |
| 193 | + dfsrr; | |
| 194 | + }; | |
| 195 | + | |
| 196 | + serial0: serial@4500 { | |
| 197 | + cell-index = <0>; | |
| 198 | + device_type = "serial"; | |
| 199 | + compatible = "ns16550"; | |
| 200 | + reg = <0x4500 0x100>; | |
| 201 | + clock-frequency = <0>; | |
| 202 | + interrupts = <42 2>; | |
| 203 | + interrupt-parent = <&mpic>; | |
| 204 | + }; | |
| 205 | + | |
| 206 | + serial1: serial@4600 { | |
| 207 | + cell-index = <1>; | |
| 208 | + device_type = "serial"; | |
| 209 | + compatible = "ns16550"; | |
| 210 | + reg = <0x4600 0x100>; | |
| 211 | + clock-frequency = <0>; | |
| 212 | + interrupts = <42 2>; | |
| 213 | + interrupt-parent = <&mpic>; | |
| 214 | + }; | |
| 215 | + | |
| 216 | + spi@7000 { | |
| 217 | + cell-index = <0>; | |
| 218 | + #address-cells = <1>; | |
| 219 | + #size-cells = <0>; | |
| 220 | + compatible = "fsl,espi"; | |
| 221 | + reg = <0x7000 0x1000>; | |
| 222 | + interrupts = <59 0x2>; | |
| 223 | + interrupt-parent = <&mpic>; | |
| 224 | + espi,num-ss-bits = <4>; | |
| 225 | + mode = "cpu"; | |
| 226 | + | |
| 227 | + fsl_m25p80@0 { | |
| 228 | + #address-cells = <1>; | |
| 229 | + #size-cells = <1>; | |
| 230 | + compatible = "fsl,espi-flash"; | |
| 231 | + reg = <0>; | |
| 232 | + linux,modalias = "fsl_m25p80"; | |
| 233 | + spi-max-frequency = <40000000>; /* input clock */ | |
| 234 | + partition@u-boot { | |
| 235 | + label = "u-boot-spi"; | |
| 236 | + reg = <0x00000000 0x00100000>; | |
| 237 | + read-only; | |
| 238 | + }; | |
| 239 | + partition@kernel { | |
| 240 | + label = "kernel-spi"; | |
| 241 | + reg = <0x00100000 0x00500000>; | |
| 242 | + read-only; | |
| 243 | + }; | |
| 244 | + partition@dtb { | |
| 245 | + label = "dtb-spi"; | |
| 246 | + reg = <0x00600000 0x00100000>; | |
| 247 | + read-only; | |
| 248 | + }; | |
| 249 | + partition@fs { | |
| 250 | + label = "file system-spi"; | |
| 251 | + reg = <0x00700000 0x00900000>; | |
| 252 | + }; | |
| 253 | + }; | |
| 254 | + }; | |
| 255 | + | |
| 256 | + gpio: gpio-controller@f000 { | |
| 257 | + #gpio-cells = <2>; | |
| 258 | + compatible = "fsl,mpc8572-gpio"; | |
| 259 | + reg = <0xf000 0x100>; | |
| 260 | + interrupts = <47 0x2>; | |
| 261 | + interrupt-parent = <&mpic>; | |
| 262 | + gpio-controller; | |
| 263 | + }; | |
| 264 | + | |
| 265 | + L2: l2-cache-controller@20000 { | |
| 266 | + compatible = "fsl,p1021-l2-cache-controller"; | |
| 267 | + reg = <0x20000 0x1000>; | |
| 268 | + cache-line-size = <32>; // 32 bytes | |
| 269 | + cache-size = <0x40000>; // L2,256K | |
| 270 | + interrupt-parent = <&mpic>; | |
| 271 | + interrupts = <16 2>; | |
| 272 | + }; | |
| 273 | + | |
| 274 | + dma@21300 { | |
| 275 | + #address-cells = <1>; | |
| 276 | + #size-cells = <1>; | |
| 277 | + compatible = "fsl,eloplus-dma"; | |
| 278 | + reg = <0x21300 0x4>; | |
| 279 | + ranges = <0x0 0x21100 0x200>; | |
| 280 | + cell-index = <0>; | |
| 281 | + dma-channel@0 { | |
| 282 | + compatible = "fsl,eloplus-dma-channel"; | |
| 283 | + reg = <0x0 0x80>; | |
| 284 | + cell-index = <0>; | |
| 285 | + interrupt-parent = <&mpic>; | |
| 286 | + interrupts = <20 2>; | |
| 287 | + }; | |
| 288 | + dma-channel@80 { | |
| 289 | + compatible = "fsl,eloplus-dma-channel"; | |
| 290 | + reg = <0x80 0x80>; | |
| 291 | + cell-index = <1>; | |
| 292 | + interrupt-parent = <&mpic>; | |
| 293 | + interrupts = <21 2>; | |
| 294 | + }; | |
| 295 | + dma-channel@100 { | |
| 296 | + compatible = "fsl,eloplus-dma-channel"; | |
| 297 | + reg = <0x100 0x80>; | |
| 298 | + cell-index = <2>; | |
| 299 | + interrupt-parent = <&mpic>; | |
| 300 | + interrupts = <22 2>; | |
| 301 | + }; | |
| 302 | + dma-channel@180 { | |
| 303 | + compatible = "fsl,eloplus-dma-channel"; | |
| 304 | + reg = <0x180 0x80>; | |
| 305 | + cell-index = <3>; | |
| 306 | + interrupt-parent = <&mpic>; | |
| 307 | + interrupts = <23 2>; | |
| 308 | + }; | |
| 309 | + }; | |
| 310 | + | |
| 311 | + usb@22000 { | |
| 312 | + #address-cells = <1>; | |
| 313 | + #size-cells = <0>; | |
| 314 | + compatible = "fsl-usb2-dr"; | |
| 315 | + reg = <0x22000 0x1000>; | |
| 316 | + interrupt-parent = <&mpic>; | |
| 317 | + interrupts = <28 0x2>; | |
| 318 | + phy_type = "ulpi"; | |
| 319 | + }; | |
| 320 | + | |
| 321 | + mdio@24000 { | |
| 322 | + #address-cells = <1>; | |
| 323 | + #size-cells = <0>; | |
| 324 | + compatible = "fsl,etsec2-mdio"; | |
| 325 | + reg = <0x24000 0x1000 0xb0030 0x4>; | |
| 326 | + | |
| 327 | + phy0: ethernet-phy@0 { | |
| 328 | + interrupt-parent = <&mpic>; | |
| 329 | + interrupts = <1 1>; | |
| 330 | + reg = <0x0>; | |
| 331 | + }; | |
| 332 | + phy1: ethernet-phy@1 { | |
| 333 | + interrupt-parent = <&mpic>; | |
| 334 | + interrupts = <2 1>; | |
| 335 | + reg = <0x1>; | |
| 336 | + }; | |
| 337 | + phy4: ethernet-phy@4 { | |
| 338 | + interrupt-parent = <&mpic>; | |
| 339 | + reg = <0x4>; | |
| 340 | + }; | |
| 341 | + }; | |
| 342 | + | |
| 343 | + mdio@25000 { | |
| 344 | + #address-cells = <1>; | |
| 345 | + #size-cells = <0>; | |
| 346 | + compatible = "fsl,etsec2-tbi"; | |
| 347 | + reg = <0x25000 0x1000 0xb1030 0x4>; | |
| 348 | + tbi0: tbi-phy@11 { | |
| 349 | + reg = <0x11>; | |
| 350 | + device_type = "tbi-phy"; | |
| 351 | + }; | |
| 352 | + }; | |
| 353 | + | |
| 354 | + enet0: ethernet@B0000 { | |
| 355 | + #address-cells = <1>; | |
| 356 | + #size-cells = <1>; | |
| 357 | + cell-index = <0>; | |
| 358 | + device_type = "network"; | |
| 359 | + model = "eTSEC"; | |
| 360 | + compatible = "fsl,etsec2"; | |
| 361 | + fsl,num_rx_queues = <0x8>; | |
| 362 | + fsl,num_tx_queues = <0x8>; | |
| 363 | + local-mac-address = [ 00 00 00 00 00 00 ]; | |
| 364 | + interrupt-parent = <&mpic>; | |
| 365 | + phy-handle = <&phy0>; | |
| 366 | + phy-connection-type = "rgmii-id"; | |
| 367 | + queue-group@0{ | |
| 368 | + #address-cells = <1>; | |
| 369 | + #size-cells = <1>; | |
| 370 | + reg = <0xB0000 0x1000>; | |
| 371 | + interrupts = <29 2 30 2 34 2>; | |
| 372 | + }; | |
| 373 | + queue-group@1{ | |
| 374 | + #address-cells = <1>; | |
| 375 | + #size-cells = <1>; | |
| 376 | + reg = <0xB4000 0x1000>; | |
| 377 | + interrupts = <17 2 18 2 24 2>; | |
| 378 | + }; | |
| 379 | + }; | |
| 380 | + | |
| 381 | + enet1: ethernet@B1000 { | |
| 382 | + #address-cells = <1>; | |
| 383 | + #size-cells = <1>; | |
| 384 | + cell-index = <0>; | |
| 385 | + device_type = "network"; | |
| 386 | + model = "eTSEC"; | |
| 387 | + compatible = "fsl,etsec2"; | |
| 388 | + fsl,num_rx_queues = <0x8>; | |
| 389 | + fsl,num_tx_queues = <0x8>; | |
| 390 | + local-mac-address = [ 00 00 00 00 00 00 ]; | |
| 391 | + interrupt-parent = <&mpic>; | |
| 392 | + phy-handle = <&phy4>; | |
| 393 | + tbi-handle = <&tbi0>; | |
| 394 | + phy-connection-type = "sgmii"; | |
| 395 | + queue-group@0{ | |
| 396 | + #address-cells = <1>; | |
| 397 | + #size-cells = <1>; | |
| 398 | + reg = <0xB1000 0x1000>; | |
| 399 | + interrupts = <35 2 36 2 40 2>; | |
| 400 | + }; | |
| 401 | + queue-group@1{ | |
| 402 | + #address-cells = <1>; | |
| 403 | + #size-cells = <1>; | |
| 404 | + reg = <0xB5000 0x1000>; | |
| 405 | + interrupts = <51 2 52 2 67 2>; | |
| 406 | + }; | |
| 407 | + }; | |
| 408 | + | |
| 409 | + enet2: ethernet@B2000 { | |
| 410 | + #address-cells = <1>; | |
| 411 | + #size-cells = <1>; | |
| 412 | + cell-index = <0>; | |
| 413 | + device_type = "network"; | |
| 414 | + model = "eTSEC"; | |
| 415 | + compatible = "fsl,etsec2"; | |
| 416 | + fsl,num_rx_queues = <0x8>; | |
| 417 | + fsl,num_tx_queues = <0x8>; | |
| 418 | + local-mac-address = [ 00 00 00 00 00 00 ]; | |
| 419 | + interrupt-parent = <&mpic>; | |
| 420 | + phy-handle = <&phy1>; | |
| 421 | + phy-connection-type = "rgmii-id"; | |
| 422 | + queue-group@0{ | |
| 423 | + #address-cells = <1>; | |
| 424 | + #size-cells = <1>; | |
| 425 | + reg = <0xB2000 0x1000>; | |
| 426 | + interrupts = <31 2 32 2 33 2>; | |
| 427 | + }; | |
| 428 | + queue-group@1{ | |
| 429 | + #address-cells = <1>; | |
| 430 | + #size-cells = <1>; | |
| 431 | + reg = <0xB6000 0x1000>; | |
| 432 | + interrupts = <25 2 26 2 27 2>; | |
| 433 | + }; | |
| 434 | + }; | |
| 435 | + | |
| 436 | + sdhci@2e000 { | |
| 437 | + compatible = "fsl,p1021-esdhc", "fsl,esdhc"; | |
| 438 | + reg = <0x2e000 0x1000>; | |
| 439 | + interrupts = <72 0x2>; | |
| 440 | + interrupt-parent = <&mpic>; | |
| 441 | + /* Filled in by U-Boot */ | |
| 442 | + clock-frequency = <0>; | |
| 443 | + }; | |
| 444 | + | |
| 445 | + crypto@30000 { | |
| 446 | + compatible = "fsl,sec3.3", "fsl,sec3.1", | |
| 447 | + "fsl,sec3.0", "fsl,sec2.4", | |
| 448 | + "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; | |
| 449 | + reg = <0x30000 0x10000>; | |
| 450 | + interrupts = <45 2 58 2>; | |
| 451 | + interrupt-parent = <&mpic>; | |
| 452 | + fsl,num-channels = <4>; | |
| 453 | + fsl,channel-fifo-len = <24>; | |
| 454 | + fsl,exec-units-mask = <0x97c>; | |
| 455 | + fsl,descriptor-types-mask = <0x3a30abf>; | |
| 456 | + }; | |
| 457 | + | |
| 458 | + mpic: pic@40000 { | |
| 459 | + interrupt-controller; | |
| 460 | + #address-cells = <0>; | |
| 461 | + #interrupt-cells = <2>; | |
| 462 | + reg = <0x40000 0x40000>; | |
| 463 | + compatible = "chrp,open-pic"; | |
| 464 | + device_type = "open-pic"; | |
| 465 | + }; | |
| 466 | + | |
| 467 | + msi@41600 { | |
| 468 | + compatible = "fsl,p1021-msi", "fsl,mpic-msi"; | |
| 469 | + reg = <0x41600 0x80>; | |
| 470 | + msi-available-ranges = <0 0x100>; | |
| 471 | + interrupts = < | |
| 472 | + 0xe0 0 | |
| 473 | + 0xe1 0 | |
| 474 | + 0xe2 0 | |
| 475 | + 0xe3 0 | |
| 476 | + 0xe4 0 | |
| 477 | + 0xe5 0 | |
| 478 | + 0xe6 0 | |
| 479 | + 0xe7 0>; | |
| 480 | + interrupt-parent = <&mpic>; | |
| 481 | + }; | |
| 482 | + | |
| 483 | + global-utilities@e0000 { //global utilities block | |
| 484 | + compatible = "fsl,p1021-guts"; | |
| 485 | + reg = <0xe0000 0x1000>; | |
| 486 | + fsl,has-rstcr; | |
| 487 | + }; | |
| 488 | + | |
| 489 | + par_io@e0100 { | |
| 490 | + #address-cells = <1>; | |
| 491 | + #size-cells = <1>; | |
| 492 | + reg = <0xe0100 0x60>; | |
| 493 | + ranges = <0x0 0xe0100 0x60>; | |
| 494 | + device_type = "par_io"; | |
| 495 | + num-ports = <3>; | |
| 496 | + pio1: ucc_pin@01 { | |
| 497 | + pio-map = < | |
| 498 | + /* port pin dir open_drain assignment has_irq */ | |
| 499 | + 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ | |
| 500 | + 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */ | |
| 501 | + 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */ | |
| 502 | + 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 | |
| 503 | +*/ | |
| 504 | + 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */ | |
| 505 | + 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */ | |
| 506 | + 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */ | |
| 507 | + 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */ | |
| 508 | + 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */ | |
| 509 | + 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */ | |
| 510 | + 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */ | |
| 511 | + 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */ | |
| 512 | + 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */ | |
| 513 | + 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */ | |
| 514 | + 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */ | |
| 515 | + 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */ | |
| 516 | + 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */ | |
| 517 | + 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */ | |
| 518 | + }; | |
| 519 | + | |
| 520 | + pio2: ucc_pin@02 { | |
| 521 | + pio-map = < | |
| 522 | + /* port pin dir open_drain assignment has_irq */ | |
| 523 | + 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ | |
| 524 | + 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */ | |
| 525 | + 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */ | |
| 526 | + 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */ | |
| 527 | + 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */ | |
| 528 | + 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */ | |
| 529 | + 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */ | |
| 530 | + 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */ | |
| 531 | + 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */ | |
| 532 | + 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */ | |
| 533 | + }; | |
| 534 | + }; | |
| 535 | + }; | |
| 536 | + | |
| 537 | + pci0: pcie@ffe09000 { | |
| 538 | + compatible = "fsl,mpc8548-pcie"; | |
| 539 | + device_type = "pci"; | |
| 540 | + #interrupt-cells = <1>; | |
| 541 | + #size-cells = <2>; | |
| 542 | + #address-cells = <3>; | |
| 543 | + reg = <0 0xffe09000 0 0x1000>; | |
| 544 | + bus-range = <0 255>; | |
| 545 | + ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 | |
| 546 | + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; | |
| 547 | + clock-frequency = <33333333>; | |
| 548 | + interrupt-parent = <&mpic>; | |
| 549 | + interrupts = <16 2>; | |
| 550 | + interrupt-map-mask = <0xf800 0 0 7>; | |
| 551 | + interrupt-map = < | |
| 552 | + /* IDSEL 0x0 */ | |
| 553 | + 0000 0 0 1 &mpic 4 1 | |
| 554 | + 0000 0 0 2 &mpic 5 1 | |
| 555 | + 0000 0 0 3 &mpic 6 1 | |
| 556 | + 0000 0 0 4 &mpic 7 1 | |
| 557 | + >; | |
| 558 | + pcie@0 { | |
| 559 | + reg = <0x0 0x0 0x0 0x0 0x0>; | |
| 560 | + #size-cells = <2>; | |
| 561 | + #address-cells = <3>; | |
| 562 | + device_type = "pci"; | |
| 563 | + ranges = <0x2000000 0x0 0xa0000000 | |
| 564 | + 0x2000000 0x0 0xa0000000 | |
| 565 | + 0x0 0x20000000 | |
| 566 | + | |
| 567 | + 0x1000000 0x0 0x0 | |
| 568 | + 0x1000000 0x0 0x0 | |
| 569 | + 0x0 0x100000>; | |
| 570 | + }; | |
| 571 | + }; | |
| 572 | + | |
| 573 | + pci1: pcie@ffe0a000 { | |
| 574 | + compatible = "fsl,mpc8548-pcie"; | |
| 575 | + device_type = "pci"; | |
| 576 | + #interrupt-cells = <1>; | |
| 577 | + #size-cells = <2>; | |
| 578 | + #address-cells = <3>; | |
| 579 | + reg = <0 0xffe0a000 0 0x1000>; | |
| 580 | + bus-range = <0 255>; | |
| 581 | + ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 | |
| 582 | + 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; | |
| 583 | + clock-frequency = <33333333>; | |
| 584 | + interrupt-parent = <&mpic>; | |
| 585 | + interrupts = <16 2>; | |
| 586 | + interrupt-map-mask = <0xf800 0 0 7>; | |
| 587 | + interrupt-map = < | |
| 588 | + /* IDSEL 0x0 */ | |
| 589 | + 0000 0 0 1 &mpic 0 1 | |
| 590 | + 0000 0 0 2 &mpic 1 1 | |
| 591 | + 0000 0 0 3 &mpic 2 1 | |
| 592 | + 0000 0 0 4 &mpic 3 1 | |
| 593 | + >; | |
| 594 | + pcie@0 { | |
| 595 | + reg = <0x0 0x0 0x0 0x0 0x0>; | |
| 596 | + #size-cells = <2>; | |
| 597 | + #address-cells = <3>; | |
| 598 | + device_type = "pci"; | |
| 599 | + ranges = <0x2000000 0x0 0xc0000000 | |
| 600 | + 0x2000000 0x0 0xc0000000 | |
| 601 | + 0x0 0x20000000 | |
| 602 | + | |
| 603 | + 0x1000000 0x0 0x0 | |
| 604 | + 0x1000000 0x0 0x0 | |
| 605 | + 0x0 0x100000>; | |
| 606 | + }; | |
| 607 | + }; | |
| 608 | + | |
| 609 | + qe@ffe80000 { | |
| 610 | + #address-cells = <1>; | |
| 611 | + #size-cells = <1>; | |
| 612 | + device_type = "qe"; | |
| 613 | + compatible = "fsl,qe"; | |
| 614 | + ranges = <0x0 0x0 0xffe80000 0x40000>; | |
| 615 | + reg = <0 0xffe80000 0 0x480>; | |
| 616 | + brg-frequency = <0>; | |
| 617 | + bus-frequency = <0>; | |
| 618 | + fsl,qe-num-riscs = <1>; | |
| 619 | + fsl,qe-num-snums = <28>; | |
| 620 | + | |
| 621 | + qeic: interrupt-controller@80 { | |
| 622 | + interrupt-controller; | |
| 623 | + compatible = "fsl,qe-ic"; | |
| 624 | + #address-cells = <0>; | |
| 625 | + #interrupt-cells = <1>; | |
| 626 | + reg = <0x80 0x80>; | |
| 627 | + interrupts = <63 2 60 2>; //high:47 low:44 | |
| 628 | + interrupt-parent = <&mpic>; | |
| 629 | + }; | |
| 630 | + | |
| 631 | + enet3: ucc@2000 { | |
| 632 | + device_type = "network"; | |
| 633 | + compatible = "ucc_geth"; | |
| 634 | + cell-index = <1>; | |
| 635 | + reg = <0x2000 0x200>; | |
| 636 | + interrupts = <32>; | |
| 637 | + interrupt-parent = <&qeic>; | |
| 638 | + local-mac-address = [ 00 00 00 00 00 00 ]; | |
| 639 | + rx-clock-name = "clk12"; | |
| 640 | + tx-clock-name = "clk9"; | |
| 641 | + pio-handle = <&pio1>; | |
| 642 | + phy-handle = <&qe_phy0>; | |
| 643 | + phy-connection-type = "mii"; | |
| 644 | + }; | |
| 645 | + | |
| 646 | + mdio@2120 { | |
| 647 | + #address-cells = <1>; | |
| 648 | + #size-cells = <0>; | |
| 649 | + reg = <0x2120 0x18>; | |
| 650 | + compatible = "fsl,ucc-mdio"; | |
| 651 | + | |
| 652 | + qe_phy0: ethernet-phy@0 { | |
| 653 | + interrupt-parent = <&mpic>; | |
| 654 | + interrupts = <4 1>; | |
| 655 | + reg = <0x0>; | |
| 656 | + device_type = "ethernet-phy"; | |
| 657 | + }; | |
| 658 | + qe_phy1: ethernet-phy@03 { | |
| 659 | + interrupt-parent = <&mpic>; | |
| 660 | + interrupts = <5 1>; | |
| 661 | + reg = <0x3>; | |
| 662 | + device_type = "ethernet-phy"; | |
| 663 | + }; | |
| 664 | + tbi-phy@11 { | |
| 665 | + reg = <0x11>; | |
| 666 | + device_type = "tbi-phy"; | |
| 667 | + }; | |
| 668 | + }; | |
| 669 | + | |
| 670 | + enet4: ucc@2400 { | |
| 671 | + device_type = "network"; | |
| 672 | + compatible = "ucc_geth"; | |
| 673 | + cell-index = <5>; | |
| 674 | + reg = <0x2400 0x200>; | |
| 675 | + interrupts = <40>; | |
| 676 | + interrupt-parent = <&qeic>; | |
| 677 | + local-mac-address = [ 00 00 00 00 00 00 ]; | |
| 678 | + rx-clock-name = "none"; | |
| 679 | + tx-clock-name = "clk13"; | |
| 680 | + pio-handle = <&pio2>; | |
| 681 | + phy-handle = <&qe_phy1>; | |
| 682 | + phy-connection-type = "rmii"; | |
| 683 | + }; | |
| 684 | + | |
| 685 | + muram@10000 { | |
| 686 | + #address-cells = <1>; | |
| 687 | + #size-cells = <1>; | |
| 688 | + compatible = "fsl,qe-muram", "fsl,cpm-muram"; | |
| 689 | + ranges = <0x0 0x10000 0x6000>; | |
| 690 | + | |
| 691 | + data-only@0 { | |
| 692 | + compatible = "fsl,qe-muram-data", | |
| 693 | + "fsl,cpm-muram-data"; | |
| 694 | + reg = <0x0 0x6000>; | |
| 695 | + }; | |
| 696 | + }; | |
| 697 | + }; | |
| 698 | +}; | |
| @@ -234,10 +234,132 @@ · 233 unmodified lines | ||
| 234 | 234 | has-inverted-stacr-oc; |
| 235 | 235 | has-new-stacr-staopc; |
| 236 | 236 | }; |
| 237 | + }; | |
| 238 | + PCIE0: pciex@d00000000 { | |
| 239 | + device_type = "pci"; | |
| 240 | + #interrupt-cells = <1>; | |
| 241 | + #size-cells = <2>; | |
| 242 | + #address-cells = <3>; | |
| 243 | + compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; | |
| 244 | + primary; | |
| 245 | + port = <0x0>; /* port number */ | |
| 246 | + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ | |
| 247 | + 0x0000000c 0x10000000 0x00001000>; /* Registers */ | |
| 248 | + dcr-reg = <0x100 0x020>; | |
| 249 | + sdr-base = <0x300>; | |
| 250 | + | |
| 251 | + /* Outbound ranges, one memory and one IO, | |
| 252 | + * later cannot be changed | |
| 253 | + */ | |
| 254 | + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 | |
| 255 | + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; | |
| 256 | + | |
| 257 | + /* Inbound 2GB range starting at 0 */ | |
| 258 | + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; | |
| 237 | 259 | |
| 260 | + /* This drives busses 10 to 0x1f */ | |
| 261 | + bus-range = <0x10 0x1f>; | |
| 262 | + | |
| 263 | + /* Legacy interrupts (note the weird polarity, the bridge seems | |
| 264 | + * to invert PCIe legacy interrupts). | |
| 265 | + * We are de-swizzling here because the numbers are actually for | |
| 266 | + * port of the root complex virtual P2P bridge. But I want | |
| 267 | + * to avoid putting a node for it in the tree, so the numbers | |
| 268 | + * below are basically de-swizzled numbers. | |
| 269 | + * The real slot is on idsel 0, so the swizzling is 1:1 | |
| 270 | + */ | |
| 271 | + interrupt-map-mask = <0x0 0x0 0x0 0x7>; | |
| 272 | + interrupt-map = < | |
| 273 | + 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */ | |
| 274 | + 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */ | |
| 275 | + 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */ | |
| 276 | + 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>; | |
| 277 | + }; | |
| 278 | + | |
| 279 | + PCIE1: pciex@d20000000 { | |
| 280 | + device_type = "pci"; | |
| 281 | + #interrupt-cells = <1>; | |
| 282 | + #size-cells = <2>; | |
| 283 | + #address-cells = <3>; | |
| 284 | + compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; | |
| 285 | + primary; | |
| 286 | + port = <0x1>; /* port number */ | |
| 287 | + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ | |
| 288 | + 0x0000000c 0x10001000 0x00001000>; /* Registers */ | |
| 289 | + dcr-reg = <0x120 0x020>; | |
| 290 | + sdr-base = <0x340>; | |
| 291 | + | |
| 292 | + /* Outbound ranges, one memory and one IO, | |
| 293 | + * later cannot be changed | |
| 294 | + */ | |
| 295 | + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 | |
| 296 | + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; | |
| 297 | + | |
| 298 | + /* Inbound 2GB range starting at 0 */ | |
| 299 | + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; | |
| 300 | + | |
| 301 | + /* This drives busses 10 to 0x1f */ | |
| 302 | + bus-range = <0x20 0x2f>; | |
| 303 | + | |
| 304 | + /* Legacy interrupts (note the weird polarity, the bridge seems | |
| 305 | + * to invert PCIe legacy interrupts). | |
| 306 | + * We are de-swizzling here because the numbers are actually for | |
| 307 | + * port of the root complex virtual P2P bridge. But I want | |
| 308 | + * to avoid putting a node for it in the tree, so the numbers | |
| 309 | + * below are basically de-swizzled numbers. | |
| 310 | + * The real slot is on idsel 0, so the swizzling is 1:1 | |
| 311 | + */ | |
| 312 | + interrupt-map-mask = <0x0 0x0 0x0 0x7>; | |
| 313 | + interrupt-map = < | |
| 314 | + 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */ | |
| 315 | + 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */ | |
| 316 | + 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */ | |
| 317 | + 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>; | |
| 318 | + }; | |
| 319 | + | |
| 320 | + PCIE2: pciex@d40000000 { | |
| 321 | + device_type = "pci"; | |
| 322 | + #interrupt-cells = <1>; | |
| 323 | + #size-cells = <2>; | |
| 324 | + #address-cells = <3>; | |
| 325 | + compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; | |
| 326 | + primary; | |
| 327 | + port = <0x2>; /* port number */ | |
| 328 | + reg = <0x0000000d 0x40000000 0x20000000 /* Config space access */ | |
| 329 | + 0x0000000c 0x10002000 0x00001000>; /* Registers */ | |
| 330 | + dcr-reg = <0x140 0x020>; | |
| 331 | + sdr-base = <0x370>; | |
| 332 | + | |
| 333 | + /* Outbound ranges, one memory and one IO, | |
| 334 | + * later cannot be changed | |
| 335 | + */ | |
| 336 | + ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000 | |
| 337 | + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>; | |
| 338 | + | |
| 339 | + /* Inbound 2GB range starting at 0 */ | |
| 340 | + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; | |
| 341 | + | |
| 342 | + /* This drives busses 10 to 0x1f */ | |
| 343 | + bus-range = <0x30 0x3f>; | |
| 344 | + | |
| 345 | + /* Legacy interrupts (note the weird polarity, the bridge seems | |
| 346 | + * to invert PCIe legacy interrupts). | |
| 347 | + * We are de-swizzling here because the numbers are actually for | |
| 348 | + * port of the root complex virtual P2P bridge. But I want | |
| 349 | + * to avoid putting a node for it in the tree, so the numbers | |
| 350 | + * below are basically de-swizzled numbers. | |
| 351 | + * The real slot is on idsel 0, so the swizzling is 1:1 | |
| 352 | + */ | |
| 353 | + interrupt-map-mask = <0x0 0x0 0x0 0x7>; | |
| 354 | + interrupt-map = < | |
| 355 | + 0x0 0x0 0x0 0x1 &UIC3 0x8 0x4 /* swizzled int A */ | |
| 356 | + 0x0 0x0 0x0 0x2 &UIC3 0x9 0x4 /* swizzled int B */ | |
| 357 | + 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ | |
| 358 | + 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; | |
| 238 | 359 | }; |
| 239 | 360 | |
| 240 | 361 | }; |
| 362 | + | |
| 241 | 363 | chosen { |
| 242 | 364 | linux,stdout-path = "/plb/opb/serial@ef600200"; |
| 243 | 365 | }; |
| @@ -0,0 +1,1451 @@ | ||
| 1 | +# | |
| 2 | +# Automatically generated make config: don't edit | |
| 3 | +# Linux kernel version: 2.6.34-rc7 | |
| 4 | +# Fri May 21 17:40:22 2010 | |
| 5 | +# | |
| 6 | +# CONFIG_PPC64 is not set | |
| 7 | + | |
| 8 | +# | |
| 9 | +# Processor support | |
| 10 | +# | |
| 11 | +# CONFIG_PPC_BOOK3S_32 is not set | |
| 12 | +# CONFIG_PPC_85xx is not set | |
| 13 | +# CONFIG_PPC_8xx is not set | |
| 14 | +# CONFIG_40x is not set | |
| 15 | +CONFIG_44x=y | |
| 16 | +# CONFIG_E200 is not set | |
| 17 | +CONFIG_4xx=y | |
| 18 | +CONFIG_BOOKE=y | |
| 19 | +CONFIG_PTE_64BIT=y | |
| 20 | +CONFIG_PHYS_64BIT=y | |
| 21 | +CONFIG_PPC_MMU_NOHASH=y | |
| 22 | +CONFIG_PPC_MMU_NOHASH_32=y | |
| 23 | +# CONFIG_PPC_MM_SLICES is not set | |
| 24 | +CONFIG_NOT_COHERENT_CACHE=y | |
| 25 | +CONFIG_PPC32=y | |
| 26 | +CONFIG_WORD_SIZE=32 | |
| 27 | +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y | |
| 28 | +CONFIG_MMU=y | |
| 29 | +CONFIG_GENERIC_CMOS_UPDATE=y | |
| 30 | +CONFIG_GENERIC_TIME=y | |
| 31 | +CONFIG_GENERIC_TIME_VSYSCALL=y | |
| 32 | +CONFIG_GENERIC_CLOCKEVENTS=y | |
| 33 | +CONFIG_GENERIC_HARDIRQS=y | |
| 34 | +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | |
| 35 | +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set | |
| 36 | +# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set | |
| 37 | +CONFIG_IRQ_PER_CPU=y | |
| 38 | +CONFIG_NR_IRQS=512 | |
| 39 | +CONFIG_STACKTRACE_SUPPORT=y | |
| 40 | +CONFIG_HAVE_LATENCYTOP_SUPPORT=y | |
| 41 | +CONFIG_TRACE_IRQFLAGS_SUPPORT=y | |
| 42 | +CONFIG_LOCKDEP_SUPPORT=y | |
| 43 | +CONFIG_RWSEM_XCHGADD_ALGORITHM=y | |
| 44 | +CONFIG_ARCH_HAS_ILOG2_U32=y | |
| 45 | +CONFIG_GENERIC_HWEIGHT=y | |
| 46 | +CONFIG_GENERIC_FIND_NEXT_BIT=y | |
| 47 | +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set | |
| 48 | +CONFIG_PPC=y | |
| 49 | +CONFIG_EARLY_PRINTK=y | |
| 50 | +CONFIG_GENERIC_NVRAM=y | |
| 51 | +CONFIG_SCHED_OMIT_FRAME_POINTER=y | |
| 52 | +CONFIG_ARCH_MAY_HAVE_PC_FDC=y | |
| 53 | +CONFIG_PPC_OF=y | |
| 54 | +CONFIG_OF=y | |
| 55 | +CONFIG_PPC_UDBG_16550=y | |
| 56 | +# CONFIG_GENERIC_TBSYNC is not set | |
| 57 | +CONFIG_AUDIT_ARCH=y | |
| 58 | +CONFIG_GENERIC_BUG=y | |
| 59 | +CONFIG_DTC=y | |
| 60 | +# CONFIG_DEFAULT_UIMAGE is not set | |
| 61 | +CONFIG_ARCH_HIBERNATION_POSSIBLE=y | |
| 62 | +CONFIG_PPC_DCR_NATIVE=y | |
| 63 | +# CONFIG_PPC_DCR_MMIO is not set | |
| 64 | +CONFIG_PPC_DCR=y | |
| 65 | +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y | |
| 66 | +CONFIG_PPC_ADV_DEBUG_REGS=y | |
| 67 | +CONFIG_PPC_ADV_DEBUG_IACS=4 | |
| 68 | +CONFIG_PPC_ADV_DEBUG_DACS=2 | |
| 69 | +CONFIG_PPC_ADV_DEBUG_DVCS=2 | |
| 70 | +CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y | |
| 71 | +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | |
| 72 | +CONFIG_CONSTRUCTORS=y | |
| 73 | + | |
| 74 | +# | |
| 75 | +# General setup | |
| 76 | +# | |
| 77 | +CONFIG_EXPERIMENTAL=y | |
| 78 | +CONFIG_BROKEN_ON_SMP=y | |
| 79 | +CONFIG_INIT_ENV_ARG_LIMIT=32 | |
| 80 | +CONFIG_LOCALVERSION="" | |
| 81 | +CONFIG_LOCALVERSION_AUTO=y | |
| 82 | +CONFIG_SWAP=y | |
| 83 | +CONFIG_SYSVIPC=y | |
| 84 | +CONFIG_SYSVIPC_SYSCTL=y | |
| 85 | +CONFIG_POSIX_MQUEUE=y | |
| 86 | +CONFIG_POSIX_MQUEUE_SYSCTL=y | |
| 87 | +# CONFIG_BSD_PROCESS_ACCT is not set | |
| 88 | +# CONFIG_TASKSTATS is not set | |
| 89 | +# CONFIG_AUDIT is not set | |
| 90 | + | |
| 91 | +# | |
| 92 | +# RCU Subsystem | |
| 93 | +# | |
| 94 | +CONFIG_TREE_RCU=y | |
| 95 | +# CONFIG_TREE_PREEMPT_RCU is not set | |
| 96 | +# CONFIG_TINY_RCU is not set | |
| 97 | +# CONFIG_RCU_TRACE is not set | |
| 98 | +CONFIG_RCU_FANOUT=32 | |
| 99 | +# CONFIG_RCU_FANOUT_EXACT is not set | |
| 100 | +# CONFIG_TREE_RCU_TRACE is not set | |
| 101 | +# CONFIG_IKCONFIG is not set | |
| 102 | +CONFIG_LOG_BUF_SHIFT=14 | |
| 103 | +# CONFIG_CGROUPS is not set | |
| 104 | +CONFIG_SYSFS_DEPRECATED=y | |
| 105 | +CONFIG_SYSFS_DEPRECATED_V2=y | |
| 106 | +# CONFIG_RELAY is not set | |
| 107 | +# CONFIG_NAMESPACES is not set | |
| 108 | +CONFIG_BLK_DEV_INITRD=y | |
| 109 | +CONFIG_INITRAMFS_SOURCE="" | |
| 110 | +CONFIG_RD_GZIP=y | |
| 111 | +# CONFIG_RD_BZIP2 is not set | |
| 112 | +# CONFIG_RD_LZMA is not set | |
| 113 | +# CONFIG_RD_LZO is not set | |
| 114 | +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | |
| 115 | +CONFIG_SYSCTL=y | |
| 116 | +CONFIG_ANON_INODES=y | |
| 117 | +CONFIG_EMBEDDED=y | |
| 118 | +CONFIG_SYSCTL_SYSCALL=y | |
| 119 | +CONFIG_KALLSYMS=y | |
| 120 | +# CONFIG_KALLSYMS_ALL is not set | |
| 121 | +# CONFIG_KALLSYMS_EXTRA_PASS is not set | |
| 122 | +CONFIG_HOTPLUG=y | |
| 123 | +CONFIG_PRINTK=y | |
| 124 | +# CONFIG_LOGBUFFER is not set | |
| 125 | +CONFIG_BUG=y | |
| 126 | +CONFIG_ELF_CORE=y | |
| 127 | +CONFIG_BASE_FULL=y | |
| 128 | +CONFIG_FUTEX=y | |
| 129 | +CONFIG_EPOLL=y | |
| 130 | +CONFIG_SIGNALFD=y | |
| 131 | +CONFIG_TIMERFD=y | |
| 132 | +CONFIG_EVENTFD=y | |
| 133 | +CONFIG_SHMEM=y | |
| 134 | +CONFIG_AIO=y | |
| 135 | +CONFIG_HAVE_PERF_EVENTS=y | |
| 136 | + | |
| 137 | +# | |
| 138 | +# Kernel Performance Events And Counters | |
| 139 | +# | |
| 140 | +# CONFIG_PERF_EVENTS is not set | |
| 141 | +# CONFIG_PERF_COUNTERS is not set | |
| 142 | +CONFIG_VM_EVENT_COUNTERS=y | |
| 143 | +CONFIG_PCI_QUIRKS=y | |
| 144 | +CONFIG_SLUB_DEBUG=y | |
| 145 | +CONFIG_COMPAT_BRK=y | |
| 146 | +# CONFIG_SLAB is not set | |
| 147 | +CONFIG_SLUB=y | |
| 148 | +# CONFIG_SLOB is not set | |
| 149 | +# CONFIG_PROFILING is not set | |
| 150 | +CONFIG_HAVE_OPROFILE=y | |
| 151 | +# CONFIG_KPROBES is not set | |
| 152 | +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y | |
| 153 | +CONFIG_HAVE_IOREMAP_PROT=y | |
| 154 | +CONFIG_HAVE_KPROBES=y | |
| 155 | +CONFIG_HAVE_KRETPROBES=y | |
| 156 | +CONFIG_HAVE_ARCH_TRACEHOOK=y | |
| 157 | +CONFIG_HAVE_DMA_ATTRS=y | |
| 158 | +CONFIG_HAVE_DMA_API_DEBUG=y | |
| 159 | + | |
| 160 | +# | |
| 161 | +# GCOV-based kernel profiling | |
| 162 | +# | |
| 163 | +# CONFIG_SLOW_WORK is not set | |
| 164 | +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | |
| 165 | +CONFIG_SLABINFO=y | |
| 166 | +CONFIG_RT_MUTEXES=y | |
| 167 | +CONFIG_BASE_SMALL=0 | |
| 168 | +CONFIG_MODULES=y | |
| 169 | +# CONFIG_MODULE_FORCE_LOAD is not set | |
| 170 | +CONFIG_MODULE_UNLOAD=y | |
| 171 | +# CONFIG_MODULE_FORCE_UNLOAD is not set | |
| 172 | +# CONFIG_MODVERSIONS is not set | |
| 173 | +# CONFIG_MODULE_SRCVERSION_ALL is not set | |
| 174 | +CONFIG_BLOCK=y | |
| 175 | +CONFIG_LBDAF=y | |
| 176 | +# CONFIG_BLK_DEV_BSG is not set | |
| 177 | +# CONFIG_BLK_DEV_INTEGRITY is not set | |
| 178 | + | |
| 179 | +# | |
| 180 | +# IO Schedulers | |
| 181 | +# | |
| 182 | +CONFIG_IOSCHED_NOOP=y | |
| 183 | +CONFIG_IOSCHED_DEADLINE=y | |
| 184 | +CONFIG_IOSCHED_CFQ=y | |
| 185 | +# CONFIG_DEFAULT_DEADLINE is not set | |
| 186 | +CONFIG_DEFAULT_CFQ=y | |
| 187 | +# CONFIG_DEFAULT_NOOP is not set | |
| 188 | +CONFIG_DEFAULT_IOSCHED="cfq" | |
| 189 | +# CONFIG_INLINE_SPIN_TRYLOCK is not set | |
| 190 | +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set | |
| 191 | +# CONFIG_INLINE_SPIN_LOCK is not set | |
| 192 | +# CONFIG_INLINE_SPIN_LOCK_BH is not set | |
| 193 | +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set | |
| 194 | +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set | |
| 195 | +CONFIG_INLINE_SPIN_UNLOCK=y | |
| 196 | +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set | |
| 197 | +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y | |
| 198 | +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set | |
| 199 | +# CONFIG_INLINE_READ_TRYLOCK is not set | |
| 200 | +# CONFIG_INLINE_READ_LOCK is not set | |
| 201 | +# CONFIG_INLINE_READ_LOCK_BH is not set | |
| 202 | +# CONFIG_INLINE_READ_LOCK_IRQ is not set | |
| 203 | +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set | |
| 204 | +CONFIG_INLINE_READ_UNLOCK=y | |
| 205 | +# CONFIG_INLINE_READ_UNLOCK_BH is not set | |
| 206 | +CONFIG_INLINE_READ_UNLOCK_IRQ=y | |
| 207 | +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set | |
| 208 | +# CONFIG_INLINE_WRITE_TRYLOCK is not set | |
| 209 | +# CONFIG_INLINE_WRITE_LOCK is not set | |
| 210 | +# CONFIG_INLINE_WRITE_LOCK_BH is not set | |
| 211 | +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set | |
| 212 | +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set | |
| 213 | +CONFIG_INLINE_WRITE_UNLOCK=y | |
| 214 | +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set | |
| 215 | +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y | |
| 216 | +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set | |
| 217 | +# CONFIG_MUTEX_SPIN_ON_OWNER is not set | |
| 218 | +# CONFIG_FREEZER is not set | |
| 219 | +CONFIG_PPC4xx_PCI_EXPRESS=y | |
| 220 | + | |
| 221 | +# | |
| 222 | +# Platform support | |
| 223 | +# | |
| 224 | +# CONFIG_PPC_CELL is not set | |
| 225 | +# CONFIG_PPC_CELL_NATIVE is not set | |
| 226 | +# CONFIG_PQ2ADS is not set | |
| 227 | +# CONFIG_BAMBOO is not set | |
| 228 | +# CONFIG_EBONY is not set | |
| 229 | +# CONFIG_SAM440EP is not set | |
| 230 | +# CONFIG_SEQUOIA is not set | |
| 231 | +# CONFIG_TAISHAN is not set | |
| 232 | +# CONFIG_KATMAI is not set | |
| 233 | +# CONFIG_RAINIER is not set | |
| 234 | +# CONFIG_WARP is not set | |
| 235 | +# CONFIG_ARCHES is not set | |
| 236 | +# CONFIG_CANYONLANDS is not set | |
| 237 | +# CONFIG_GLACIER is not set | |
| 238 | +# CONFIG_REDWOOD is not set | |
| 239 | +# CONFIG_EIGER is not set | |
| 240 | +# CONFIG_YOSEMITE is not set | |
| 241 | +CONFIG_ICON=y | |
| 242 | +# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set | |
| 243 | +CONFIG_PPC44x_SIMPLE=y | |
| 244 | +# CONFIG_PPC4xx_GPIO is not set | |
| 245 | +CONFIG_440SPe=y | |
| 246 | +CONFIG_STDBINUTILS=y | |
| 247 | +# CONFIG_IPIC is not set | |
| 248 | +# CONFIG_MPIC is not set | |
| 249 | +# CONFIG_MPIC_WEIRD is not set | |
| 250 | +# CONFIG_PPC_I8259 is not set | |
| 251 | +# CONFIG_PPC_RTAS is not set | |
| 252 | +# CONFIG_MMIO_NVRAM is not set | |
| 253 | +# CONFIG_PPC_MPC106 is not set | |
| 254 | +# CONFIG_PPC_970_NAP is not set | |
| 255 | +# CONFIG_PPC_INDIRECT_IO is not set | |
| 256 | +# CONFIG_GENERIC_IOMAP is not set | |
| 257 | +# CONFIG_CPU_FREQ is not set | |
| 258 | +# CONFIG_FSL_ULI1575 is not set | |
| 259 | +# CONFIG_SIMPLE_GPIO is not set | |
| 260 | + | |
| 261 | +# | |
| 262 | +# Kernel options | |
| 263 | +# | |
| 264 | +CONFIG_HIGHMEM=y | |
| 265 | +# CONFIG_NO_HZ is not set | |
| 266 | +# CONFIG_HIGH_RES_TIMERS is not set | |
| 267 | +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | |
| 268 | +# CONFIG_HZ_100 is not set | |
| 269 | +CONFIG_HZ_250=y | |
| 270 | +# CONFIG_HZ_300 is not set | |
| 271 | +# CONFIG_HZ_1000 is not set | |
| 272 | +CONFIG_HZ=250 | |
| 273 | +# CONFIG_SCHED_HRTICK is not set | |
| 274 | +CONFIG_PREEMPT_NONE=y | |
| 275 | +# CONFIG_PREEMPT_VOLUNTARY is not set | |
| 276 | +# CONFIG_PREEMPT is not set | |
| 277 | +CONFIG_BINFMT_ELF=y | |
| 278 | +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | |
| 279 | +# CONFIG_HAVE_AOUT is not set | |
| 280 | +# CONFIG_BINFMT_MISC is not set | |
| 281 | +# CONFIG_MATH_EMULATION is not set | |
| 282 | +# CONFIG_IOMMU_HELPER is not set | |
| 283 | +# CONFIG_SWIOTLB is not set | |
| 284 | +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y | |
| 285 | +CONFIG_ARCH_HAS_WALK_MEMORY=y | |
| 286 | +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y | |
| 287 | +CONFIG_SPARSE_IRQ=y | |
| 288 | +CONFIG_MAX_ACTIVE_REGIONS=32 | |
| 289 | +CONFIG_ARCH_FLATMEM_ENABLE=y | |
| 290 | +CONFIG_ARCH_POPULATES_NODE_MAP=y | |
| 291 | +CONFIG_SELECT_MEMORY_MODEL=y | |
| 292 | +CONFIG_FLATMEM_MANUAL=y | |
| 293 | +# CONFIG_DISCONTIGMEM_MANUAL is not set | |
| 294 | +# CONFIG_SPARSEMEM_MANUAL is not set | |
| 295 | +CONFIG_FLATMEM=y | |
| 296 | +CONFIG_FLAT_NODE_MEM_MAP=y | |
| 297 | +CONFIG_PAGEFLAGS_EXTENDED=y | |
| 298 | +CONFIG_SPLIT_PTLOCK_CPUS=4 | |
| 299 | +CONFIG_MIGRATION=y | |
| 300 | +CONFIG_PHYS_ADDR_T_64BIT=y | |
| 301 | +CONFIG_ZONE_DMA_FLAG=1 | |
| 302 | +CONFIG_BOUNCE=y | |
| 303 | +CONFIG_VIRT_TO_BUS=y | |
| 304 | +# CONFIG_KSM is not set | |
| 305 | +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | |
| 306 | +CONFIG_PPC_4K_PAGES=y | |
| 307 | +# CONFIG_PPC_16K_PAGES is not set | |
| 308 | +# CONFIG_PPC_64K_PAGES is not set | |
| 309 | +# CONFIG_PPC_256K_PAGES is not set | |
| 310 | +CONFIG_FORCE_MAX_ZONEORDER=11 | |
| 311 | +CONFIG_PROC_DEVICETREE=y | |
| 312 | +CONFIG_CMDLINE_BOOL=y | |
| 313 | +CONFIG_CMDLINE="" | |
| 314 | +CONFIG_EXTRA_TARGETS="" | |
| 315 | +# CONFIG_ARCH_HAS_NMI_WATCHDOG is not set | |
| 316 | +CONFIG_SECCOMP=y | |
| 317 | +CONFIG_ISA_DMA_API=y | |
| 318 | + | |
| 319 | +# | |
| 320 | +# Bus options | |
| 321 | +# | |
| 322 | +CONFIG_ZONE_DMA=y | |
| 323 | +CONFIG_NEED_DMA_MAP_STATE=y | |
| 324 | +CONFIG_PPC_INDIRECT_PCI=y | |
| 325 | +CONFIG_4xx_SOC=y | |
| 326 | +CONFIG_PPC_PCI_CHOICE=y | |
| 327 | +CONFIG_PCI=y | |
| 328 | +CONFIG_PCI_DOMAINS=y | |
| 329 | +CONFIG_PCI_SYSCALL=y | |
| 330 | +CONFIG_PCIEPORTBUS=y | |
| 331 | +CONFIG_PCIEAER=y | |
| 332 | +# CONFIG_PCIE_ECRC is not set | |
| 333 | +# CONFIG_PCIEAER_INJECT is not set | |
| 334 | +# CONFIG_PCIEASPM is not set | |
| 335 | +CONFIG_ARCH_SUPPORTS_MSI=y | |
| 336 | +# CONFIG_PCI_MSI is not set | |
| 337 | +# CONFIG_PCI_DEBUG is not set | |
| 338 | +# CONFIG_PCI_STUB is not set | |
| 339 | +# CONFIG_PCI_IOV is not set | |
| 340 | +# CONFIG_PCCARD is not set | |
| 341 | +# CONFIG_HOTPLUG_PCI is not set | |
| 342 | +# CONFIG_HAS_RAPIDIO is not set | |
| 343 | + | |
| 344 | +# | |
| 345 | +# Advanced setup | |
| 346 | +# | |
| 347 | +# CONFIG_ADVANCED_OPTIONS is not set | |
| 348 | + | |
| 349 | +# | |
| 350 | +# Default settings for advanced configuration options are used | |
| 351 | +# | |
| 352 | +CONFIG_LOWMEM_SIZE=0x30000000 | |
| 353 | +CONFIG_PAGE_OFFSET=0xc0000000 | |
| 354 | +CONFIG_KERNEL_START=0xc0000000 | |
| 355 | +CONFIG_PHYSICAL_START=0x00000000 | |
| 356 | +CONFIG_TASK_SIZE=0xc0000000 | |
| 357 | +CONFIG_CONSISTENT_SIZE=0x00200000 | |
| 358 | +CONFIG_NET=y | |
| 359 | + | |
| 360 | +# | |
| 361 | +# Networking options | |
| 362 | +# | |
| 363 | +CONFIG_PACKET=y | |
| 364 | +CONFIG_UNIX=y | |
| 365 | +# CONFIG_NET_KEY is not set | |
| 366 | +CONFIG_INET=y | |
| 367 | +# CONFIG_IP_MULTICAST is not set | |
| 368 | +# CONFIG_IP_ADVANCED_ROUTER is not set | |
| 369 | +CONFIG_IP_FIB_HASH=y | |
| 370 | +CONFIG_IP_PNP=y | |
| 371 | +CONFIG_IP_PNP_DHCP=y | |
| 372 | +CONFIG_IP_PNP_BOOTP=y | |
| 373 | +# CONFIG_IP_PNP_RARP is not set | |
| 374 | +# CONFIG_NET_IPIP is not set | |
| 375 | +# CONFIG_NET_IPGRE is not set | |
| 376 | +# CONFIG_ARPD is not set | |
| 377 | +# CONFIG_SYN_COOKIES is not set | |
| 378 | +# CONFIG_INET_AH is not set | |
| 379 | +# CONFIG_INET_ESP is not set | |
| 380 | +# CONFIG_INET_IPCOMP is not set | |
| 381 | +# CONFIG_INET_XFRM_TUNNEL is not set | |
| 382 | +# CONFIG_INET_TUNNEL is not set | |
| 383 | +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set | |
| 384 | +# CONFIG_INET_XFRM_MODE_TUNNEL is not set | |
| 385 | +# CONFIG_INET_XFRM_MODE_BEET is not set | |
| 386 | +# CONFIG_INET_LRO is not set | |
| 387 | +CONFIG_INET_DIAG=y | |
| 388 | +CONFIG_INET_TCP_DIAG=y | |
| 389 | +# CONFIG_TCP_CONG_ADVANCED is not set | |
| 390 | +CONFIG_TCP_CONG_CUBIC=y | |
| 391 | +CONFIG_DEFAULT_TCP_CONG="cubic" | |
| 392 | +# CONFIG_TCP_MD5SIG is not set | |
| 393 | +# CONFIG_IPV6 is not set | |
| 394 | +# CONFIG_NETWORK_SECMARK is not set | |
| 395 | +# CONFIG_NETFILTER is not set | |
| 396 | +# CONFIG_IP_DCCP is not set | |
| 397 | +# CONFIG_IP_SCTP is not set | |
| 398 | +# CONFIG_RDS is not set | |
| 399 | +# CONFIG_TIPC is not set | |
| 400 | +# CONFIG_ATM is not set | |
| 401 | +# CONFIG_BRIDGE is not set | |
| 402 | +# CONFIG_NET_DSA is not set | |
| 403 | +# CONFIG_VLAN_8021Q is not set | |
| 404 | +# CONFIG_DECNET is not set | |
| 405 | +# CONFIG_LLC2 is not set | |
| 406 | +# CONFIG_IPX is not set | |
| 407 | +# CONFIG_ATALK is not set | |
| 408 | +# CONFIG_X25 is not set | |
| 409 | +# CONFIG_LAPB is not set | |
| 410 | +# CONFIG_ECONET is not set | |
| 411 | +# CONFIG_WAN_ROUTER is not set | |
| 412 | +# CONFIG_PHONET is not set | |
| 413 | +# CONFIG_IEEE802154 is not set | |
| 414 | +# CONFIG_NET_SCHED is not set | |
| 415 | +# CONFIG_DCB is not set | |
| 416 | + | |
| 417 | +# | |
| 418 | +# Network testing | |
| 419 | +# | |
| 420 | +# CONFIG_NET_PKTGEN is not set | |
| 421 | +# CONFIG_HAMRADIO is not set | |
| 422 | +# CONFIG_CAN is not set | |
| 423 | +# CONFIG_IRDA is not set | |
| 424 | +# CONFIG_BT is not set | |
| 425 | +# CONFIG_AF_RXRPC is not set | |
| 426 | +CONFIG_WIRELESS=y | |
| 427 | +# CONFIG_CFG80211 is not set | |
| 428 | +# CONFIG_LIB80211 is not set | |
| 429 | + | |
| 430 | +# | |
| 431 | +# CFG80211 needs to be enabled for MAC80211 | |
| 432 | +# | |
| 433 | +# CONFIG_WIMAX is not set | |
| 434 | +# CONFIG_RFKILL is not set | |
| 435 | +# CONFIG_NET_9P is not set | |
| 436 | + | |
| 437 | +# | |
| 438 | +# Device Drivers | |
| 439 | +# | |
| 440 | + | |
| 441 | +# | |
| 442 | +# Generic Driver Options | |
| 443 | +# | |
| 444 | +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |
| 445 | +# CONFIG_DEVTMPFS is not set | |
| 446 | +CONFIG_STANDALONE=y | |
| 447 | +CONFIG_PREVENT_FIRMWARE_BUILD=y | |
| 448 | +CONFIG_FW_LOADER=y | |
| 449 | +CONFIG_FIRMWARE_IN_KERNEL=y | |
| 450 | +CONFIG_EXTRA_FIRMWARE="" | |
| 451 | +# CONFIG_DEBUG_DRIVER is not set | |
| 452 | +# CONFIG_DEBUG_DEVRES is not set | |
| 453 | +# CONFIG_SYS_HYPERVISOR is not set | |
| 454 | +CONFIG_CONNECTOR=y | |
| 455 | +CONFIG_PROC_EVENTS=y | |
| 456 | +CONFIG_MTD=y | |
| 457 | +# CONFIG_MTD_DEBUG is not set | |
| 458 | +# CONFIG_MTD_TESTS is not set | |
| 459 | +# CONFIG_MTD_CONCAT is not set | |
| 460 | +CONFIG_MTD_PARTITIONS=y | |
| 461 | +# CONFIG_MTD_REDBOOT_PARTS is not set | |
| 462 | +CONFIG_MTD_CMDLINE_PARTS=y | |
| 463 | +CONFIG_MTD_OF_PARTS=y | |
| 464 | +# CONFIG_MTD_AR7_PARTS is not set | |
| 465 | + | |
| 466 | +# | |
| 467 | +# User Modules And Translation Layers | |
| 468 | +# | |
| 469 | +CONFIG_MTD_CHAR=y | |
| 470 | +CONFIG_MTD_BLKDEVS=y | |
| 471 | +CONFIG_MTD_BLOCK=y | |
| 472 | +# CONFIG_FTL is not set | |
| 473 | +# CONFIG_NFTL is not set | |
| 474 | +# CONFIG_INFTL is not set | |
| 475 | +# CONFIG_RFD_FTL is not set | |
| 476 | +# CONFIG_SSFDC is not set | |
| 477 | +# CONFIG_MTD_OOPS is not set | |
| 478 | + | |
| 479 | +# | |
| 480 | +# RAM/ROM/Flash chip drivers | |
| 481 | +# | |
| 482 | +CONFIG_MTD_CFI=y | |
| 483 | +# CONFIG_MTD_JEDECPROBE is not set | |
| 484 | +CONFIG_MTD_GEN_PROBE=y | |
| 485 | +# CONFIG_MTD_CFI_ADV_OPTIONS is not set | |
| 486 | +CONFIG_MTD_MAP_BANK_WIDTH_1=y | |
| 487 | +CONFIG_MTD_MAP_BANK_WIDTH_2=y | |
| 488 | +CONFIG_MTD_MAP_BANK_WIDTH_4=y | |
| 489 | +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | |
| 490 | +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | |
| 491 | +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | |
| 492 | +CONFIG_MTD_CFI_I1=y | |
| 493 | +CONFIG_MTD_CFI_I2=y | |
| 494 | +# CONFIG_MTD_CFI_I4 is not set | |
| 495 | +# CONFIG_MTD_CFI_I8 is not set | |
| 496 | +# CONFIG_MTD_CFI_INTELEXT is not set | |
| 497 | +CONFIG_MTD_CFI_AMDSTD=y | |
| 498 | +# CONFIG_MTD_CFI_STAA is not set | |
| 499 | +CONFIG_MTD_CFI_UTIL=y | |
| 500 | +# CONFIG_MTD_RAM is not set | |
| 501 | +# CONFIG_MTD_ROM is not set | |
| 502 | +# CONFIG_MTD_ABSENT is not set | |
| 503 | + | |
| 504 | +# | |
| 505 | +# Mapping drivers for chip access | |
| 506 | +# | |
| 507 | +# CONFIG_MTD_COMPLEX_MAPPINGS is not set | |
| 508 | +# CONFIG_MTD_PHYSMAP is not set | |
| 509 | +CONFIG_MTD_PHYSMAP_OF=y | |
| 510 | +# CONFIG_MTD_INTEL_VR_NOR is not set | |
| 511 | +# CONFIG_MTD_PLATRAM is not set | |
| 512 | + | |
| 513 | +# | |
| 514 | +# Self-contained MTD device drivers | |
| 515 | +# | |
| 516 | +# CONFIG_MTD_PMC551 is not set | |
| 517 | +# CONFIG_MTD_SLRAM is not set | |
| 518 | +# CONFIG_MTD_PHRAM is not set | |
| 519 | +# CONFIG_MTD_MTDRAM is not set | |
| 520 | +# CONFIG_MTD_BLOCK2MTD is not set | |
| 521 | + | |
| 522 | +# | |
| 523 | +# Disk-On-Chip Device Drivers | |
| 524 | +# | |
| 525 | +# CONFIG_MTD_DOC2000 is not set | |
| 526 | +# CONFIG_MTD_DOC2001 is not set | |
| 527 | +# CONFIG_MTD_DOC2001PLUS is not set | |
| 528 | +# CONFIG_MTD_NAND is not set | |
| 529 | +# CONFIG_MTD_ONENAND is not set | |
| 530 | + | |
| 531 | +# | |
| 532 | +# LPDDR flash memory drivers | |
| 533 | +# | |
| 534 | +# CONFIG_MTD_LPDDR is not set | |
| 535 | + | |
| 536 | +# | |
| 537 | +# UBI - Unsorted block images | |
| 538 | +# | |
| 539 | +# CONFIG_MTD_UBI is not set | |
| 540 | +CONFIG_OF_FLATTREE=y | |
| 541 | +CONFIG_OF_DYNAMIC=y | |
| 542 | +CONFIG_OF_DEVICE=y | |
| 543 | +CONFIG_OF_I2C=y | |
| 544 | +# CONFIG_PARPORT is not set | |
| 545 | +CONFIG_BLK_DEV=y | |
| 546 | +# CONFIG_BLK_DEV_FD is not set | |
| 547 | +# CONFIG_BLK_CPQ_DA is not set | |
| 548 | +# CONFIG_BLK_CPQ_CISS_DA is not set | |
| 549 | +# CONFIG_BLK_DEV_DAC960 is not set | |
| 550 | +# CONFIG_BLK_DEV_UMEM is not set | |
| 551 | +# CONFIG_BLK_DEV_COW_COMMON is not set | |
| 552 | +# CONFIG_BLK_DEV_LOOP is not set | |
| 553 | +# CONFIG_BLK_DEV_DRBD is not set | |
| 554 | +# CONFIG_BLK_DEV_NBD is not set | |
| 555 | +# CONFIG_BLK_DEV_SX8 is not set | |
| 556 | +CONFIG_BLK_DEV_RAM=y | |
| 557 | +CONFIG_BLK_DEV_RAM_COUNT=16 | |
| 558 | +CONFIG_BLK_DEV_RAM_SIZE=35000 | |
| 559 | +# CONFIG_BLK_DEV_XIP is not set | |
| 560 | +# CONFIG_CDROM_PKTCDVD is not set | |
| 561 | +# CONFIG_ATA_OVER_ETH is not set | |
| 562 | +CONFIG_XILINX_SYSACE=y | |
| 563 | +# CONFIG_BLK_DEV_HD is not set | |
| 564 | +# CONFIG_MISC_DEVICES is not set | |
| 565 | +CONFIG_HAVE_IDE=y | |
| 566 | +# CONFIG_IDE is not set | |
| 567 | + | |
| 568 | +# | |
| 569 | +# SCSI device support | |
| 570 | +# | |
| 571 | +CONFIG_SCSI_MOD=y | |
| 572 | +# CONFIG_RAID_ATTRS is not set | |
| 573 | +CONFIG_SCSI=y | |
| 574 | +CONFIG_SCSI_DMA=y | |
| 575 | +# CONFIG_SCSI_TGT is not set | |
| 576 | +# CONFIG_SCSI_NETLINK is not set | |
| 577 | +CONFIG_SCSI_PROC_FS=y | |
| 578 | + | |
| 579 | +# | |
| 580 | +# SCSI support type (disk, tape, CD-ROM) | |
| 581 | +# | |
| 582 | +CONFIG_BLK_DEV_SD=y | |
| 583 | +# CONFIG_CHR_DEV_ST is not set | |
| 584 | +# CONFIG_CHR_DEV_OSST is not set | |
| 585 | +# CONFIG_BLK_DEV_SR is not set | |
| 586 | +# CONFIG_CHR_DEV_SG is not set | |
| 587 | +# CONFIG_CHR_DEV_SCH is not set | |
| 588 | +# CONFIG_SCSI_MULTI_LUN is not set | |
| 589 | +CONFIG_SCSI_CONSTANTS=y | |
| 590 | +CONFIG_SCSI_LOGGING=y | |
| 591 | +# CONFIG_SCSI_SCAN_ASYNC is not set | |
| 592 | +CONFIG_SCSI_WAIT_SCAN=m | |
| 593 | + | |
| 594 | +# | |
| 595 | +# SCSI Transports | |
| 596 | +# | |
| 597 | +# CONFIG_SCSI_SPI_ATTRS is not set | |
| 598 | +# CONFIG_SCSI_FC_ATTRS is not set | |
| 599 | +# CONFIG_SCSI_ISCSI_ATTRS is not set | |
| 600 | +CONFIG_SCSI_SAS_ATTRS=y | |
| 601 | +# CONFIG_SCSI_SAS_LIBSAS is not set | |
| 602 | +# CONFIG_SCSI_SRP_ATTRS is not set | |
| 603 | +# CONFIG_SCSI_LOWLEVEL is not set | |
| 604 | +# CONFIG_SCSI_DH is not set | |
| 605 | +# CONFIG_SCSI_OSD_INITIATOR is not set | |
| 606 | +# CONFIG_ATA is not set | |
| 607 | +# CONFIG_MD is not set | |
| 608 | +CONFIG_FUSION=y | |
| 609 | +# CONFIG_FUSION_SPI is not set | |
| 610 | +# CONFIG_FUSION_FC is not set | |
| 611 | +CONFIG_FUSION_SAS=y | |
| 612 | +CONFIG_FUSION_MAX_SGE=128 | |
| 613 | +CONFIG_FUSION_CTL=y | |
| 614 | +CONFIG_FUSION_LOGGING=y | |
| 615 | + | |
| 616 | +# | |
| 617 | +# IEEE 1394 (FireWire) support | |
| 618 | +# | |
| 619 | + | |
| 620 | +# | |
| 621 | +# You can enable one or both FireWire driver stacks. | |
| 622 | +# | |
| 623 | + | |
| 624 | +# | |
| 625 | +# The newer stack is recommended. | |
| 626 | +# | |
| 627 | +# CONFIG_FIREWIRE is not set | |
| 628 | +# CONFIG_IEEE1394 is not set | |
| 629 | +# CONFIG_I2O is not set | |
| 630 | +# CONFIG_MACINTOSH_DRIVERS is not set | |
| 631 | +CONFIG_NETDEVICES=y | |
| 632 | +# CONFIG_DUMMY is not set | |
| 633 | +# CONFIG_BONDING is not set | |
| 634 | +# CONFIG_MACVLAN is not set | |
| 635 | +# CONFIG_EQUALIZER is not set | |
| 636 | +# CONFIG_TUN is not set | |
| 637 | +# CONFIG_VETH is not set | |
| 638 | +# CONFIG_ARCNET is not set | |
| 639 | +# CONFIG_PHYLIB is not set | |
| 640 | +CONFIG_NET_ETHERNET=y | |
| 641 | +# CONFIG_MII is not set | |
| 642 | +# CONFIG_HAPPYMEAL is not set | |
| 643 | +# CONFIG_SUNGEM is not set | |
| 644 | +# CONFIG_CASSINI is not set | |
| 645 | +# CONFIG_NET_VENDOR_3COM is not set | |
| 646 | +# CONFIG_ETHOC is not set | |
| 647 | +# CONFIG_DNET is not set | |
| 648 | +# CONFIG_NET_TULIP is not set | |
| 649 | +# CONFIG_HP100 is not set | |
| 650 | +CONFIG_IBM_NEW_EMAC=y | |
| 651 | +CONFIG_IBM_NEW_EMAC_RXB=128 | |
| 652 | +CONFIG_IBM_NEW_EMAC_TXB=64 | |
| 653 | +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 | |
| 654 | +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 | |
| 655 | +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 | |
| 656 | +# CONFIG_IBM_NEW_EMAC_DEBUG is not set | |
| 657 | +# CONFIG_IBM_NEW_EMAC_ZMII is not set | |
| 658 | +# CONFIG_IBM_NEW_EMAC_RGMII is not set | |
| 659 | +# CONFIG_IBM_NEW_EMAC_TAH is not set | |
| 660 | +CONFIG_IBM_NEW_EMAC_EMAC4=y | |
| 661 | +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | |
| 662 | +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | |
| 663 | +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | |
| 664 | +# CONFIG_NET_PCI is not set | |
| 665 | +# CONFIG_B44 is not set | |
| 666 | +# CONFIG_KS8842 is not set | |
| 667 | +# CONFIG_KS8851_MLL is not set | |
| 668 | +# CONFIG_ATL2 is not set | |
| 669 | +# CONFIG_XILINX_EMACLITE is not set | |
| 670 | +# CONFIG_NETDEV_1000 is not set | |
| 671 | +# CONFIG_NETDEV_10000 is not set | |
| 672 | +# CONFIG_TR is not set | |
| 673 | +# CONFIG_WLAN is not set | |
| 674 | + | |
| 675 | +# | |
| 676 | +# Enable WiMAX (Networking options) to see the WiMAX drivers | |
| 677 | +# | |
| 678 | +# CONFIG_WAN is not set | |
| 679 | +# CONFIG_FDDI is not set | |
| 680 | +# CONFIG_HIPPI is not set | |
| 681 | +# CONFIG_PPP is not set | |
| 682 | +# CONFIG_SLIP is not set | |
| 683 | +# CONFIG_NET_FC is not set | |
| 684 | +# CONFIG_NETCONSOLE is not set | |
| 685 | +# CONFIG_NETPOLL is not set | |
| 686 | +# CONFIG_NET_POLL_CONTROLLER is not set | |
| 687 | +# CONFIG_VMXNET3 is not set | |
| 688 | +# CONFIG_ISDN is not set | |
| 689 | +# CONFIG_PHONE is not set | |
| 690 | + | |
| 691 | +# | |
| 692 | +# Input device support | |
| 693 | +# | |
| 694 | +CONFIG_INPUT=y | |
| 695 | +# CONFIG_INPUT_FF_MEMLESS is not set | |
| 696 | +# CONFIG_INPUT_POLLDEV is not set | |
| 697 | +# CONFIG_INPUT_SPARSEKMAP is not set | |
| 698 | + | |
| 699 | +# | |
| 700 | +# Userland interfaces | |
| 701 | +# | |
| 702 | +CONFIG_INPUT_MOUSEDEV=y | |
| 703 | +CONFIG_INPUT_MOUSEDEV_PSAUX=y | |
| 704 | +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 | |
| 705 | +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 | |
| 706 | +# CONFIG_INPUT_JOYDEV is not set | |
| 707 | +# CONFIG_INPUT_EVDEV is not set | |
| 708 | +# CONFIG_INPUT_EVBUG is not set | |
| 709 | + | |
| 710 | +# | |
| 711 | +# Input Device Drivers | |
| 712 | +# | |
| 713 | +CONFIG_INPUT_KEYBOARD=y | |
| 714 | +# CONFIG_KEYBOARD_ADP5588 is not set | |
| 715 | +CONFIG_KEYBOARD_ATKBD=y | |
| 716 | +# CONFIG_QT2160 is not set | |
| 717 | +# CONFIG_KEYBOARD_LKKBD is not set | |
| 718 | +# CONFIG_KEYBOARD_MAX7359 is not set | |
| 719 | +# CONFIG_KEYBOARD_NEWTON is not set | |
| 720 | +# CONFIG_KEYBOARD_OPENCORES is not set | |
| 721 | +# CONFIG_KEYBOARD_STOWAWAY is not set | |
| 722 | +# CONFIG_KEYBOARD_SUNKBD is not set | |
| 723 | +# CONFIG_KEYBOARD_XTKBD is not set | |
| 724 | +CONFIG_INPUT_MOUSE=y | |
| 725 | +CONFIG_MOUSE_PS2=y | |
| 726 | +# CONFIG_MOUSE_PS2_ALPS is not set | |
| 727 | +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set | |
| 728 | +# CONFIG_MOUSE_PS2_SYNAPTICS is not set | |
| 729 | +# CONFIG_MOUSE_PS2_TRACKPOINT is not set | |
| 730 | +# CONFIG_MOUSE_PS2_ELANTECH is not set | |
| 731 | +# CONFIG_MOUSE_PS2_SENTELIC is not set | |
| 732 | +# CONFIG_MOUSE_PS2_TOUCHKIT is not set | |
| 733 | +# CONFIG_MOUSE_SERIAL is not set | |
| 734 | +# CONFIG_MOUSE_VSXXXAA is not set | |
| 735 | +# CONFIG_MOUSE_SYNAPTICS_I2C is not set | |
| 736 | +# CONFIG_INPUT_JOYSTICK is not set | |
| 737 | +# CONFIG_INPUT_TABLET is not set | |
| 738 | +# CONFIG_INPUT_TOUCHSCREEN is not set | |
| 739 | +# CONFIG_INPUT_MISC is not set | |
| 740 | + | |
| 741 | +# | |
| 742 | +# Hardware I/O ports | |
| 743 | +# | |
| 744 | +CONFIG_SERIO=y | |
| 745 | +CONFIG_SERIO_I8042=y | |
| 746 | +CONFIG_SERIO_SERPORT=y | |
| 747 | +# CONFIG_SERIO_PCIPS2 is not set | |
| 748 | +CONFIG_SERIO_LIBPS2=y | |
| 749 | +# CONFIG_SERIO_RAW is not set | |
| 750 | +# CONFIG_SERIO_XILINX_XPS_PS2 is not set | |
| 751 | +# CONFIG_SERIO_ALTERA_PS2 is not set | |
| 752 | +# CONFIG_GAMEPORT is not set | |
| 753 | + | |
| 754 | +# | |
| 755 | +# Character devices | |
| 756 | +# | |
| 757 | +CONFIG_VT=y | |
| 758 | +CONFIG_CONSOLE_TRANSLATIONS=y | |
| 759 | +CONFIG_VT_CONSOLE=y | |
| 760 | +CONFIG_HW_CONSOLE=y | |
| 761 | +# CONFIG_VT_HW_CONSOLE_BINDING is not set | |
| 762 | +CONFIG_DEVKMEM=y | |
| 763 | +# CONFIG_SERIAL_NONSTANDARD is not set | |
| 764 | +# CONFIG_NOZOMI is not set | |
| 765 | + | |
| 766 | +# | |
| 767 | +# Serial drivers | |
| 768 | +# | |
| 769 | +CONFIG_SERIAL_8250=y | |
| 770 | +CONFIG_SERIAL_8250_CONSOLE=y | |
| 771 | +# CONFIG_SERIAL_8250_PCI is not set | |
| 772 | +CONFIG_SERIAL_8250_NR_UARTS=4 | |
| 773 | +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | |
| 774 | +CONFIG_SERIAL_8250_EXTENDED=y | |
| 775 | +# CONFIG_SERIAL_8250_MANY_PORTS is not set | |
| 776 | +CONFIG_SERIAL_8250_SHARE_IRQ=y | |
| 777 | +# CONFIG_SERIAL_8250_DETECT_IRQ is not set | |
| 778 | +# CONFIG_SERIAL_8250_RSA is not set | |
| 779 | + | |
| 780 | +# | |
| 781 | +# Non-8250 serial port support | |
| 782 | +# | |
| 783 | +# CONFIG_SERIAL_UARTLITE is not set | |
| 784 | +CONFIG_SERIAL_CORE=y | |
| 785 | +CONFIG_SERIAL_CORE_CONSOLE=y | |
| 786 | +# CONFIG_SERIAL_JSM is not set | |
| 787 | +CONFIG_SERIAL_OF_PLATFORM=y | |
| 788 | +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set | |
| 789 | +# CONFIG_SERIAL_TIMBERDALE is not set | |
| 790 | +# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set | |
| 791 | +CONFIG_UNIX98_PTYS=y | |
| 792 | +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | |
| 793 | +CONFIG_LEGACY_PTYS=y | |
| 794 | +CONFIG_LEGACY_PTY_COUNT=256 | |
| 795 | +# CONFIG_HVC_UDBG is not set | |
| 796 | +# CONFIG_IPMI_HANDLER is not set | |
| 797 | +# CONFIG_HW_RANDOM is not set | |
| 798 | +# CONFIG_NVRAM is not set | |
| 799 | +# CONFIG_R3964 is not set | |
| 800 | +# CONFIG_APPLICOM is not set | |
| 801 | +# CONFIG_RAW_DRIVER is not set | |
| 802 | +# CONFIG_BOOTCOUNT is not set | |
| 803 | +# CONFIG_DISPLAY_PDSP1880 is not set | |
| 804 | +# CONFIG_MUCMC52_IO is not set | |
| 805 | +# CONFIG_UC101_IO is not set | |
| 806 | +# CONFIG_SRAM is not set | |
| 807 | +# CONFIG_TCG_TPM is not set | |
| 808 | +CONFIG_DEVPORT=y | |
| 809 | +CONFIG_I2C=y | |
| 810 | +CONFIG_I2C_BOARDINFO=y | |
| 811 | +CONFIG_I2C_COMPAT=y | |
| 812 | +CONFIG_I2C_CHARDEV=y | |
| 813 | +CONFIG_I2C_HELPER_AUTO=y | |
| 814 | + | |
| 815 | +# | |
| 816 | +# I2C Hardware Bus support | |
| 817 | +# | |
| 818 | + | |
| 819 | +# | |
| 820 | +# PC SMBus host controller drivers | |
| 821 | +# | |
| 822 | +# CONFIG_I2C_ALI1535 is not set | |
| 823 | +# CONFIG_I2C_ALI1563 is not set | |
| 824 | +# CONFIG_I2C_ALI15X3 is not set | |
| 825 | +# CONFIG_I2C_AMD756 is not set | |
| 826 | +# CONFIG_I2C_AMD8111 is not set | |
| 827 | +# CONFIG_I2C_I801 is not set | |
| 828 | +# CONFIG_I2C_ISCH is not set | |
| 829 | +# CONFIG_I2C_PIIX4 is not set | |
| 830 | +# CONFIG_I2C_NFORCE2 is not set | |
| 831 | +# CONFIG_I2C_SIS5595 is not set | |
| 832 | +# CONFIG_I2C_SIS630 is not set | |
| 833 | +# CONFIG_I2C_SIS96X is not set | |
| 834 | +# CONFIG_I2C_VIA is not set | |
| 835 | +# CONFIG_I2C_VIAPRO is not set | |
| 836 | + | |
| 837 | +# | |
| 838 | +# I2C system bus drivers (mostly embedded / system-on-chip) | |
| 839 | +# | |
| 840 | +CONFIG_I2C_IBM_IIC=y | |
| 841 | +# CONFIG_I2C_MPC is not set | |
| 842 | +# CONFIG_I2C_OCORES is not set | |
| 843 | +# CONFIG_I2C_SIMTEC is not set | |
| 844 | +# CONFIG_I2C_XILINX is not set | |
| 845 | + | |
| 846 | +# | |
| 847 | +# External I2C/SMBus adapter drivers | |
| 848 | +# | |
| 849 | +# CONFIG_I2C_PARPORT_LIGHT is not set | |
| 850 | +# CONFIG_I2C_TAOS_EVM is not set | |
| 851 | + | |
| 852 | +# | |
| 853 | +# Other I2C/SMBus bus drivers | |
| 854 | +# | |
| 855 | +# CONFIG_I2C_PCA_PLATFORM is not set | |
| 856 | +# CONFIG_I2C_STUB is not set | |
| 857 | +# CONFIG_I2C_DEBUG_CORE is not set | |
| 858 | +# CONFIG_I2C_DEBUG_ALGO is not set | |
| 859 | +# CONFIG_I2C_DEBUG_BUS is not set | |
| 860 | +# CONFIG_SPI is not set | |
| 861 | + | |
| 862 | +# | |
| 863 | +# PPS support | |
| 864 | +# | |
| 865 | +# CONFIG_PPS is not set | |
| 866 | +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y | |
| 867 | +# CONFIG_GPIOLIB is not set | |
| 868 | +# CONFIG_W1 is not set | |
| 869 | +# CONFIG_POWER_SUPPLY is not set | |
| 870 | +# CONFIG_HWMON is not set | |
| 871 | +# CONFIG_THERMAL is not set | |
| 872 | +# CONFIG_WATCHDOG is not set | |
| 873 | +CONFIG_SSB_POSSIBLE=y | |
| 874 | + | |
| 875 | +# | |
| 876 | +# Sonics Silicon Backplane | |
| 877 | +# | |
| 878 | +# CONFIG_SSB is not set | |
| 879 | + | |
| 880 | +# | |
| 881 | +# Multifunction device drivers | |
| 882 | +# | |
| 883 | +# CONFIG_MFD_CORE is not set | |
| 884 | +# CONFIG_MFD_88PM860X is not set | |
| 885 | +CONFIG_MFD_SM501=y | |
| 886 | +# CONFIG_HTC_PASIC3 is not set | |
| 887 | +# CONFIG_TWL4030_CORE is not set | |
| 888 | +# CONFIG_MFD_TMIO is not set | |
| 889 | +# CONFIG_PMIC_DA903X is not set | |
| 890 | +# CONFIG_PMIC_ADP5520 is not set | |
| 891 | +# CONFIG_MFD_MAX8925 is not set | |
| 892 | +# CONFIG_MFD_WM8400 is not set | |
| 893 | +# CONFIG_MFD_WM831X is not set | |
| 894 | +# CONFIG_MFD_WM8350_I2C is not set | |
| 895 | +# CONFIG_MFD_WM8994 is not set | |
| 896 | +# CONFIG_MFD_PCF50633 is not set | |
| 897 | +# CONFIG_AB3100_CORE is not set | |
| 898 | +# CONFIG_LPC_SCH is not set | |
| 899 | +# CONFIG_REGULATOR is not set | |
| 900 | +# CONFIG_MEDIA_SUPPORT is not set | |
| 901 | + | |
| 902 | +# | |
| 903 | +# Graphics support | |
| 904 | +# | |
| 905 | +# CONFIG_AGP is not set | |
| 906 | +CONFIG_VGA_ARB=y | |
| 907 | +CONFIG_VGA_ARB_MAX_GPUS=16 | |
| 908 | +# CONFIG_DRM is not set | |
| 909 | +# CONFIG_VGASTATE is not set | |
| 910 | +CONFIG_VIDEO_OUTPUT_CONTROL=m | |
| 911 | +CONFIG_FB=y | |
| 912 | +# CONFIG_FIRMWARE_EDID is not set | |
| 913 | +# CONFIG_FB_DDC is not set | |
| 914 | +# CONFIG_FB_BOOT_VESA_SUPPORT is not set | |
| 915 | +CONFIG_FB_CFB_FILLRECT=y | |
| 916 | +CONFIG_FB_CFB_COPYAREA=y | |
| 917 | +CONFIG_FB_CFB_IMAGEBLIT=y | |
| 918 | +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set | |
| 919 | +# CONFIG_FB_SYS_FILLRECT is not set | |
| 920 | +# CONFIG_FB_SYS_COPYAREA is not set | |
| 921 | +# CONFIG_FB_SYS_IMAGEBLIT is not set | |
| 922 | +# CONFIG_FB_FOREIGN_ENDIAN is not set | |
| 923 | +# CONFIG_FB_SYS_FOPS is not set | |
| 924 | +# CONFIG_FB_SVGALIB is not set | |
| 925 | +# CONFIG_FB_MACMODES is not set | |
| 926 | +# CONFIG_FB_BACKLIGHT is not set | |
| 927 | +# CONFIG_FB_MODE_HELPERS is not set | |
| 928 | +# CONFIG_FB_TILEBLITTING is not set | |
| 929 | + | |
| 930 | +# | |
| 931 | +# Frame buffer hardware drivers | |
| 932 | +# | |
| 933 | +# CONFIG_FB_CIRRUS is not set | |
| 934 | +# CONFIG_FB_PM2 is not set | |
| 935 | +# CONFIG_FB_CYBER2000 is not set | |
| 936 | +# CONFIG_FB_OF is not set | |
| 937 | +# CONFIG_FB_CT65550 is not set | |
| 938 | +# CONFIG_FB_ASILIANT is not set | |
| 939 | +# CONFIG_FB_IMSTT is not set | |
| 940 | +# CONFIG_FB_VGA16 is not set | |
| 941 | +# CONFIG_FB_UVESA is not set | |
| 942 | +# CONFIG_FB_S1D13XXX is not set | |
| 943 | +# CONFIG_FB_NVIDIA is not set | |
| 944 | +# CONFIG_FB_RIVA is not set | |
| 945 | +# CONFIG_FB_MATROX is not set | |
| 946 | +# CONFIG_FB_RADEON is not set | |
| 947 | +# CONFIG_FB_ATY128 is not set | |
| 948 | +# CONFIG_FB_ATY is not set | |
| 949 | +# CONFIG_FB_S3 is not set | |
| 950 | +# CONFIG_FB_SAVAGE is not set | |
| 951 | +# CONFIG_FB_SIS is not set | |
| 952 | +# CONFIG_FB_VIA is not set | |
| 953 | +# CONFIG_FB_NEOMAGIC is not set | |
| 954 | +# CONFIG_FB_KYRO is not set | |
| 955 | +# CONFIG_FB_3DFX is not set | |
| 956 | +# CONFIG_FB_VOODOO1 is not set | |
| 957 | +# CONFIG_FB_VT8623 is not set | |
| 958 | +# CONFIG_FB_TRIDENT is not set | |
| 959 | +# CONFIG_FB_ARK is not set | |
| 960 | +# CONFIG_FB_PM3 is not set | |
| 961 | +# CONFIG_FB_CARMINE is not set | |
| 962 | +CONFIG_FB_SM501=y | |
| 963 | +# CONFIG_FB_IBM_GXT4500 is not set | |
| 964 | +# CONFIG_FB_VIRTUAL is not set | |
| 965 | +# CONFIG_FB_METRONOME is not set | |
| 966 | +# CONFIG_FB_MB862XX is not set | |
| 967 | +# CONFIG_FB_BROADSHEET is not set | |
| 968 | +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set | |
| 969 | + | |
| 970 | +# | |
| 971 | +# Display device support | |
| 972 | +# | |
| 973 | +# CONFIG_DISPLAY_SUPPORT is not set | |
| 974 | + | |
| 975 | +# | |
| 976 | +# Console display driver support | |
| 977 | +# | |
| 978 | +CONFIG_DUMMY_CONSOLE=y | |
| 979 | +CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 980 | +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set | |
| 981 | +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | |
| 982 | +# CONFIG_FONTS is not set | |
| 983 | +CONFIG_FONT_8x8=y | |
| 984 | +CONFIG_FONT_8x16=y | |
| 985 | +CONFIG_LOGO=y | |
| 986 | +# CONFIG_LOGO_LINUX_MONO is not set | |
| 987 | +# CONFIG_LOGO_LINUX_VGA16 is not set | |
| 988 | +CONFIG_LOGO_LINUX_CLUT224=y | |
| 989 | +# CONFIG_SOUND is not set | |
| 990 | +CONFIG_HID_SUPPORT=y | |
| 991 | +CONFIG_HID=y | |
| 992 | +# CONFIG_HIDRAW is not set | |
| 993 | +# CONFIG_HID_PID is not set | |
| 994 | + | |
| 995 | +# | |
| 996 | +# Special HID drivers | |
| 997 | +# | |
| 998 | +# CONFIG_USB_SUPPORT is not set | |
| 999 | +# CONFIG_UWB is not set | |
| 1000 | +# CONFIG_MMC is not set | |
| 1001 | +# CONFIG_MEMSTICK is not set | |
| 1002 | +# CONFIG_NEW_LEDS is not set | |
| 1003 | +# CONFIG_ACCESSIBILITY is not set | |
| 1004 | +# CONFIG_INFINIBAND is not set | |
| 1005 | +# CONFIG_EDAC is not set | |
| 1006 | +CONFIG_RTC_LIB=y | |
| 1007 | +CONFIG_RTC_CLASS=y | |
| 1008 | +CONFIG_RTC_HCTOSYS=y | |
| 1009 | +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | |
| 1010 | +# CONFIG_RTC_DEBUG is not set | |
| 1011 | + | |
| 1012 | +# | |
| 1013 | +# RTC interfaces | |
| 1014 | +# | |
| 1015 | +CONFIG_RTC_INTF_SYSFS=y | |
| 1016 | +CONFIG_RTC_INTF_PROC=y | |
| 1017 | +CONFIG_RTC_INTF_DEV=y | |
| 1018 | +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | |
| 1019 | +# CONFIG_RTC_DRV_TEST is not set | |
| 1020 | + | |
| 1021 | +# | |
| 1022 | +# I2C RTC drivers | |
| 1023 | +# | |
| 1024 | +CONFIG_RTC_DRV_DS1307=y | |
| 1025 | +# CONFIG_RTC_DRV_DS1374 is not set | |
| 1026 | +# CONFIG_RTC_DRV_DS1672 is not set | |
| 1027 | +# CONFIG_RTC_DRV_MAX6900 is not set | |
| 1028 | +# CONFIG_RTC_DRV_RS5C372 is not set | |
| 1029 | +# CONFIG_RTC_DRV_ISL1208 is not set | |
| 1030 | +# CONFIG_RTC_DRV_X1205 is not set | |
| 1031 | +# CONFIG_RTC_DRV_PCF8563 is not set | |
| 1032 | +# CONFIG_RTC_DRV_PCF8583 is not set | |
| 1033 | +# CONFIG_RTC_DRV_M41T80 is not set | |
| 1034 | +# CONFIG_RTC_DRV_BQ32K is not set | |
| 1035 | +# CONFIG_RTC_DRV_S35390A is not set | |
| 1036 | +# CONFIG_RTC_DRV_FM3130 is not set | |
| 1037 | +# CONFIG_RTC_DRV_RX8581 is not set | |
| 1038 | +# CONFIG_RTC_DRV_RX8025 is not set | |
| 1039 | + | |
| 1040 | +# | |
| 1041 | +# SPI RTC drivers | |
| 1042 | +# | |
| 1043 | + | |
| 1044 | +# | |
| 1045 | +# Platform RTC drivers | |
| 1046 | +# | |
| 1047 | +# CONFIG_RTC_DRV_CMOS is not set | |
| 1048 | +# CONFIG_RTC_DRV_DS1286 is not set | |
| 1049 | +# CONFIG_RTC_DRV_DS1511 is not set | |
| 1050 | +# CONFIG_RTC_DRV_DS1553 is not set | |
| 1051 | +# CONFIG_RTC_DRV_DS1742 is not set | |
| 1052 | +# CONFIG_RTC_DRV_STK17TA8 is not set | |
| 1053 | +# CONFIG_RTC_DRV_M48T86 is not set | |
| 1054 | +# CONFIG_RTC_DRV_M48T35 is not set | |
| 1055 | +# CONFIG_RTC_DRV_M48T59 is not set | |
| 1056 | +# CONFIG_RTC_DRV_MSM6242 is not set | |
| 1057 | +# CONFIG_RTC_DRV_BQ4802 is not set | |
| 1058 | +# CONFIG_RTC_DRV_RP5C01 is not set | |
| 1059 | +# CONFIG_RTC_DRV_V3020 is not set | |
| 1060 | + | |
| 1061 | +# | |
| 1062 | +# on-CPU RTC drivers | |
| 1063 | +# | |
| 1064 | +# CONFIG_RTC_DRV_GENERIC is not set | |
| 1065 | +# CONFIG_DMADEVICES is not set | |
| 1066 | +# CONFIG_AUXDISPLAY is not set | |
| 1067 | +# CONFIG_UIO is not set | |
| 1068 | + | |
| 1069 | +# | |
| 1070 | +# TI VLYNQ | |
| 1071 | +# | |
| 1072 | +# CONFIG_STAGING is not set | |
| 1073 | + | |
| 1074 | +# | |
| 1075 | +# File systems | |
| 1076 | +# | |
| 1077 | +CONFIG_EXT2_FS=y | |
| 1078 | +# CONFIG_EXT2_FS_XATTR is not set | |
| 1079 | +# CONFIG_EXT2_FS_XIP is not set | |
| 1080 | +CONFIG_EXT3_FS=y | |
| 1081 | +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | |
| 1082 | +CONFIG_EXT3_FS_XATTR=y | |
| 1083 | +# CONFIG_EXT3_FS_POSIX_ACL is not set | |
| 1084 | +# CONFIG_EXT3_FS_SECURITY is not set | |
| 1085 | +# CONFIG_EXT4_FS is not set | |
| 1086 | +CONFIG_JBD=y | |
| 1087 | +CONFIG_FS_MBCACHE=y | |
| 1088 | +# CONFIG_REISERFS_FS is not set | |
| 1089 | +# CONFIG_JFS_FS is not set | |
| 1090 | +# CONFIG_FS_POSIX_ACL is not set | |
| 1091 | +# CONFIG_XFS_FS is not set | |
| 1092 | +# CONFIG_GFS2_FS is not set | |
| 1093 | +# CONFIG_OCFS2_FS is not set | |
| 1094 | +# CONFIG_BTRFS_FS is not set | |
| 1095 | +# CONFIG_NILFS2_FS is not set | |
| 1096 | +CONFIG_FILE_LOCKING=y | |
| 1097 | +CONFIG_FSNOTIFY=y | |
| 1098 | +CONFIG_DNOTIFY=y | |
| 1099 | +CONFIG_INOTIFY=y | |
| 1100 | +CONFIG_INOTIFY_USER=y | |
| 1101 | +# CONFIG_QUOTA is not set | |
| 1102 | +# CONFIG_AUTOFS_FS is not set | |
| 1103 | +# CONFIG_AUTOFS4_FS is not set | |
| 1104 | +# CONFIG_FUSE_FS is not set | |
| 1105 | + | |
| 1106 | +# | |
| 1107 | +# Caches | |
| 1108 | +# | |
| 1109 | +# CONFIG_FSCACHE is not set | |
| 1110 | + | |
| 1111 | +# | |
| 1112 | +# CD-ROM/DVD Filesystems | |
| 1113 | +# | |
| 1114 | +# CONFIG_ISO9660_FS is not set | |
| 1115 | +# CONFIG_UDF_FS is not set | |
| 1116 | + | |
| 1117 | +# | |
| 1118 | +# DOS/FAT/NT Filesystems | |
| 1119 | +# | |
| 1120 | +CONFIG_FAT_FS=y | |
| 1121 | +# CONFIG_MSDOS_FS is not set | |
| 1122 | +CONFIG_VFAT_FS=y | |
| 1123 | +CONFIG_FAT_DEFAULT_CODEPAGE=437 | |
| 1124 | +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | |
| 1125 | +# CONFIG_NTFS_FS is not set | |
| 1126 | + | |
| 1127 | +# | |
| 1128 | +# Pseudo filesystems | |
| 1129 | +# | |
| 1130 | +CONFIG_PROC_FS=y | |
| 1131 | +CONFIG_PROC_KCORE=y | |
| 1132 | +CONFIG_PROC_SYSCTL=y | |
| 1133 | +CONFIG_PROC_PAGE_MONITOR=y | |
| 1134 | +CONFIG_SYSFS=y | |
| 1135 | +CONFIG_TMPFS=y | |
| 1136 | +# CONFIG_TMPFS_POSIX_ACL is not set | |
| 1137 | +# CONFIG_HUGETLB_PAGE is not set | |
| 1138 | +# CONFIG_CONFIGFS_FS is not set | |
| 1139 | +CONFIG_MISC_FILESYSTEMS=y | |
| 1140 | +# CONFIG_ADFS_FS is not set | |
| 1141 | +# CONFIG_AFFS_FS is not set | |
| 1142 | +# CONFIG_HFS_FS is not set | |
| 1143 | +# CONFIG_HFSPLUS_FS is not set | |
| 1144 | +# CONFIG_BEFS_FS is not set | |
| 1145 | +# CONFIG_BFS_FS is not set | |
| 1146 | +# CONFIG_EFS_FS is not set | |
| 1147 | +# CONFIG_JFFS2_FS is not set | |
| 1148 | +# CONFIG_YAFFS_FS is not set | |
| 1149 | +# CONFIG_LOGFS is not set | |
| 1150 | +CONFIG_CRAMFS=y | |
| 1151 | +# CONFIG_SQUASHFS is not set | |
| 1152 | +# CONFIG_VXFS_FS is not set | |
| 1153 | +# CONFIG_MINIX_FS is not set | |
| 1154 | +# CONFIG_OMFS_FS is not set | |
| 1155 | +# CONFIG_HPFS_FS is not set | |
| 1156 | +# CONFIG_QNX4FS_FS is not set | |
| 1157 | +# CONFIG_ROMFS_FS is not set | |
| 1158 | +# CONFIG_SYSV_FS is not set | |
| 1159 | +# CONFIG_UFS_FS is not set | |
| 1160 | +CONFIG_NETWORK_FILESYSTEMS=y | |
| 1161 | +CONFIG_NFS_FS=y | |
| 1162 | +CONFIG_NFS_V3=y | |
| 1163 | +# CONFIG_NFS_V3_ACL is not set | |
| 1164 | +# CONFIG_NFS_V4 is not set | |
| 1165 | +CONFIG_ROOT_NFS=y | |
| 1166 | +# CONFIG_NFSD is not set | |
| 1167 | +CONFIG_LOCKD=y | |
| 1168 | +CONFIG_LOCKD_V4=y | |
| 1169 | +CONFIG_NFS_COMMON=y | |
| 1170 | +CONFIG_SUNRPC=y | |
| 1171 | +# CONFIG_RPCSEC_GSS_KRB5 is not set | |
| 1172 | +# CONFIG_RPCSEC_GSS_SPKM3 is not set | |
| 1173 | +# CONFIG_SMB_FS is not set | |
| 1174 | +# CONFIG_CEPH_FS is not set | |
| 1175 | +# CONFIG_CIFS is not set | |
| 1176 | +# CONFIG_NCP_FS is not set | |
| 1177 | +# CONFIG_CODA_FS is not set | |
| 1178 | +# CONFIG_AFS_FS is not set | |
| 1179 | + | |
| 1180 | +# | |
| 1181 | +# Partition Types | |
| 1182 | +# | |
| 1183 | +# CONFIG_PARTITION_ADVANCED is not set | |
| 1184 | +CONFIG_MSDOS_PARTITION=y | |
| 1185 | +CONFIG_NLS=y | |
| 1186 | +CONFIG_NLS_DEFAULT="iso8859-1" | |
| 1187 | +CONFIG_NLS_CODEPAGE_437=y | |
| 1188 | +# CONFIG_NLS_CODEPAGE_737 is not set | |
| 1189 | +# CONFIG_NLS_CODEPAGE_775 is not set | |
| 1190 | +CONFIG_NLS_CODEPAGE_850=y | |
| 1191 | +# CONFIG_NLS_CODEPAGE_852 is not set | |
| 1192 | +# CONFIG_NLS_CODEPAGE_855 is not set | |
| 1193 | +# CONFIG_NLS_CODEPAGE_857 is not set | |
| 1194 | +# CONFIG_NLS_CODEPAGE_860 is not set | |
| 1195 | +# CONFIG_NLS_CODEPAGE_861 is not set | |
| 1196 | +# CONFIG_NLS_CODEPAGE_862 is not set | |
| 1197 | +# CONFIG_NLS_CODEPAGE_863 is not set | |
| 1198 | +# CONFIG_NLS_CODEPAGE_864 is not set | |
| 1199 | +# CONFIG_NLS_CODEPAGE_865 is not set | |
| 1200 | +# CONFIG_NLS_CODEPAGE_866 is not set | |
| 1201 | +# CONFIG_NLS_CODEPAGE_869 is not set | |
| 1202 | +# CONFIG_NLS_CODEPAGE_936 is not set | |
| 1203 | +# CONFIG_NLS_CODEPAGE_950 is not set | |
| 1204 | +# CONFIG_NLS_CODEPAGE_932 is not set | |
| 1205 | +# CONFIG_NLS_CODEPAGE_949 is not set | |
| 1206 | +# CONFIG_NLS_CODEPAGE_874 is not set | |
| 1207 | +# CONFIG_NLS_ISO8859_8 is not set | |
| 1208 | +# CONFIG_NLS_CODEPAGE_1250 is not set | |
| 1209 | +# CONFIG_NLS_CODEPAGE_1251 is not set | |
| 1210 | +# CONFIG_NLS_ASCII is not set | |
| 1211 | +CONFIG_NLS_ISO8859_1=y | |
| 1212 | +# CONFIG_NLS_ISO8859_2 is not set | |
| 1213 | +# CONFIG_NLS_ISO8859_3 is not set | |
| 1214 | +# CONFIG_NLS_ISO8859_4 is not set | |
| 1215 | +# CONFIG_NLS_ISO8859_5 is not set | |
| 1216 | +# CONFIG_NLS_ISO8859_6 is not set | |
| 1217 | +# CONFIG_NLS_ISO8859_7 is not set | |
| 1218 | +# CONFIG_NLS_ISO8859_9 is not set | |
| 1219 | +# CONFIG_NLS_ISO8859_13 is not set | |
| 1220 | +# CONFIG_NLS_ISO8859_14 is not set | |
| 1221 | +CONFIG_NLS_ISO8859_15=y | |
| 1222 | +# CONFIG_NLS_KOI8_R is not set | |
| 1223 | +# CONFIG_NLS_KOI8_U is not set | |
| 1224 | +# CONFIG_NLS_UTF8 is not set | |
| 1225 | +# CONFIG_DLM is not set | |
| 1226 | +# CONFIG_BINARY_PRINTF is not set | |
| 1227 | + | |
| 1228 | +# | |
| 1229 | +# Library routines | |
| 1230 | +# | |
| 1231 | +CONFIG_BITREVERSE=y | |
| 1232 | +CONFIG_GENERIC_FIND_LAST_BIT=y | |
| 1233 | +# CONFIG_CRC_CCITT is not set | |
| 1234 | +# CONFIG_CRC16 is not set | |
| 1235 | +# CONFIG_CRC_T10DIF is not set | |
| 1236 | +# CONFIG_CRC_ITU_T is not set | |
| 1237 | +CONFIG_CRC32=y | |
| 1238 | +# CONFIG_CRC7 is not set | |
| 1239 | +# CONFIG_LIBCRC32C is not set | |
| 1240 | +CONFIG_ZLIB_INFLATE=y | |
| 1241 | +CONFIG_DECOMPRESS_GZIP=y | |
| 1242 | +CONFIG_HAS_IOMEM=y | |
| 1243 | +CONFIG_HAS_IOPORT=y | |
| 1244 | +CONFIG_HAS_DMA=y | |
| 1245 | +CONFIG_HAVE_LMB=y | |
| 1246 | +CONFIG_NLATTR=y | |
| 1247 | +CONFIG_GENERIC_ATOMIC64=y | |
| 1248 | + | |
| 1249 | +# | |
| 1250 | +# Kernel hacking | |
| 1251 | +# | |
| 1252 | +# CONFIG_PRINTK_TIME is not set | |
| 1253 | +CONFIG_ENABLE_WARN_DEPRECATED=y | |
| 1254 | +CONFIG_ENABLE_MUST_CHECK=y | |
| 1255 | +CONFIG_FRAME_WARN=1024 | |
| 1256 | +CONFIG_MAGIC_SYSRQ=y | |
| 1257 | +# CONFIG_STRIP_ASM_SYMS is not set | |
| 1258 | +# CONFIG_UNUSED_SYMBOLS is not set | |
| 1259 | +# CONFIG_DEBUG_FS is not set | |
| 1260 | +# CONFIG_HEADERS_CHECK is not set | |
| 1261 | +CONFIG_DEBUG_KERNEL=y | |
| 1262 | +# CONFIG_DEBUG_SHIRQ is not set | |
| 1263 | +CONFIG_DETECT_SOFTLOCKUP=y | |
| 1264 | +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | |
| 1265 | +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | |
| 1266 | +CONFIG_DETECT_HUNG_TASK=y | |
| 1267 | +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | |
| 1268 | +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | |
| 1269 | +CONFIG_SCHED_DEBUG=y | |
| 1270 | +# CONFIG_SCHEDSTATS is not set | |
| 1271 | +# CONFIG_TIMER_STATS is not set | |
| 1272 | +# CONFIG_DEBUG_OBJECTS is not set | |
| 1273 | +# CONFIG_SLUB_DEBUG_ON is not set | |
| 1274 | +# CONFIG_SLUB_STATS is not set | |
| 1275 | +# CONFIG_DEBUG_KMEMLEAK is not set | |
| 1276 | +# CONFIG_DEBUG_RT_MUTEXES is not set | |
| 1277 | +# CONFIG_RT_MUTEX_TESTER is not set | |
| 1278 | +# CONFIG_DEBUG_SPINLOCK is not set | |
| 1279 | +# CONFIG_DEBUG_MUTEXES is not set | |
| 1280 | +# CONFIG_DEBUG_LOCK_ALLOC is not set | |
| 1281 | +# CONFIG_PROVE_LOCKING is not set | |
| 1282 | +# CONFIG_LOCK_STAT is not set | |
| 1283 | +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set | |
| 1284 | +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | |
| 1285 | +# CONFIG_DEBUG_KOBJECT is not set | |
| 1286 | +# CONFIG_DEBUG_HIGHMEM is not set | |
| 1287 | +# CONFIG_DEBUG_BUGVERBOSE is not set | |
| 1288 | +# CONFIG_DEBUG_INFO is not set | |
| 1289 | +# CONFIG_DEBUG_VM is not set | |
| 1290 | +# CONFIG_DEBUG_WRITECOUNT is not set | |
| 1291 | +# CONFIG_DEBUG_MEMORY_INIT is not set | |
| 1292 | +# CONFIG_DEBUG_LIST is not set | |
| 1293 | +# CONFIG_DEBUG_SG is not set | |
| 1294 | +# CONFIG_DEBUG_NOTIFIERS is not set | |
| 1295 | +# CONFIG_DEBUG_CREDENTIALS is not set | |
| 1296 | +# CONFIG_RCU_TORTURE_TEST is not set | |
| 1297 | +# CONFIG_RCU_CPU_STALL_DETECTOR is not set | |
| 1298 | +# CONFIG_BACKTRACE_SELF_TEST is not set | |
| 1299 | +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | |
| 1300 | +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set | |
| 1301 | +# CONFIG_FAULT_INJECTION is not set | |
| 1302 | +# CONFIG_LATENCYTOP is not set | |
| 1303 | +CONFIG_SYSCTL_SYSCALL_CHECK=y | |
| 1304 | +# CONFIG_DEBUG_PAGEALLOC is not set | |
| 1305 | +CONFIG_HAVE_FUNCTION_TRACER=y | |
| 1306 | +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | |
| 1307 | +CONFIG_HAVE_DYNAMIC_FTRACE=y | |
| 1308 | +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | |
| 1309 | +CONFIG_TRACING_SUPPORT=y | |
| 1310 | +CONFIG_FTRACE=y | |
| 1311 | +# CONFIG_FUNCTION_TRACER is not set | |
| 1312 | +# CONFIG_IRQSOFF_TRACER is not set | |
| 1313 | +# CONFIG_SCHED_TRACER is not set | |
| 1314 | +# CONFIG_ENABLE_DEFAULT_TRACERS is not set | |
| 1315 | +# CONFIG_BOOT_TRACER is not set | |
| 1316 | +CONFIG_BRANCH_PROFILE_NONE=y | |
| 1317 | +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set | |
| 1318 | +# CONFIG_PROFILE_ALL_BRANCHES is not set | |
| 1319 | +# CONFIG_STACK_TRACER is not set | |
| 1320 | +# CONFIG_KMEMTRACE is not set | |
| 1321 | +# CONFIG_WORKQUEUE_TRACER is not set | |
| 1322 | +# CONFIG_BLK_DEV_IO_TRACE is not set | |
| 1323 | +# CONFIG_DMA_API_DEBUG is not set | |
| 1324 | +# CONFIG_SAMPLES is not set | |
| 1325 | +CONFIG_HAVE_ARCH_KGDB=y | |
| 1326 | +# CONFIG_KGDB is not set | |
| 1327 | +# CONFIG_PPC_DISABLE_WERROR is not set | |
| 1328 | +CONFIG_PPC_WERROR=y | |
| 1329 | +CONFIG_PRINT_STACK_DEPTH=64 | |
| 1330 | +# CONFIG_DEBUG_STACKOVERFLOW is not set | |
| 1331 | +# CONFIG_DEBUG_STACK_USAGE is not set | |
| 1332 | +# CONFIG_CODE_PATCHING_SELFTEST is not set | |
| 1333 | +# CONFIG_FTR_FIXUP_SELFTEST is not set | |
| 1334 | +# CONFIG_MSI_BITMAP_SELFTEST is not set | |
| 1335 | +# CONFIG_XMON is not set | |
| 1336 | +# CONFIG_IRQSTACKS is not set | |
| 1337 | +# CONFIG_BDI_SWITCH is not set | |
| 1338 | +# CONFIG_PPC_EARLY_DEBUG is not set | |
| 1339 | + | |
| 1340 | +# | |
| 1341 | +# Security options | |
| 1342 | +# | |
| 1343 | +# CONFIG_KEYS is not set | |
| 1344 | +# CONFIG_SECURITY is not set | |
| 1345 | +# CONFIG_SECURITYFS is not set | |
| 1346 | +# CONFIG_DEFAULT_SECURITY_SELINUX is not set | |
| 1347 | +# CONFIG_DEFAULT_SECURITY_SMACK is not set | |
| 1348 | +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set | |
| 1349 | +CONFIG_DEFAULT_SECURITY_DAC=y | |
| 1350 | +CONFIG_DEFAULT_SECURITY="" | |
| 1351 | +CONFIG_CRYPTO=y | |
| 1352 | + | |
| 1353 | +# | |
| 1354 | +# Crypto core or helper | |
| 1355 | +# | |
| 1356 | +CONFIG_CRYPTO_ALGAPI=y | |
| 1357 | +CONFIG_CRYPTO_ALGAPI2=y | |
| 1358 | +CONFIG_CRYPTO_AEAD2=y | |
| 1359 | +CONFIG_CRYPTO_BLKCIPHER=y | |
| 1360 | +CONFIG_CRYPTO_BLKCIPHER2=y | |
| 1361 | +CONFIG_CRYPTO_HASH=y | |
| 1362 | +CONFIG_CRYPTO_HASH2=y | |
| 1363 | +CONFIG_CRYPTO_RNG2=y | |
| 1364 | +CONFIG_CRYPTO_PCOMP=y | |
| 1365 | +CONFIG_CRYPTO_MANAGER=y | |
| 1366 | +CONFIG_CRYPTO_MANAGER2=y | |
| 1367 | +# CONFIG_CRYPTO_GF128MUL is not set | |
| 1368 | +# CONFIG_CRYPTO_NULL is not set | |
| 1369 | +CONFIG_CRYPTO_WORKQUEUE=y | |
| 1370 | +# CONFIG_CRYPTO_CRYPTD is not set | |
| 1371 | +# CONFIG_CRYPTO_AUTHENC is not set | |
| 1372 | +# CONFIG_CRYPTO_TEST is not set | |
| 1373 | + | |
| 1374 | +# | |
| 1375 | +# Authenticated Encryption with Associated Data | |
| 1376 | +# | |
| 1377 | +# CONFIG_CRYPTO_CCM is not set | |
| 1378 | +# CONFIG_CRYPTO_GCM is not set | |
| 1379 | +# CONFIG_CRYPTO_SEQIV is not set | |
| 1380 | + | |
| 1381 | +# | |
| 1382 | +# Block modes | |
| 1383 | +# | |
| 1384 | +CONFIG_CRYPTO_CBC=y | |
| 1385 | +# CONFIG_CRYPTO_CTR is not set | |
| 1386 | +# CONFIG_CRYPTO_CTS is not set | |
| 1387 | +CONFIG_CRYPTO_ECB=y | |
| 1388 | +# CONFIG_CRYPTO_LRW is not set | |
| 1389 | +CONFIG_CRYPTO_PCBC=y | |
| 1390 | +# CONFIG_CRYPTO_XTS is not set | |
| 1391 | + | |
| 1392 | +# | |
| 1393 | +# Hash modes | |
| 1394 | +# | |
| 1395 | +# CONFIG_CRYPTO_HMAC is not set | |
| 1396 | +# CONFIG_CRYPTO_XCBC is not set | |
| 1397 | +# CONFIG_CRYPTO_VMAC is not set | |
| 1398 | + | |
| 1399 | +# | |
| 1400 | +# Digest | |
| 1401 | +# | |
| 1402 | +# CONFIG_CRYPTO_CRC32C is not set | |
| 1403 | +# CONFIG_CRYPTO_GHASH is not set | |
| 1404 | +# CONFIG_CRYPTO_MD4 is not set | |
| 1405 | +CONFIG_CRYPTO_MD5=y | |
| 1406 | +# CONFIG_CRYPTO_MICHAEL_MIC is not set | |
| 1407 | +# CONFIG_CRYPTO_RMD128 is not set | |
| 1408 | +# CONFIG_CRYPTO_RMD160 is not set | |
| 1409 | +# CONFIG_CRYPTO_RMD256 is not set | |
| 1410 | +# CONFIG_CRYPTO_RMD320 is not set | |
| 1411 | +# CONFIG_CRYPTO_SHA1 is not set | |
| 1412 | +# CONFIG_CRYPTO_SHA256 is not set | |
| 1413 | +# CONFIG_CRYPTO_SHA512 is not set | |
| 1414 | +# CONFIG_CRYPTO_TGR192 is not set | |
| 1415 | +# CONFIG_CRYPTO_WP512 is not set | |
| 1416 | + | |
| 1417 | +# | |
| 1418 | +# Ciphers | |
| 1419 | +# | |
| 1420 | +# CONFIG_CRYPTO_AES is not set | |
| 1421 | +# CONFIG_CRYPTO_ANUBIS is not set | |
| 1422 | +# CONFIG_CRYPTO_ARC4 is not set | |
| 1423 | +# CONFIG_CRYPTO_BLOWFISH is not set | |
| 1424 | +# CONFIG_CRYPTO_CAMELLIA is not set | |
| 1425 | +# CONFIG_CRYPTO_CAST5 is not set | |
| 1426 | +# CONFIG_CRYPTO_CAST6 is not set | |
| 1427 | +CONFIG_CRYPTO_DES=y | |
| 1428 | +# CONFIG_CRYPTO_FCRYPT is not set | |
| 1429 | +# CONFIG_CRYPTO_KHAZAD is not set | |
| 1430 | +# CONFIG_CRYPTO_SALSA20 is not set | |
| 1431 | +# CONFIG_CRYPTO_SEED is not set | |
| 1432 | +# CONFIG_CRYPTO_SERPENT is not set | |
| 1433 | +# CONFIG_CRYPTO_TEA is not set | |
| 1434 | +# CONFIG_CRYPTO_TWOFISH is not set | |
| 1435 | + | |
| 1436 | +# | |
| 1437 | +# Compression | |
| 1438 | +# | |
| 1439 | +# CONFIG_CRYPTO_DEFLATE is not set | |
| 1440 | +# CONFIG_CRYPTO_ZLIB is not set | |
| 1441 | +# CONFIG_CRYPTO_LZO is not set | |
| 1442 | + | |
| 1443 | +# | |
| 1444 | +# Random Number Generation | |
| 1445 | +# | |
| 1446 | +# CONFIG_CRYPTO_ANSI_CPRNG is not set | |
| 1447 | +CONFIG_CRYPTO_HW=y | |
| 1448 | +# CONFIG_CRYPTO_DEV_HIFN_795X is not set | |
| 1449 | +# CONFIG_CRYPTO_DEV_PPC4XX is not set | |
| 1450 | +# CONFIG_PPC_CLOCK is not set | |
| 1451 | +# CONFIG_VIRTUALIZATION is not set | |
| @@ -42,7 +42,7 @@ extern struct ppc64_caches ppc64_caches; · 41 unmodified lines | ||
| 42 | 42 | #endif /* __powerpc64__ && ! __ASSEMBLY__ */ |
| 43 | 43 | |
| 44 | 44 | #if !defined(__ASSEMBLY__) |
| 45 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 45 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 46 | 46 | #endif |
| 47 | 47 | |
| 48 | 48 | #endif /* __KERNEL__ */ |
| @@ -70,6 +70,7 @@ struct pt_regs; · 69 unmodified lines | ||
| 70 | 70 | extern int machine_check_generic(struct pt_regs *regs); |
| 71 | 71 | extern int machine_check_4xx(struct pt_regs *regs); |
| 72 | 72 | extern int machine_check_440A(struct pt_regs *regs); |
| 73 | +extern int machine_check_e500mc(struct pt_regs *regs); | |
| 73 | 74 | extern int machine_check_e500(struct pt_regs *regs); |
| 74 | 75 | extern int machine_check_e200(struct pt_regs *regs); |
| 75 | 76 | extern int machine_check_47x(struct pt_regs *regs); |
| @@ -2,6 +2,18 @@ · 1 unmodified line | ||
| 2 | 2 | #define _ASM_POWERPC_KEXEC_H |
| 3 | 3 | #ifdef __KERNEL__ |
| 4 | 4 | |
| 5 | +#ifdef CONFIG_FSL_BOOKE | |
| 6 | + | |
| 7 | +/* | |
| 8 | + * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory | |
| 9 | + * and therefore we can only deal with memory within this range | |
| 10 | + */ | |
| 11 | +#define KEXEC_SOURCE_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) | |
| 12 | +#define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) | |
| 13 | +#define KEXEC_CONTROL_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) | |
| 14 | + | |
| 15 | +#else | |
| 16 | + | |
| 5 | 17 | /* |
| 6 | 18 | * Maximum page that is mapped directly into kernel memory. |
| 7 | 19 | * XXX: Since we copy virt we can use any page we allocate |
| @@ -21,6 +33,7 @@ · 13 unmodified lines | ||
| 21 | 33 | /* TASK_SIZE, probably left over from use_mm ?? */ |
| 22 | 34 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE |
| 23 | 35 | #endif |
| 36 | +#endif | |
| 24 | 37 | |
| 25 | 38 | #define KEXEC_CONTROL_PAGE_SIZE 4096 |
| 26 | 39 | |
| @@ -123,10 +123,6 @@ static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev) · 122 unmodified lines | ||
| 123 | 123 | */ |
| 124 | 124 | struct macio_driver |
| 125 | 125 | { |
| 126 | − char *name; | |
| 127 | − struct of_device_id *match_table; | |
| 128 | − struct module *owner; | |
| 129 | − | |
| 130 | 126 | int (*probe)(struct macio_dev* dev, const struct of_device_id *match); |
| 131 | 127 | int (*remove)(struct macio_dev* dev); |
| 132 | 128 | |
| @@ -162,14 +162,6 @@ do { \ · 161 unmodified lines | ||
| 162 | 162 | |
| 163 | 163 | #endif /* !CONFIG_HUGETLB_PAGE */ |
| 164 | 164 | |
| 165 | −#ifdef MODULE | |
| 166 | −#define __page_aligned __attribute__((__aligned__(PAGE_SIZE))) | |
| 167 | −#else | |
| 168 | −#define __page_aligned \ | |
| 169 | − __attribute__((__aligned__(PAGE_SIZE), \ | |
| 170 | − __section__(".data.page_aligned"))) | |
| 171 | −#endif | |
| 172 | − | |
| 173 | 165 | #define VM_DATA_DEFAULT_FLAGS \ |
| 174 | 166 | (test_thread_flag(TIF_32BIT) ? \ |
| 175 | 167 | VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64) |
| @@ -4,6 +4,12 @@ · 3 unmodified lines | ||
| 4 | 4 | * are not true Book E PowerPCs, they borrowed a number of features |
| 5 | 5 | * before Book E was finalized, and are included here as well. Unfortunatly, |
| 6 | 6 | * they sometimes used different locations than true Book E CPUs did. |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or | |
| 9 | + * modify it under the terms of the GNU General Public License version 2 | |
| 10 | + * as published by the Free Software Foundation. | |
| 11 | + * | |
| 12 | + * Copyright 2009-2010 Freescale Semiconductor, Inc. | |
| 7 | 13 | */ |
| 8 | 14 | #ifdef __KERNEL__ |
| 9 | 15 | #ifndef __ASM_POWERPC_REG_BOOKE_H__ |
| @@ -88,6 +94,7 @@ · 78 unmodified lines | ||
| 88 | 94 | #define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */ |
| 89 | 95 | #define SPRN_IVOR36 0x214 /* Interrupt Vector Offset Register 36 */ |
| 90 | 96 | #define SPRN_IVOR37 0x215 /* Interrupt Vector Offset Register 37 */ |
| 97 | +#define SPRN_MCARU 0x239 /* Machine Check Address Register Upper */ | |
| 91 | 98 | #define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */ |
| 92 | 99 | #define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */ |
| 93 | 100 | #define SPRN_MCSR 0x23C /* Machine Check Status Register */ |
| @@ -196,8 +203,11 @@ · 102 unmodified lines | ||
| 196 | 203 | #define PPC47x_MCSR_IPR 0x00400000 /* Imprecise Machine Check Exception */ |
| 197 | 204 | |
| 198 | 205 | #ifdef CONFIG_E500 |
| 206 | +/* All e500 */ | |
| 199 | 207 | #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ |
| 200 | 208 | #define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */ |
| 209 | + | |
| 210 | +/* e500v1/v2 */ | |
| 201 | 211 | #define MCSR_DCP_PERR 0x20000000UL /* D-Cache Push Parity Error */ |
| 202 | 212 | #define MCSR_DCPERR 0x10000000UL /* D-Cache Parity Error */ |
| 203 | 213 | #define MCSR_BUS_IAERR 0x00000080UL /* Instruction Address Error */ |
| @@ -209,12 +219,20 @@ · 5 unmodified lines | ||
| 209 | 219 | #define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */ |
| 210 | 220 | #define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */ |
| 211 | 221 | |
| 212 | −/* e500 parts may set unused bits in MCSR; mask these off */ | |
| 213 | −#define MCSR_MASK (MCSR_MCP | MCSR_ICPERR | MCSR_DCP_PERR | \ | |
| 214 | − MCSR_DCPERR | MCSR_BUS_IAERR | MCSR_BUS_RAERR | \ | |
| 215 | − MCSR_BUS_WAERR | MCSR_BUS_IBERR | MCSR_BUS_RBERR | \ | |
| 216 | − MCSR_BUS_WBERR | MCSR_BUS_IPERR | MCSR_BUS_RPERR) | |
| 222 | +/* e500mc */ | |
| 223 | +#define MCSR_DCPERR_MC 0x20000000UL /* D-Cache Parity Error */ | |
| 224 | +#define MCSR_L2MMU_MHIT 0x04000000UL /* Hit on multiple TLB entries */ | |
| 225 | +#define MCSR_NMI 0x00100000UL /* Non-Maskable Interrupt */ | |
| 226 | +#define MCSR_MAV 0x00080000UL /* MCAR address valid */ | |
| 227 | +#define MCSR_MEA 0x00040000UL /* MCAR is effective address */ | |
| 228 | +#define MCSR_IF 0x00010000UL /* Instruction Fetch */ | |
| 229 | +#define MCSR_LD 0x00008000UL /* Load */ | |
| 230 | +#define MCSR_ST 0x00004000UL /* Store */ | |
| 231 | +#define MCSR_LDG 0x00002000UL /* Guarded Load */ | |
| 232 | +#define MCSR_TLBSYNC 0x00000002UL /* Multiple tlbsyncs detected */ | |
| 233 | +#define MCSR_BSL2_ERR 0x00000001UL /* Backside L2 cache error */ | |
| 217 | 234 | #endif |
| 235 | + | |
| 218 | 236 | #ifdef CONFIG_E200 |
| 219 | 237 | #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ |
| 220 | 238 | #define MCSR_CP_PERR 0x20000000UL /* Cache Push Parity Error */ |
| @@ -225,11 +243,6 @@ · 4 unmodified lines | ||
| 225 | 243 | #define MCSR_BUS_DRERR 0x00000008UL /* Read Bus Error on data load */ |
| 226 | 244 | #define MCSR_BUS_WRERR 0x00000004UL /* Write Bus Error on buffered |
| 227 | 245 | store or cache line push */ |
| 228 | − | |
| 229 | −/* e200 parts may set unused bits in MCSR; mask these off */ | |
| 230 | −#define MCSR_MASK (MCSR_MCP | MCSR_CP_PERR | MCSR_CPERR | \ | |
| 231 | − MCSR_EXCP_ERR | MCSR_BUS_IRERR | MCSR_BUS_DRERR | \ | |
| 232 | − MCSR_BUS_WRERR) | |
| 233 | 246 | #endif |
| 234 | 247 | |
| 235 | 248 | /* Bit definitions for the DBSR. */ |
| @@ -57,8 +57,12 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o · 56 unmodified lines | ||
| 57 | 57 | obj-$(CONFIG_E500) += idle_e500.o |
| 58 | 58 | obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o |
| 59 | 59 | obj-$(CONFIG_TAU) += tau_6xx.o |
| 60 | −obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \ | |
| 61 | − swsusp_$(CONFIG_WORD_SIZE).o | |
| 60 | +obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o | |
| 61 | +ifeq ($(CONFIG_FSL_BOOKE),y) | |
| 62 | +obj-$(CONFIG_HIBERNATION) += swsusp_booke.o | |
| 63 | +else | |
| 64 | +obj-$(CONFIG_HIBERNATION) += swsusp_$(CONFIG_WORD_SIZE).o | |
| 65 | +endif | |
| 62 | 66 | obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o |
| 63 | 67 | obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o |
| 64 | 68 | obj-$(CONFIG_44x) += cpu_setup_44x.o |
| @@ -1840,7 +1840,7 @@ static struct cpu_spec __initdata cpu_specs[] = { · 1839 unmodified lines | ||
| 1840 | 1840 | .oprofile_cpu_type = "ppc/e500mc", |
| 1841 | 1841 | .oprofile_type = PPC_OPROFILE_FSL_EMB, |
| 1842 | 1842 | .cpu_setup = __setup_cpu_e500mc, |
| 1843 | − .machine_check = machine_check_e500, | |
| 1843 | + .machine_check = machine_check_e500mc, | |
| 1844 | 1844 | .platform = "ppce500mc", |
| 1845 | 1845 | }, |
| 1846 | 1846 | { /* default match */ |
| @@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu) · 162 unmodified lines | ||
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ |
| 166 | +#ifdef CONFIG_PPC_STD_MMU_64 | |
| 166 | 167 | static void crash_kexec_wait_realmode(int cpu) |
| 167 | 168 | { |
| 168 | 169 | unsigned int msecs; |
| @@ -187,6 +188,7 @@ static void crash_kexec_wait_realmode(int cpu) · 18 unmodified lines | ||
| 187 | 188 | } |
| 188 | 189 | mb(); |
| 189 | 190 | } |
| 191 | +#endif | |
| 190 | 192 | |
| 191 | 193 | /* |
| 192 | 194 | * This function will be called by secondary cpus or by kexec cpu |
| @@ -445,7 +447,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs) · 252 unmodified lines | ||
| 445 | 447 | crash_kexec_prepare_cpus(crashing_cpu); |
| 446 | 448 | cpu_set(crashing_cpu, cpus_in_crash); |
| 447 | 449 | crash_kexec_stop_spus(); |
| 450 | +#ifdef CONFIG_PPC_STD_MMU_64 | |
| 448 | 451 | crash_kexec_wait_realmode(crashing_cpu); |
| 452 | +#endif | |
| 449 | 453 | if (ppc_md.kexec_cpu_down) |
| 450 | 454 | ppc_md.kexec_cpu_down(1, 0); |
| 451 | 455 | } |
| @@ -0,0 +1,237 @@ | ||
| 1 | + | |
| 2 | +/* 1. Find the index of the entry we're executing in */ | |
| 3 | + bl invstr /* Find our address */ | |
| 4 | +invstr: mflr r6 /* Make it accessible */ | |
| 5 | + mfmsr r7 | |
| 6 | + rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ | |
| 7 | + mfspr r7, SPRN_PID0 | |
| 8 | + slwi r7,r7,16 | |
| 9 | + or r7,r7,r4 | |
| 10 | + mtspr SPRN_MAS6,r7 | |
| 11 | + tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ | |
| 12 | + mfspr r7,SPRN_MAS1 | |
| 13 | + andis. r7,r7,MAS1_VALID@h | |
| 14 | + bne match_TLB | |
| 15 | + | |
| 16 | + mfspr r7,SPRN_MMUCFG | |
| 17 | + rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | |
| 18 | + cmpwi r7,3 | |
| 19 | + bne match_TLB /* skip if NPIDS != 3 */ | |
| 20 | + | |
| 21 | + mfspr r7,SPRN_PID1 | |
| 22 | + slwi r7,r7,16 | |
| 23 | + or r7,r7,r4 | |
| 24 | + mtspr SPRN_MAS6,r7 | |
| 25 | + tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ | |
| 26 | + mfspr r7,SPRN_MAS1 | |
| 27 | + andis. r7,r7,MAS1_VALID@h | |
| 28 | + bne match_TLB | |
| 29 | + mfspr r7, SPRN_PID2 | |
| 30 | + slwi r7,r7,16 | |
| 31 | + or r7,r7,r4 | |
| 32 | + mtspr SPRN_MAS6,r7 | |
| 33 | + tlbsx 0,r6 /* Fall through, we had to match */ | |
| 34 | + | |
| 35 | +match_TLB: | |
| 36 | + mfspr r7,SPRN_MAS0 | |
| 37 | + rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ | |
| 38 | + | |
| 39 | + mfspr r7,SPRN_MAS1 /* Insure IPROT set */ | |
| 40 | + oris r7,r7,MAS1_IPROT@h | |
| 41 | + mtspr SPRN_MAS1,r7 | |
| 42 | + tlbwe | |
| 43 | + | |
| 44 | +/* 2. Invalidate all entries except the entry we're executing in */ | |
| 45 | + mfspr r9,SPRN_TLB1CFG | |
| 46 | + andi. r9,r9,0xfff | |
| 47 | + li r6,0 /* Set Entry counter to 0 */ | |
| 48 | +1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 49 | + rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ | |
| 50 | + mtspr SPRN_MAS0,r7 | |
| 51 | + tlbre | |
| 52 | + mfspr r7,SPRN_MAS1 | |
| 53 | + rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ | |
| 54 | + cmpw r3,r6 | |
| 55 | + beq skpinv /* Dont update the current execution TLB */ | |
| 56 | + mtspr SPRN_MAS1,r7 | |
| 57 | + tlbwe | |
| 58 | + isync | |
| 59 | +skpinv: addi r6,r6,1 /* Increment */ | |
| 60 | + cmpw r6,r9 /* Are we done? */ | |
| 61 | + bne 1b /* If not, repeat */ | |
| 62 | + | |
| 63 | + /* Invalidate TLB0 */ | |
| 64 | + li r6,0x04 | |
| 65 | + tlbivax 0,r6 | |
| 66 | + TLBSYNC | |
| 67 | + /* Invalidate TLB1 */ | |
| 68 | + li r6,0x0c | |
| 69 | + tlbivax 0,r6 | |
| 70 | + TLBSYNC | |
| 71 | + | |
| 72 | +/* 3. Setup a temp mapping and jump to it */ | |
| 73 | + andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ | |
| 74 | + addi r5, r5, 0x1 | |
| 75 | + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 76 | + rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | |
| 77 | + mtspr SPRN_MAS0,r7 | |
| 78 | + tlbre | |
| 79 | + | |
| 80 | + /* grab and fixup the RPN */ | |
| 81 | + mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ | |
| 82 | + rlwinm r6,r6,25,27,31 | |
| 83 | + li r8,-1 | |
| 84 | + addi r6,r6,10 | |
| 85 | + slw r6,r8,r6 /* convert to mask */ | |
| 86 | + | |
| 87 | + bl 1f /* Find our address */ | |
| 88 | +1: mflr r7 | |
| 89 | + | |
| 90 | + mfspr r8,SPRN_MAS3 | |
| 91 | +#ifdef CONFIG_PHYS_64BIT | |
| 92 | + mfspr r23,SPRN_MAS7 | |
| 93 | +#endif | |
| 94 | + and r8,r6,r8 | |
| 95 | + subfic r9,r6,-4096 | |
| 96 | + and r9,r9,r7 | |
| 97 | + | |
| 98 | + or r25,r8,r9 | |
| 99 | + ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) | |
| 100 | + | |
| 101 | + /* Just modify the entry ID and EPN for the temp mapping */ | |
| 102 | + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 103 | + rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | |
| 104 | + mtspr SPRN_MAS0,r7 | |
| 105 | + xori r6,r4,1 /* Setup TMP mapping in the other Address space */ | |
| 106 | + slwi r6,r6,12 | |
| 107 | + oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h | |
| 108 | + ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l | |
| 109 | + mtspr SPRN_MAS1,r6 | |
| 110 | + mfspr r6,SPRN_MAS2 | |
| 111 | + li r7,0 /* temp EPN = 0 */ | |
| 112 | + rlwimi r7,r6,0,20,31 | |
| 113 | + mtspr SPRN_MAS2,r7 | |
| 114 | + mtspr SPRN_MAS3,r8 | |
| 115 | + tlbwe | |
| 116 | + | |
| 117 | + xori r6,r4,1 | |
| 118 | + slwi r6,r6,5 /* setup new context with other address space */ | |
| 119 | + bl 1f /* Find our address */ | |
| 120 | +1: mflr r9 | |
| 121 | + rlwimi r7,r9,0,20,31 | |
| 122 | + addi r7,r7,(2f - 1b) | |
| 123 | + mtspr SPRN_SRR0,r7 | |
| 124 | + mtspr SPRN_SRR1,r6 | |
| 125 | + rfi | |
| 126 | +2: | |
| 127 | +/* 4. Clear out PIDs & Search info */ | |
| 128 | + li r6,0 | |
| 129 | + mtspr SPRN_MAS6,r6 | |
| 130 | + mtspr SPRN_PID0,r6 | |
| 131 | + | |
| 132 | + mfspr r7,SPRN_MMUCFG | |
| 133 | + rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | |
| 134 | + cmpwi r7,3 | |
| 135 | + bne 2f /* skip if NPIDS != 3 */ | |
| 136 | + | |
| 137 | + mtspr SPRN_PID1,r6 | |
| 138 | + mtspr SPRN_PID2,r6 | |
| 139 | + | |
| 140 | +/* 5. Invalidate mapping we started in */ | |
| 141 | +2: | |
| 142 | + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 143 | + rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | |
| 144 | + mtspr SPRN_MAS0,r7 | |
| 145 | + tlbre | |
| 146 | + mfspr r6,SPRN_MAS1 | |
| 147 | + rlwinm r6,r6,0,2,0 /* clear IPROT */ | |
| 148 | + mtspr SPRN_MAS1,r6 | |
| 149 | + tlbwe | |
| 150 | + /* Invalidate TLB1 */ | |
| 151 | + li r9,0x0c | |
| 152 | + tlbivax 0,r9 | |
| 153 | + TLBSYNC | |
| 154 | + | |
| 155 | +/* The mapping only needs to be cache-coherent on SMP */ | |
| 156 | +#ifdef CONFIG_SMP | |
| 157 | +#define M_IF_SMP MAS2_M | |
| 158 | +#else | |
| 159 | +#define M_IF_SMP 0 | |
| 160 | +#endif | |
| 161 | + | |
| 162 | +#if defined(ENTRY_MAPPING_BOOT_SETUP) | |
| 163 | + | |
| 164 | +/* 6. Setup KERNELBASE mapping in TLB1[0] */ | |
| 165 | + lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ | |
| 166 | + mtspr SPRN_MAS0,r6 | |
| 167 | + lis r6,(MAS1_VALID|MAS1_IPROT)@h | |
| 168 | + ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l | |
| 169 | + mtspr SPRN_MAS1,r6 | |
| 170 | + lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h | |
| 171 | + ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l | |
| 172 | + mtspr SPRN_MAS2,r6 | |
| 173 | + mtspr SPRN_MAS3,r8 | |
| 174 | + tlbwe | |
| 175 | + | |
| 176 | +/* 7. Jump to KERNELBASE mapping */ | |
| 177 | + lis r6,(KERNELBASE & ~0xfff)@h | |
| 178 | + ori r6,r6,(KERNELBASE & ~0xfff)@l | |
| 179 | + | |
| 180 | +#elif defined(ENTRY_MAPPING_KEXEC_SETUP) | |
| 181 | +/* | |
| 182 | + * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp | |
| 183 | + * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This | |
| 184 | + * will cover the first 2GiB of memory. | |
| 185 | + */ | |
| 186 | + | |
| 187 | + lis r10, (MAS1_VALID|MAS1_IPROT)@h | |
| 188 | + ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l | |
| 189 | + li r11, 0 | |
| 190 | + li r0, 8 | |
| 191 | + mtctr r0 | |
| 192 | + | |
| 193 | +next_tlb_setup: | |
| 194 | + addi r0, r11, 3 | |
| 195 | + rlwinm r0, r0, 16, 4, 15 // Compute esel | |
| 196 | + rlwinm r9, r11, 28, 0, 3 // Compute [ER]PN | |
| 197 | + oris r0, r0, (MAS0_TLBSEL(1))@h | |
| 198 | + mtspr SPRN_MAS0,r0 | |
| 199 | + mtspr SPRN_MAS1,r10 | |
| 200 | + mtspr SPRN_MAS2,r9 | |
| 201 | + ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR) | |
| 202 | + mtspr SPRN_MAS3,r9 | |
| 203 | + tlbwe | |
| 204 | + addi r11, r11, 1 | |
| 205 | + bdnz+ next_tlb_setup | |
| 206 | + | |
| 207 | +/* 7. Jump to our 1:1 mapping */ | |
| 208 | + li r6, 0 | |
| 209 | + | |
| 210 | +#else | |
| 211 | + #error You need to specify the mapping or not use this at all. | |
| 212 | +#endif | |
| 213 | + | |
| 214 | + lis r7,MSR_KERNEL@h | |
| 215 | + ori r7,r7,MSR_KERNEL@l | |
| 216 | + bl 1f /* Find our address */ | |
| 217 | +1: mflr r9 | |
| 218 | + rlwimi r6,r9,0,20,31 | |
| 219 | + addi r6,r6,(2f - 1b) | |
| 220 | + add r6, r6, r25 | |
| 221 | + mtspr SPRN_SRR0,r6 | |
| 222 | + mtspr SPRN_SRR1,r7 | |
| 223 | + rfi /* start execution out of TLB1[0] entry */ | |
| 224 | + | |
| 225 | +/* 8. Clear out the temp mapping */ | |
| 226 | +2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 227 | + rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | |
| 228 | + mtspr SPRN_MAS0,r7 | |
| 229 | + tlbre | |
| 230 | + mfspr r8,SPRN_MAS1 | |
| 231 | + rlwinm r8,r8,0,2,0 /* clear IPROT */ | |
| 232 | + mtspr SPRN_MAS1,r8 | |
| 233 | + tlbwe | |
| 234 | + /* Invalidate TLB1 */ | |
| 235 | + li r9,0x0c | |
| 236 | + tlbivax 0,r9 | |
| 237 | + TLBSYNC | |
| @@ -94,204 +94,10 @@ _ENTRY(_start); · 93 unmodified lines | ||
| 94 | 94 | */ |
| 95 | 95 | |
| 96 | 96 | _ENTRY(__early_start) |
| 97 | −/* 1. Find the index of the entry we're executing in */ | |
| 98 | − bl invstr /* Find our address */ | |
| 99 | −invstr: mflr r6 /* Make it accessible */ | |
| 100 | − mfmsr r7 | |
| 101 | − rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ | |
| 102 | − mfspr r7, SPRN_PID0 | |
| 103 | − slwi r7,r7,16 | |
| 104 | − or r7,r7,r4 | |
| 105 | − mtspr SPRN_MAS6,r7 | |
| 106 | − tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ | |
| 107 | − mfspr r7,SPRN_MAS1 | |
| 108 | − andis. r7,r7,MAS1_VALID@h | |
| 109 | − bne match_TLB | |
| 110 | − | |
| 111 | − mfspr r7,SPRN_MMUCFG | |
| 112 | − rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | |
| 113 | − cmpwi r7,3 | |
| 114 | − bne match_TLB /* skip if NPIDS != 3 */ | |
| 115 | − | |
| 116 | − mfspr r7,SPRN_PID1 | |
| 117 | − slwi r7,r7,16 | |
| 118 | − or r7,r7,r4 | |
| 119 | − mtspr SPRN_MAS6,r7 | |
| 120 | − tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ | |
| 121 | − mfspr r7,SPRN_MAS1 | |
| 122 | − andis. r7,r7,MAS1_VALID@h | |
| 123 | − bne match_TLB | |
| 124 | − mfspr r7, SPRN_PID2 | |
| 125 | − slwi r7,r7,16 | |
| 126 | − or r7,r7,r4 | |
| 127 | − mtspr SPRN_MAS6,r7 | |
| 128 | − tlbsx 0,r6 /* Fall through, we had to match */ | |
| 129 | − | |
| 130 | −match_TLB: | |
| 131 | − mfspr r7,SPRN_MAS0 | |
| 132 | − rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ | |
| 133 | − | |
| 134 | − mfspr r7,SPRN_MAS1 /* Insure IPROT set */ | |
| 135 | − oris r7,r7,MAS1_IPROT@h | |
| 136 | − mtspr SPRN_MAS1,r7 | |
| 137 | − tlbwe | |
| 138 | − | |
| 139 | −/* 2. Invalidate all entries except the entry we're executing in */ | |
| 140 | − mfspr r9,SPRN_TLB1CFG | |
| 141 | − andi. r9,r9,0xfff | |
| 142 | − li r6,0 /* Set Entry counter to 0 */ | |
| 143 | −1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 144 | − rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ | |
| 145 | − mtspr SPRN_MAS0,r7 | |
| 146 | − tlbre | |
| 147 | − mfspr r7,SPRN_MAS1 | |
| 148 | − rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ | |
| 149 | − cmpw r3,r6 | |
| 150 | − beq skpinv /* Dont update the current execution TLB */ | |
| 151 | − mtspr SPRN_MAS1,r7 | |
| 152 | − tlbwe | |
| 153 | − isync | |
| 154 | −skpinv: addi r6,r6,1 /* Increment */ | |
| 155 | − cmpw r6,r9 /* Are we done? */ | |
| 156 | − bne 1b /* If not, repeat */ | |
| 157 | − | |
| 158 | − /* Invalidate TLB0 */ | |
| 159 | − li r6,0x04 | |
| 160 | − tlbivax 0,r6 | |
| 161 | − TLBSYNC | |
| 162 | − /* Invalidate TLB1 */ | |
| 163 | − li r6,0x0c | |
| 164 | − tlbivax 0,r6 | |
| 165 | − TLBSYNC | |
| 166 | − | |
| 167 | −/* 3. Setup a temp mapping and jump to it */ | |
| 168 | − andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ | |
| 169 | − addi r5, r5, 0x1 | |
| 170 | − lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 171 | − rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | |
| 172 | − mtspr SPRN_MAS0,r7 | |
| 173 | − tlbre | |
| 174 | − | |
| 175 | − /* grab and fixup the RPN */ | |
| 176 | − mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ | |
| 177 | − rlwinm r6,r6,25,27,31 | |
| 178 | − li r8,-1 | |
| 179 | − addi r6,r6,10 | |
| 180 | − slw r6,r8,r6 /* convert to mask */ | |
| 181 | − | |
| 182 | − bl 1f /* Find our address */ | |
| 183 | −1: mflr r7 | |
| 184 | − | |
| 185 | − mfspr r8,SPRN_MAS3 | |
| 186 | −#ifdef CONFIG_PHYS_64BIT | |
| 187 | − mfspr r23,SPRN_MAS7 | |
| 188 | −#endif | |
| 189 | − and r8,r6,r8 | |
| 190 | − subfic r9,r6,-4096 | |
| 191 | − and r9,r9,r7 | |
| 192 | − | |
| 193 | − or r25,r8,r9 | |
| 194 | − ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) | |
| 195 | − | |
| 196 | − /* Just modify the entry ID and EPN for the temp mapping */ | |
| 197 | − lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 198 | − rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | |
| 199 | − mtspr SPRN_MAS0,r7 | |
| 200 | − xori r6,r4,1 /* Setup TMP mapping in the other Address space */ | |
| 201 | − slwi r6,r6,12 | |
| 202 | − oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h | |
| 203 | − ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l | |
| 204 | − mtspr SPRN_MAS1,r6 | |
| 205 | − mfspr r6,SPRN_MAS2 | |
| 206 | − li r7,0 /* temp EPN = 0 */ | |
| 207 | − rlwimi r7,r6,0,20,31 | |
| 208 | − mtspr SPRN_MAS2,r7 | |
| 209 | − mtspr SPRN_MAS3,r8 | |
| 210 | − tlbwe | |
| 211 | − | |
| 212 | − xori r6,r4,1 | |
| 213 | − slwi r6,r6,5 /* setup new context with other address space */ | |
| 214 | − bl 1f /* Find our address */ | |
| 215 | −1: mflr r9 | |
| 216 | − rlwimi r7,r9,0,20,31 | |
| 217 | − addi r7,r7,(2f - 1b) | |
| 218 | − mtspr SPRN_SRR0,r7 | |
| 219 | − mtspr SPRN_SRR1,r6 | |
| 220 | − rfi | |
| 221 | −2: | |
| 222 | −/* 4. Clear out PIDs & Search info */ | |
| 223 | − li r6,0 | |
| 224 | − mtspr SPRN_MAS6,r6 | |
| 225 | − mtspr SPRN_PID0,r6 | |
| 226 | − | |
| 227 | − mfspr r7,SPRN_MMUCFG | |
| 228 | − rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | |
| 229 | − cmpwi r7,3 | |
| 230 | − bne 2f /* skip if NPIDS != 3 */ | |
| 231 | 97 | |
| 232 | − mtspr SPRN_PID1,r6 | |
| 233 | − mtspr SPRN_PID2,r6 | |
| 234 | − | |
| 235 | −/* 5. Invalidate mapping we started in */ | |
| 236 | −2: | |
| 237 | − lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 238 | − rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | |
| 239 | − mtspr SPRN_MAS0,r7 | |
| 240 | − tlbre | |
| 241 | − mfspr r6,SPRN_MAS1 | |
| 242 | − rlwinm r6,r6,0,2,0 /* clear IPROT */ | |
| 243 | − mtspr SPRN_MAS1,r6 | |
| 244 | − tlbwe | |
| 245 | − /* Invalidate TLB1 */ | |
| 246 | − li r9,0x0c | |
| 247 | − tlbivax 0,r9 | |
| 248 | − TLBSYNC | |
| 249 | − | |
| 250 | −/* The mapping only needs to be cache-coherent on SMP */ | |
| 251 | −#ifdef CONFIG_SMP | |
| 252 | −#define M_IF_SMP MAS2_M | |
| 253 | −#else | |
| 254 | −#define M_IF_SMP 0 | |
| 255 | −#endif | |
| 256 | − | |
| 257 | −/* 6. Setup KERNELBASE mapping in TLB1[0] */ | |
| 258 | − lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ | |
| 259 | − mtspr SPRN_MAS0,r6 | |
| 260 | − lis r6,(MAS1_VALID|MAS1_IPROT)@h | |
| 261 | − ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l | |
| 262 | − mtspr SPRN_MAS1,r6 | |
| 263 | − lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h | |
| 264 | − ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l | |
| 265 | − mtspr SPRN_MAS2,r6 | |
| 266 | − mtspr SPRN_MAS3,r8 | |
| 267 | − tlbwe | |
| 268 | − | |
| 269 | −/* 7. Jump to KERNELBASE mapping */ | |
| 270 | − lis r6,(KERNELBASE & ~0xfff)@h | |
| 271 | − ori r6,r6,(KERNELBASE & ~0xfff)@l | |
| 272 | − lis r7,MSR_KERNEL@h | |
| 273 | − ori r7,r7,MSR_KERNEL@l | |
| 274 | − bl 1f /* Find our address */ | |
| 275 | −1: mflr r9 | |
| 276 | − rlwimi r6,r9,0,20,31 | |
| 277 | − addi r6,r6,(2f - 1b) | |
| 278 | − mtspr SPRN_SRR0,r6 | |
| 279 | − mtspr SPRN_SRR1,r7 | |
| 280 | − rfi /* start execution out of TLB1[0] entry */ | |
| 281 | − | |
| 282 | −/* 8. Clear out the temp mapping */ | |
| 283 | −2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | |
| 284 | − rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | |
| 285 | − mtspr SPRN_MAS0,r7 | |
| 286 | − tlbre | |
| 287 | − mfspr r8,SPRN_MAS1 | |
| 288 | − rlwinm r8,r8,0,2,0 /* clear IPROT */ | |
| 289 | − mtspr SPRN_MAS1,r8 | |
| 290 | − tlbwe | |
| 291 | − /* Invalidate TLB1 */ | |
| 292 | − li r9,0x0c | |
| 293 | − tlbivax 0,r9 | |
| 294 | − TLBSYNC | |
| 98 | +#define ENTRY_MAPPING_BOOT_SETUP | |
| 99 | +#include "fsl_booke_entry_mapping.S" | |
| 100 | +#undef ENTRY_MAPPING_BOOT_SETUP | |
| 295 | 101 | |
| 296 | 102 | /* Establish the interrupt vector offsets */ |
| 297 | 103 | SET_IVOR(0, CriticalInput); |
| @@ -378,17 +378,6 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, · 377 unmodified lines | ||
| 378 | 378 | * single-stepped a copy of the instruction. The address of this |
| 379 | 379 | * copy is p->ainsn.insn. |
| 380 | 380 | */ |
| 381 | −static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | |
| 382 | −{ | |
| 383 | − int ret; | |
| 384 | − unsigned int insn = *p->ainsn.insn; | |
| 385 | − | |
| 386 | − regs->nip = (unsigned long)p->addr; | |
| 387 | − ret = emulate_step(regs, insn); | |
| 388 | − if (ret == 0) | |
| 389 | − regs->nip = (unsigned long)p->addr + 4; | |
| 390 | −} | |
| 391 | − | |
| 392 | 381 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
| 393 | 382 | { |
| 394 | 383 | struct kprobe *cur = kprobe_running(); |
| @@ -406,7 +395,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) · 11 unmodified lines | ||
| 406 | 395 | cur->post_handler(cur, regs, 0); |
| 407 | 396 | } |
| 408 | 397 | |
| 409 | − resume_execution(cur, regs); | |
| 398 | + /* Adjust nip to after the single-stepped instruction */ | |
| 399 | + regs->nip = (unsigned long)cur->addr + 4; | |
| 410 | 400 | regs->msr |= kcb->kprobe_saved_msr; |
| 411 | 401 | |
| 412 | 402 | /*Restore back the original saved kprobes variables and continue. */ |
| @@ -711,6 +711,22 @@ relocate_new_kernel: · 710 unmodified lines | ||
| 711 | 711 | /* r4 = reboot_code_buffer */ |
| 712 | 712 | /* r5 = start_address */ |
| 713 | 713 | |
| 714 | +#ifdef CONFIG_FSL_BOOKE | |
| 715 | + | |
| 716 | + mr r29, r3 | |
| 717 | + mr r30, r4 | |
| 718 | + mr r31, r5 | |
| 719 | + | |
| 720 | +#define ENTRY_MAPPING_KEXEC_SETUP | |
| 721 | +#include "fsl_booke_entry_mapping.S" | |
| 722 | +#undef ENTRY_MAPPING_KEXEC_SETUP | |
| 723 | + | |
| 724 | + mr r3, r29 | |
| 725 | + mr r4, r30 | |
| 726 | + mr r5, r31 | |
| 727 | + | |
| 728 | + li r0, 0 | |
| 729 | +#else | |
| 714 | 730 | li r0, 0 |
| 715 | 731 | |
| 716 | 732 | /* |
| @@ -727,6 +743,7 @@ relocate_new_kernel: · 10 unmodified lines | ||
| 727 | 743 | rfi |
| 728 | 744 | |
| 729 | 745 | 1: |
| 746 | +#endif | |
| 730 | 747 | /* from this point address translation is turned off */ |
| 731 | 748 | /* and interrupts are disabled */ |
| 732 | 749 | |
| @@ -1309,6 +1309,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) · 1308 unmodified lines | ||
| 1309 | 1309 | printk(KERN_WARNING "PCI: Cannot allocate resource region " |
| 1310 | 1310 | "%d of PCI bridge %d, will remap\n", i, bus->number); |
| 1311 | 1311 | clear_resource: |
| 1312 | + res->start = res->end = 0; | |
| 1312 | 1313 | res->flags = 0; |
| 1313 | 1314 | } |
| 1314 | 1315 | |
| @@ -101,7 +101,7 @@ EXPORT_SYMBOL(pci_dram_offset); · 100 unmodified lines | ||
| 101 | 101 | EXPORT_SYMBOL(start_thread); |
| 102 | 102 | EXPORT_SYMBOL(kernel_thread); |
| 103 | 103 | |
| 104 | −#ifndef CONFIG_BOOKE | |
| 104 | +#ifdef CONFIG_PPC_FPU | |
| 105 | 105 | EXPORT_SYMBOL_GPL(cvt_df); |
| 106 | 106 | EXPORT_SYMBOL_GPL(cvt_fd); |
| 107 | 107 | #endif |
| @@ -0,0 +1,193 @@ | ||
| 1 | +/* | |
| 2 | + * Based on swsusp_32.S, modified for FSL BookE by | |
| 3 | + * Anton Vorontsov <avorontsov@ru.mvista.com> | |
| 4 | + * Copyright (c) 2009-2010 MontaVista Software, LLC. | |
| 5 | + */ | |
| 6 | + | |
| 7 | +#include <linux/threads.h> | |
| 8 | +#include <asm/processor.h> | |
| 9 | +#include <asm/page.h> | |
| 10 | +#include <asm/cputable.h> | |
| 11 | +#include <asm/thread_info.h> | |
| 12 | +#include <asm/ppc_asm.h> | |
| 13 | +#include <asm/asm-offsets.h> | |
| 14 | +#include <asm/mmu.h> | |
| 15 | + | |
| 16 | +/* | |
| 17 | + * Structure for storing CPU registers on the save area. | |
| 18 | + */ | |
| 19 | +#define SL_SP 0 | |
| 20 | +#define SL_PC 4 | |
| 21 | +#define SL_MSR 8 | |
| 22 | +#define SL_TCR 0xc | |
| 23 | +#define SL_SPRG0 0x10 | |
| 24 | +#define SL_SPRG1 0x14 | |
| 25 | +#define SL_SPRG2 0x18 | |
| 26 | +#define SL_SPRG3 0x1c | |
| 27 | +#define SL_SPRG4 0x20 | |
| 28 | +#define SL_SPRG5 0x24 | |
| 29 | +#define SL_SPRG6 0x28 | |
| 30 | +#define SL_SPRG7 0x2c | |
| 31 | +#define SL_TBU 0x30 | |
| 32 | +#define SL_TBL 0x34 | |
| 33 | +#define SL_R2 0x38 | |
| 34 | +#define SL_CR 0x3c | |
| 35 | +#define SL_LR 0x40 | |
| 36 | +#define SL_R12 0x44 /* r12 to r31 */ | |
| 37 | +#define SL_SIZE (SL_R12 + 80) | |
| 38 | + | |
| 39 | + .section .data | |
| 40 | + .align 5 | |
| 41 | + | |
| 42 | +_GLOBAL(swsusp_save_area) | |
| 43 | + .space SL_SIZE | |
| 44 | + | |
| 45 | + | |
| 46 | + .section .text | |
| 47 | + .align 5 | |
| 48 | + | |
| 49 | +_GLOBAL(swsusp_arch_suspend) | |
| 50 | + lis r11,swsusp_save_area@h | |
| 51 | + ori r11,r11,swsusp_save_area@l | |
| 52 | + | |
| 53 | + mflr r0 | |
| 54 | + stw r0,SL_LR(r11) | |
| 55 | + mfcr r0 | |
| 56 | + stw r0,SL_CR(r11) | |
| 57 | + stw r1,SL_SP(r11) | |
| 58 | + stw r2,SL_R2(r11) | |
| 59 | + stmw r12,SL_R12(r11) | |
| 60 | + | |
| 61 | + /* Save MSR & TCR */ | |
| 62 | + mfmsr r4 | |
| 63 | + stw r4,SL_MSR(r11) | |
| 64 | + mfspr r4,SPRN_TCR | |
| 65 | + stw r4,SL_TCR(r11) | |
| 66 | + | |
| 67 | + /* Get a stable timebase and save it */ | |
| 68 | +1: mfspr r4,SPRN_TBRU | |
| 69 | + stw r4,SL_TBU(r11) | |
| 70 | + mfspr r5,SPRN_TBRL | |
| 71 | + stw r5,SL_TBL(r11) | |
| 72 | + mfspr r3,SPRN_TBRU | |
| 73 | + cmpw r3,r4 | |
| 74 | + bne 1b | |
| 75 | + | |
| 76 | + /* Save SPRGs */ | |
| 77 | + mfsprg r4,0 | |
| 78 | + stw r4,SL_SPRG0(r11) | |
| 79 | + mfsprg r4,1 | |
| 80 | + stw r4,SL_SPRG1(r11) | |
| 81 | + mfsprg r4,2 | |
| 82 | + stw r4,SL_SPRG2(r11) | |
| 83 | + mfsprg r4,3 | |
| 84 | + stw r4,SL_SPRG3(r11) | |
| 85 | + mfsprg r4,4 | |
| 86 | + stw r4,SL_SPRG4(r11) | |
| 87 | + mfsprg r4,5 | |
| 88 | + stw r4,SL_SPRG5(r11) | |
| 89 | + mfsprg r4,6 | |
| 90 | + stw r4,SL_SPRG6(r11) | |
| 91 | + mfsprg r4,7 | |
| 92 | + stw r4,SL_SPRG7(r11) | |
| 93 | + | |
| 94 | + /* Call the low level suspend stuff (we should probably have made | |
| 95 | + * a stackframe... | |
| 96 | + */ | |
| 97 | + bl swsusp_save | |
| 98 | + | |
| 99 | + /* Restore LR from the save area */ | |
| 100 | + lis r11,swsusp_save_area@h | |
| 101 | + ori r11,r11,swsusp_save_area@l | |
| 102 | + lwz r0,SL_LR(r11) | |
| 103 | + mtlr r0 | |
| 104 | + | |
| 105 | + blr | |
| 106 | + | |
| 107 | +_GLOBAL(swsusp_arch_resume) | |
| 108 | + sync | |
| 109 | + | |
| 110 | + /* Load ptr the list of pages to copy in r3 */ | |
| 111 | + lis r11,(restore_pblist)@h | |
| 112 | + ori r11,r11,restore_pblist@l | |
| 113 | + lwz r3,0(r11) | |
| 114 | + | |
| 115 | + /* Copy the pages. This is a very basic implementation, to | |
| 116 | + * be replaced by something more cache efficient */ | |
| 117 | +1: | |
| 118 | + li r0,256 | |
| 119 | + mtctr r0 | |
| 120 | + lwz r5,pbe_address(r3) /* source */ | |
| 121 | + lwz r6,pbe_orig_address(r3) /* destination */ | |
| 122 | +2: | |
| 123 | + lwz r8,0(r5) | |
| 124 | + lwz r9,4(r5) | |
| 125 | + lwz r10,8(r5) | |
| 126 | + lwz r11,12(r5) | |
| 127 | + addi r5,r5,16 | |
| 128 | + stw r8,0(r6) | |
| 129 | + stw r9,4(r6) | |
| 130 | + stw r10,8(r6) | |
| 131 | + stw r11,12(r6) | |
| 132 | + addi r6,r6,16 | |
| 133 | + bdnz 2b | |
| 134 | + lwz r3,pbe_next(r3) | |
| 135 | + cmpwi 0,r3,0 | |
| 136 | + bne 1b | |
| 137 | + | |
| 138 | + bl flush_dcache_L1 | |
| 139 | + bl flush_instruction_cache | |
| 140 | + | |
| 141 | + lis r11,swsusp_save_area@h | |
| 142 | + ori r11,r11,swsusp_save_area@l | |
| 143 | + | |
| 144 | + lwz r4,SL_SPRG0(r11) | |
| 145 | + mtsprg 0,r4 | |
| 146 | + lwz r4,SL_SPRG1(r11) | |
| 147 | + mtsprg 1,r4 | |
| 148 | + lwz r4,SL_SPRG2(r11) | |
| 149 | + mtsprg 2,r4 | |
| 150 | + lwz r4,SL_SPRG3(r11) | |
| 151 | + mtsprg 3,r4 | |
| 152 | + lwz r4,SL_SPRG4(r11) | |
| 153 | + mtsprg 4,r4 | |
| 154 | + lwz r4,SL_SPRG5(r11) | |
| 155 | + mtsprg 5,r4 | |
| 156 | + lwz r4,SL_SPRG6(r11) | |
| 157 | + mtsprg 6,r4 | |
| 158 | + lwz r4,SL_SPRG7(r11) | |
| 159 | + mtsprg 7,r4 | |
| 160 | + | |
| 161 | + /* restore the MSR */ | |
| 162 | + lwz r3,SL_MSR(r11) | |
| 163 | + mtmsr r3 | |
| 164 | + | |
| 165 | + /* Restore TB */ | |
| 166 | + li r3,0 | |
| 167 | + mtspr SPRN_TBWL,r3 | |
| 168 | + lwz r3,SL_TBU(r11) | |
| 169 | + lwz r4,SL_TBL(r11) | |
| 170 | + mtspr SPRN_TBWU,r3 | |
| 171 | + mtspr SPRN_TBWL,r4 | |
| 172 | + | |
| 173 | + /* Restore TCR and clear any pending bits in TSR. */ | |
| 174 | + lwz r4,SL_TCR(r11) | |
| 175 | + mtspr SPRN_TCR,r4 | |
| 176 | + lis r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h | |
| 177 | + mtspr SPRN_TSR,r4 | |
| 178 | + | |
| 179 | + /* Kick decrementer */ | |
| 180 | + li r0,1 | |
| 181 | + mtdec r0 | |
| 182 | + | |
| 183 | + /* Restore the callee-saved registers and return */ | |
| 184 | + lwz r0,SL_CR(r11) | |
| 185 | + mtcr r0 | |
| 186 | + lwz r2,SL_R2(r11) | |
| 187 | + lmw r12,SL_R12(r11) | |
| 188 | + lwz r1,SL_SP(r11) | |
| 189 | + lwz r0,SL_LR(r11) | |
| 190 | + mtlr r0 | |
| 191 | + | |
| 192 | + li r3,0 | |
| 193 | + blr | |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
| 3 | + * Copyright 2007-2010 Freescale Semiconductor, Inc. | |
| 3 | 4 | * |
| 4 | 5 | * This program is free software; you can redistribute it and/or |
| 5 | 6 | * modify it under the terms of the GNU General Public License |
| @@ -305,7 +306,7 @@ static inline int check_io_access(struct pt_regs *regs) · 299 unmodified lines | ||
| 305 | 306 | #ifndef CONFIG_FSL_BOOKE |
| 306 | 307 | #define get_mc_reason(regs) ((regs)->dsisr) |
| 307 | 308 | #else |
| 308 | −#define get_mc_reason(regs) (mfspr(SPRN_MCSR) & MCSR_MASK) | |
| 309 | +#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) | |
| 309 | 310 | #endif |
| 310 | 311 | #define REASON_FP ESR_FP |
| 311 | 312 | #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) |
| @@ -421,6 +422,91 @@ int machine_check_47x(struct pt_regs *regs) · 109 unmodified lines | ||
| 421 | 422 | return 0; |
| 422 | 423 | } |
| 423 | 424 | #elif defined(CONFIG_E500) |
| 425 | +int machine_check_e500mc(struct pt_regs *regs) | |
| 426 | +{ | |
| 427 | + unsigned long mcsr = mfspr(SPRN_MCSR); | |
| 428 | + unsigned long reason = mcsr; | |
| 429 | + int recoverable = 1; | |
| 430 | + | |
| 431 | + printk("Machine check in kernel mode.\n"); | |
| 432 | + printk("Caused by (from MCSR=%lx): ", reason); | |
| 433 | + | |
| 434 | + if (reason & MCSR_MCP) | |
| 435 | + printk("Machine Check Signal\n"); | |
| 436 | + | |
| 437 | + if (reason & MCSR_ICPERR) { | |
| 438 | + printk("Instruction Cache Parity Error\n"); | |
| 439 | + | |
| 440 | + /* | |
| 441 | + * This is recoverable by invalidating the i-cache. | |
| 442 | + */ | |
| 443 | + mtspr(SPRN_L1CSR1, mfspr(SPRN_L1CSR1) | L1CSR1_ICFI); | |
| 444 | + while (mfspr(SPRN_L1CSR1) & L1CSR1_ICFI) | |
| 445 | + ; | |
| 446 | + | |
| 447 | + /* | |
| 448 | + * This will generally be accompanied by an instruction | |
| 449 | + * fetch error report -- only treat MCSR_IF as fatal | |
| 450 | + * if it wasn't due to an L1 parity error. | |
| 451 | + */ | |
| 452 | + reason &= ~MCSR_IF; | |
| 453 | + } | |
| 454 | + | |
| 455 | + if (reason & MCSR_DCPERR_MC) { | |
| 456 | + printk("Data Cache Parity Error\n"); | |
| 457 | + recoverable = 0; | |
| 458 | + } | |
| 459 | + | |
| 460 | + if (reason & MCSR_L2MMU_MHIT) { | |
| 461 | + printk("Hit on multiple TLB entries\n"); | |
| 462 | + recoverable = 0; | |
| 463 | + } | |
| 464 | + | |
| 465 | + if (reason & MCSR_NMI) | |
| 466 | + printk("Non-maskable interrupt\n"); | |
| 467 | + | |
| 468 | + if (reason & MCSR_IF) { | |
| 469 | + printk("Instruction Fetch Error Report\n"); | |
| 470 | + recoverable = 0; | |
| 471 | + } | |
| 472 | + | |
| 473 | + if (reason & MCSR_LD) { | |
| 474 | + printk("Load Error Report\n"); | |
| 475 | + recoverable = 0; | |
| 476 | + } | |
| 477 | + | |
| 478 | + if (reason & MCSR_ST) { | |
| 479 | + printk("Store Error Report\n"); | |
| 480 | + recoverable = 0; | |
| 481 | + } | |
| 482 | + | |
| 483 | + if (reason & MCSR_LDG) { | |
| 484 | + printk("Guarded Load Error Report\n"); | |
| 485 | + recoverable = 0; | |
| 486 | + } | |
| 487 | + | |
| 488 | + if (reason & MCSR_TLBSYNC) | |
| 489 | + printk("Simultaneous tlbsync operations\n"); | |
| 490 | + | |
| 491 | + if (reason & MCSR_BSL2_ERR) { | |
| 492 | + printk("Level 2 Cache Error\n"); | |
| 493 | + recoverable = 0; | |
| 494 | + } | |
| 495 | + | |
| 496 | + if (reason & MCSR_MAV) { | |
| 497 | + u64 addr; | |
| 498 | + | |
| 499 | + addr = mfspr(SPRN_MCAR); | |
| 500 | + addr |= (u64)mfspr(SPRN_MCARU) << 32; | |
| 501 | + | |
| 502 | + printk("Machine Check %s Address: %#llx\n", | |
| 503 | + reason & MCSR_MEA ? "Effective" : "Physical", addr); | |
| 504 | + } | |
| 505 | + | |
| 506 | + mtspr(SPRN_MCSR, mcsr); | |
| 507 | + return mfspr(SPRN_MCSR) == 0 && recoverable; | |
| 508 | +} | |
| 509 | + | |
| 424 | 510 | int machine_check_e500(struct pt_regs *regs) |
| 425 | 511 | { |
| 426 | 512 | unsigned long reason = get_mc_reason(regs); |
| @@ -223,19 +223,17 @@ SECTIONS · 222 unmodified lines | ||
| 223 | 223 | #endif |
| 224 | 224 | |
| 225 | 225 | /* The initial task and kernel stack */ |
| 226 | − .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { | |
| 227 | − INIT_TASK_DATA(THREAD_SIZE) | |
| 228 | − } | |
| 226 | + INIT_TASK_DATA_SECTION(THREAD_SIZE) | |
| 229 | 227 | |
| 230 | − .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { | |
| 228 | + .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) { | |
| 231 | 229 | PAGE_ALIGNED_DATA(PAGE_SIZE) |
| 232 | 230 | } |
| 233 | 231 | |
| 234 | − .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { | |
| 232 | + .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) { | |
| 235 | 233 | CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) |
| 236 | 234 | } |
| 237 | 235 | |
| 238 | − .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { | |
| 236 | + .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) { | |
| 239 | 237 | READ_MOSTLY_DATA(L1_CACHE_BYTES) |
| 240 | 238 | } |
| 241 | 239 | |
| @@ -164,7 +164,7 @@ static int __init kvmppc_e500_init(void) · 163 unmodified lines | ||
| 164 | 164 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE); |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | −static void __init kvmppc_e500_exit(void) | |
| 167 | +static void __exit kvmppc_e500_exit(void) | |
| 168 | 168 | { |
| 169 | 169 | kvmppc_booke_exit(); |
| 170 | 170 | } |
| @@ -171,6 +171,17 @@ config ISS4xx · 170 unmodified lines | ||
| 171 | 171 | help |
| 172 | 172 | This option enables support for the IBM ISS simulation environment |
| 173 | 173 | |
| 174 | +config ICON | |
| 175 | + bool "Icon" | |
| 176 | + depends on 44x | |
| 177 | + default n | |
| 178 | + select PPC44x_SIMPLE | |
| 179 | + select 440SPe | |
| 180 | + select PCI | |
| 181 | + select PPC4xx_PCI_EXPRESS | |
| 182 | + help | |
| 183 | + This option enables support for the AMCC PPC440SPe evaluation board. | |
| 184 | + | |
| 174 | 185 | #config LUAN |
| 175 | 186 | # bool "Luan" |
| 176 | 187 | # depends on 44x |
| @@ -61,7 +61,8 @@ static char *board[] __initdata = { · 60 unmodified lines | ||
| 61 | 61 | "amcc,redwood", |
| 62 | 62 | "amcc,sequoia", |
| 63 | 63 | "amcc,taishan", |
| 64 | − "amcc,yosemite" | |
| 64 | + "amcc,yosemite", | |
| 65 | + "mosaixtech,icon" | |
| 65 | 66 | }; |
| 66 | 67 | |
| 67 | 68 | static int __init ppc44x_probe(void) |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved. | |
| 2 | + * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved. | |
| 3 | 3 | * |
| 4 | 4 | * Author: Andy Fleming <afleming@freescale.com> |
| 5 | 5 | * |
| @@ -154,6 +154,10 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) · 148 unmodified lines | ||
| 154 | 154 | * Setup the architecture |
| 155 | 155 | * |
| 156 | 156 | */ |
| 157 | +#ifdef CONFIG_SMP | |
| 158 | +extern void __init mpc85xx_smp_init(void); | |
| 159 | +#endif | |
| 160 | + | |
| 157 | 161 | static void __init mpc85xx_mds_setup_arch(void) |
| 158 | 162 | { |
| 159 | 163 | struct device_node *np; |
| @@ -194,6 +198,10 @@ static void __init mpc85xx_mds_setup_arch(void) · 34 unmodified lines | ||
| 194 | 198 | } |
| 195 | 199 | #endif |
| 196 | 200 | |
| 201 | +#ifdef CONFIG_SMP | |
| 202 | + mpc85xx_smp_init(); | |
| 203 | +#endif | |
| 204 | + | |
| 197 | 205 | #ifdef CONFIG_QUICC_ENGINE |
| 198 | 206 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); |
| 199 | 207 | if (!np) { |
| @@ -271,9 +279,49 @@ static void __init mpc85xx_mds_setup_arch(void) · 71 unmodified lines | ||
| 271 | 279 | BCSR_UCC_RGMII, BCSR_UCC_RTBI); |
| 272 | 280 | } |
| 273 | 281 | |
| 282 | + } else if (machine_is(p1021_mds)) { | |
| 283 | +#define BCSR11_ENET_MICRST (0x1 << 5) | |
| 284 | + /* Reset Micrel PHY */ | |
| 285 | + clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | |
| 286 | + setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); | |
| 274 | 287 | } |
| 288 | + | |
| 275 | 289 | iounmap(bcsr_regs); |
| 276 | 290 | } |
| 291 | + | |
| 292 | + if (machine_is(p1021_mds)) { | |
| 293 | +#define MPC85xx_PMUXCR_OFFSET 0x60 | |
| 294 | +#define MPC85xx_PMUXCR_QE0 0x00008000 | |
| 295 | +#define MPC85xx_PMUXCR_QE3 0x00001000 | |
| 296 | +#define MPC85xx_PMUXCR_QE9 0x00000040 | |
| 297 | +#define MPC85xx_PMUXCR_QE12 0x00000008 | |
| 298 | + static __be32 __iomem *pmuxcr; | |
| 299 | + | |
| 300 | + np = of_find_node_by_name(NULL, "global-utilities"); | |
| 301 | + | |
| 302 | + if (np) { | |
| 303 | + pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET; | |
| 304 | + | |
| 305 | + if (!pmuxcr) | |
| 306 | + printk(KERN_EMERG "Error: Alternate function" | |
| 307 | + " signal multiplex control register not" | |
| 308 | + " mapped!\n"); | |
| 309 | + else | |
| 310 | + /* P1021 has pins muxed for QE and other functions. To | |
| 311 | + * enable QE UEC mode, we need to set bit QE0 for UCC1 | |
| 312 | + * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9 | |
| 313 | + * and QE12 for QE MII management singals in PMUXCR | |
| 314 | + * register. | |
| 315 | + */ | |
| 316 | + setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 | | |
| 317 | + MPC85xx_PMUXCR_QE3 | | |
| 318 | + MPC85xx_PMUXCR_QE9 | | |
| 319 | + MPC85xx_PMUXCR_QE12); | |
| 320 | + | |
| 321 | + of_node_put(np); | |
| 322 | + } | |
| 323 | + | |
| 324 | + } | |
| 277 | 325 | #endif /* CONFIG_QUICC_ENGINE */ |
| 278 | 326 | |
| 279 | 327 | #ifdef CONFIG_SWIOTLB |
| @@ -330,6 +378,16 @@ static struct of_device_id mpc85xx_ids[] = { · 50 unmodified lines | ||
| 330 | 378 | {}, |
| 331 | 379 | }; |
| 332 | 380 | |
| 381 | +static struct of_device_id p1021_ids[] = { | |
| 382 | + { .type = "soc", }, | |
| 383 | + { .compatible = "soc", }, | |
| 384 | + { .compatible = "simple-bus", }, | |
| 385 | + { .type = "qe", }, | |
| 386 | + { .compatible = "fsl,qe", }, | |
| 387 | + { .compatible = "gianfar", }, | |
| 388 | + {}, | |
| 389 | +}; | |
| 390 | + | |
| 333 | 391 | static int __init mpc85xx_publish_devices(void) |
| 334 | 392 | { |
| 335 | 393 | if (machine_is(mpc8568_mds)) |
| @@ -342,11 +400,22 @@ static int __init mpc85xx_publish_devices(void) · 6 unmodified lines | ||
| 342 | 400 | |
| 343 | 401 | return 0; |
| 344 | 402 | } |
| 403 | + | |
| 404 | +static int __init p1021_publish_devices(void) | |
| 405 | +{ | |
| 406 | + /* Publish the QE devices */ | |
| 407 | + of_platform_bus_probe(NULL, p1021_ids, NULL); | |
| 408 | + | |
| 409 | + return 0; | |
| 410 | +} | |
| 411 | + | |
| 345 | 412 | machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); |
| 346 | 413 | machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); |
| 414 | +machine_device_initcall(p1021_mds, p1021_publish_devices); | |
| 347 | 415 | |
| 348 | 416 | machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); |
| 349 | 417 | machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); |
| 418 | +machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier); | |
| 350 | 419 | |
| 351 | 420 | static void __init mpc85xx_mds_pic_init(void) |
| 352 | 421 | { |
| @@ -366,7 +435,7 @@ static void __init mpc85xx_mds_pic_init(void) · 13 unmodified lines | ||
| 366 | 435 | |
| 367 | 436 | mpic = mpic_alloc(np, r.start, |
| 368 | 437 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
| 369 | − MPIC_BROKEN_FRR_NIRQS, | |
| 438 | + MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, | |
| 370 | 439 | 0, 256, " OpenPIC "); |
| 371 | 440 | BUG_ON(mpic == NULL); |
| 372 | 441 | of_node_put(np); |
| @@ -380,7 +449,11 @@ static void __init mpc85xx_mds_pic_init(void) · 7 unmodified lines | ||
| 380 | 449 | if (!np) |
| 381 | 450 | return; |
| 382 | 451 | } |
| 383 | − qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); | |
| 452 | + if (machine_is(p1021_mds)) | |
| 453 | + qe_ic_init(np, 0, qe_ic_cascade_low_mpic, | |
| 454 | + qe_ic_cascade_high_mpic); | |
| 455 | + else | |
| 456 | + qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); | |
| 384 | 457 | of_node_put(np); |
| 385 | 458 | #endif /* CONFIG_QUICC_ENGINE */ |
| 386 | 459 | } |
| @@ -426,3 +499,26 @@ define_machine(mpc8569_mds) { · 39 unmodified lines | ||
| 426 | 499 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, |
| 427 | 500 | #endif |
| 428 | 501 | }; |
| 502 | + | |
| 503 | +static int __init p1021_mds_probe(void) | |
| 504 | +{ | |
| 505 | + unsigned long root = of_get_flat_dt_root(); | |
| 506 | + | |
| 507 | + return of_flat_dt_is_compatible(root, "fsl,P1021MDS"); | |
| 508 | + | |
| 509 | +} | |
| 510 | + | |
| 511 | +define_machine(p1021_mds) { | |
| 512 | + .name = "P1021 MDS", | |
| 513 | + .probe = p1021_mds_probe, | |
| 514 | + .setup_arch = mpc85xx_mds_setup_arch, | |
| 515 | + .init_IRQ = mpc85xx_mds_pic_init, | |
| 516 | + .get_irq = mpic_get_irq, | |
| 517 | + .restart = fsl_rstcr_restart, | |
| 518 | + .calibrate_decr = generic_calibrate_decr, | |
| 519 | + .progress = udbg_progress, | |
| 520 | +#ifdef CONFIG_PCI | |
| 521 | + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | |
| 522 | +#endif | |
| 523 | +}; | |
| 524 | + | |
| @@ -1066,7 +1066,7 @@ static int __init cell_iommu_fixed_mapping_init(void) · 1065 unmodified lines | ||
| 1066 | 1066 | fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT); |
| 1067 | 1067 | fsize = lmb_phys_mem_size(); |
| 1068 | 1068 | |
| 1069 | − if ((fbase + fsize) <= 0x800000000) | |
| 1069 | + if ((fbase + fsize) <= 0x800000000ul) | |
| 1070 | 1070 | hbase = 0; /* use the device tree window */ |
| 1071 | 1071 | else { |
| 1072 | 1072 | /* If we're over 32 GB we need to cheat. We can't map all of |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | − * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved. | |
| 2 | + * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. | |
| 3 | 3 | * |
| 4 | 4 | * Author: Tony Li <tony.li@freescale.com> |
| 5 | 5 | * Jason Jin <Jason.jin@freescale.com> |
| @@ -22,14 +22,20 @@ · 16 unmodified lines | ||
| 22 | 22 | #include <asm/prom.h> |
| 23 | 23 | #include <asm/hw_irq.h> |
| 24 | 24 | #include <asm/ppc-pci.h> |
| 25 | +#include <asm/mpic.h> | |
| 25 | 26 | #include "fsl_msi.h" |
| 26 | 27 | |
| 28 | +LIST_HEAD(msi_head); | |
| 29 | + | |
| 27 | 30 | struct fsl_msi_feature { |
| 28 | 31 | u32 fsl_pic_ip; |
| 29 | 32 | u32 msiir_offset; |
| 30 | 33 | }; |
| 31 | 34 | |
| 32 | −static struct fsl_msi *fsl_msi; | |
| 35 | +struct fsl_msi_cascade_data { | |
| 36 | + struct fsl_msi *msi_data; | |
| 37 | + int index; | |
| 38 | +}; | |
| 33 | 39 | |
| 34 | 40 | static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) |
| 35 | 41 | { |
| @@ -54,10 +60,12 @@ static struct irq_chip fsl_msi_chip = { · 18 unmodified lines | ||
| 54 | 60 | static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, |
| 55 | 61 | irq_hw_number_t hw) |
| 56 | 62 | { |
| 63 | + struct fsl_msi *msi_data = h->host_data; | |
| 57 | 64 | struct irq_chip *chip = &fsl_msi_chip; |
| 58 | 65 | |
| 59 | 66 | irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; |
| 60 | 67 | |
| 68 | + set_irq_chip_data(virq, msi_data); | |
| 61 | 69 | set_irq_chip_and_handler(virq, chip, handle_edge_irq); |
| 62 | 70 | |
| 63 | 71 | return 0; |
| @@ -96,11 +104,12 @@ static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) · 32 unmodified lines | ||
| 96 | 104 | static void fsl_teardown_msi_irqs(struct pci_dev *pdev) |
| 97 | 105 | { |
| 98 | 106 | struct msi_desc *entry; |
| 99 | − struct fsl_msi *msi_data = fsl_msi; | |
| 107 | + struct fsl_msi *msi_data; | |
| 100 | 108 | |
| 101 | 109 | list_for_each_entry(entry, &pdev->msi_list, list) { |
| 102 | 110 | if (entry->irq == NO_IRQ) |
| 103 | 111 | continue; |
| 112 | + msi_data = get_irq_data(entry->irq); | |
| 104 | 113 | set_irq_msi(entry->irq, NULL); |
| 105 | 114 | msi_bitmap_free_hwirqs(&msi_data->bitmap, |
| 106 | 115 | virq_to_hw(entry->irq), 1); |
| @@ -111,9 +120,10 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) · 4 unmodified lines | ||
| 111 | 120 | } |
| 112 | 121 | |
| 113 | 122 | static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, |
| 114 | − struct msi_msg *msg) | |
| 123 | + struct msi_msg *msg, | |
| 124 | + struct fsl_msi *fsl_msi_data) | |
| 115 | 125 | { |
| 116 | − struct fsl_msi *msi_data = fsl_msi; | |
| 126 | + struct fsl_msi *msi_data = fsl_msi_data; | |
| 117 | 127 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
| 118 | 128 | u32 base = 0; |
| 119 | 129 | |
| @@ -130,14 +140,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, · 10 unmodified lines | ||
| 130 | 140 | |
| 131 | 141 | static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
| 132 | 142 | { |
| 133 | − int rc, hwirq; | |
| 143 | + int rc, hwirq = -ENOMEM; | |
| 134 | 144 | unsigned int virq; |
| 135 | 145 | struct msi_desc *entry; |
| 136 | 146 | struct msi_msg msg; |
| 137 | − struct fsl_msi *msi_data = fsl_msi; | |
| 147 | + struct fsl_msi *msi_data; | |
| 138 | 148 | |
| 139 | 149 | list_for_each_entry(entry, &pdev->msi_list, list) { |
| 140 | − hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); | |
| 150 | + list_for_each_entry(msi_data, &msi_head, list) { | |
| 151 | + hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); | |
| 152 | + if (hwirq >= 0) | |
| 153 | + break; | |
| 154 | + } | |
| 155 | + | |
| 141 | 156 | if (hwirq < 0) { |
| 142 | 157 | rc = hwirq; |
| 143 | 158 | pr_debug("%s: fail allocating msi interrupt\n", |
| @@ -154,25 +169,31 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) · 10 unmodified lines | ||
| 154 | 169 | rc = -ENOSPC; |
| 155 | 170 | goto out_free; |
| 156 | 171 | } |
| 172 | + set_irq_data(virq, msi_data); | |
| 157 | 173 | set_irq_msi(virq, entry); |
| 158 | 174 | |
| 159 | − fsl_compose_msi_msg(pdev, hwirq, &msg); | |
| 175 | + fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data); | |
| 160 | 176 | write_msi_msg(virq, &msg); |
| 161 | 177 | } |
| 162 | 178 | return 0; |
| 163 | 179 | |
| 164 | 180 | out_free: |
| 181 | + /* free by the caller of this function */ | |
| 165 | 182 | return rc; |
| 166 | 183 | } |
| 167 | 184 | |
| 168 | 185 | static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) |
| 169 | 186 | { |
| 170 | 187 | unsigned int cascade_irq; |
| 171 | − struct fsl_msi *msi_data = fsl_msi; | |
| 188 | + struct fsl_msi *msi_data; | |
| 172 | 189 | int msir_index = -1; |
| 173 | 190 | u32 msir_value = 0; |
| 174 | 191 | u32 intr_index; |
| 175 | 192 | u32 have_shift = 0; |
| 193 | + struct fsl_msi_cascade_data *cascade_data; | |
| 194 | + | |
| 195 | + cascade_data = (struct fsl_msi_cascade_data *)get_irq_data(irq); | |
| 196 | + msi_data = cascade_data->msi_data; | |
| 176 | 197 | |
| 177 | 198 | raw_spin_lock(&desc->lock); |
| 178 | 199 | if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { |
| @@ -187,13 +208,13 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) · 8 unmodified lines | ||
| 187 | 208 | if (unlikely(desc->status & IRQ_INPROGRESS)) |
| 188 | 209 | goto unlock; |
| 189 | 210 | |
| 190 | − msir_index = (int)desc->handler_data; | |
| 211 | + msir_index = cascade_data->index; | |
| 191 | 212 | |
| 192 | 213 | if (msir_index >= NR_MSI_REG) |
| 193 | 214 | cascade_irq = NO_IRQ; |
| 194 | 215 | |
| 195 | 216 | desc->status |= IRQ_INPROGRESS; |
| 196 | − switch (fsl_msi->feature & FSL_PIC_IP_MASK) { | |
| 217 | + switch (msi_data->feature & FSL_PIC_IP_MASK) { | |
| 197 | 218 | case FSL_PIC_IP_MPIC: |
| 198 | 219 | msir_value = fsl_msi_read(msi_data->msi_regs, |
| 199 | 220 | msir_index * 0x10); |
| @@ -229,6 +250,30 @@ unlock: · 29 unmodified lines | ||
| 229 | 250 | raw_spin_unlock(&desc->lock); |
| 230 | 251 | } |
| 231 | 252 | |
| 253 | +static int fsl_of_msi_remove(struct of_device *ofdev) | |
| 254 | +{ | |
| 255 | + struct fsl_msi *msi = ofdev->dev.platform_data; | |
| 256 | + int virq, i; | |
| 257 | + struct fsl_msi_cascade_data *cascade_data; | |
| 258 | + | |
| 259 | + if (msi->list.prev != NULL) | |
| 260 | + list_del(&msi->list); | |
| 261 | + for (i = 0; i < NR_MSI_REG; i++) { | |
| 262 | + virq = msi->msi_virqs[i]; | |
| 263 | + if (virq != NO_IRQ) { | |
| 264 | + cascade_data = get_irq_data(virq); | |
| 265 | + kfree(cascade_data); | |
| 266 | + irq_dispose_mapping(virq); | |
| 267 | + } | |
| 268 | + } | |
| 269 | + if (msi->bitmap.bitmap) | |
| 270 | + msi_bitmap_free(&msi->bitmap); | |
| 271 | + iounmap(msi->msi_regs); | |
| 272 | + kfree(msi); | |
| 273 | + | |
| 274 | + return 0; | |
| 275 | +} | |
| 276 | + | |
| 232 | 277 | static int __devinit fsl_of_msi_probe(struct of_device *dev, |
| 233 | 278 | const struct of_device_id *match) |
| 234 | 279 | { |
| @@ -239,15 +284,18 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, · 4 unmodified lines | ||
| 239 | 284 | int virt_msir; |
| 240 | 285 | const u32 *p; |
| 241 | 286 | struct fsl_msi_feature *features = match->data; |
| 287 | + struct fsl_msi_cascade_data *cascade_data = NULL; | |
| 288 | + int len; | |
| 289 | + u32 offset; | |
| 242 | 290 | |
| 243 | 291 | printk(KERN_DEBUG "Setting up Freescale MSI support\n"); |
| 244 | 292 | |
| 245 | 293 | msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); |
| 246 | 294 | if (!msi) { |
| 247 | 295 | dev_err(&dev->dev, "No memory for MSI structure\n"); |
| 248 | − err = -ENOMEM; | |
| 249 | − goto error_out; | |
| 296 | + return -ENOMEM; | |
| 250 | 297 | } |
| 298 | + dev->dev.platform_data = msi; | |
| 251 | 299 | |
| 252 | 300 | msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, |
| 253 | 301 | NR_MSI_IRQS, &fsl_msi_host_ops, 0); |
| @@ -298,27 +346,47 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, · 44 unmodified lines | ||
| 298 | 346 | err = -EINVAL; |
| 299 | 347 | goto error_out; |
| 300 | 348 | } |
| 349 | + offset = 0; | |
| 350 | + p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len); | |
| 351 | + if (p) | |
| 352 | + offset = *p / IRQS_PER_MSI_REG; | |
| 301 | 353 | |
| 302 | 354 | count /= sizeof(u32); |
| 303 | − for (i = 0; i < count / 2; i++) { | |
| 304 | − if (i > NR_MSI_REG) | |
| 305 | − break; | |
| 355 | + for (i = 0; i < min(count / 2, NR_MSI_REG); i++) { | |
| 306 | 356 | virt_msir = irq_of_parse_and_map(dev->dev.of_node, i); |
| 307 | 357 | if (virt_msir != NO_IRQ) { |
| 308 | − set_irq_data(virt_msir, (void *)i); | |
| 358 | + cascade_data = kzalloc( | |
| 359 | + sizeof(struct fsl_msi_cascade_data), | |
| 360 | + GFP_KERNEL); | |
| 361 | + if (!cascade_data) { | |
| 362 | + dev_err(&dev->dev, | |
| 363 | + "No memory for MSI cascade data\n"); | |
| 364 | + err = -ENOMEM; | |
| 365 | + goto error_out; | |
| 366 | + } | |
| 367 | + msi->msi_virqs[i] = virt_msir; | |
| 368 | + cascade_data->index = i + offset; | |
| 369 | + cascade_data->msi_data = msi; | |
| 370 | + set_irq_data(virt_msir, (void *)cascade_data); | |
| 309 | 371 | set_irq_chained_handler(virt_msir, fsl_msi_cascade); |
| 310 | 372 | } |
| 311 | 373 | } |
| 312 | 374 | |
| 313 | − fsl_msi = msi; | |
| 375 | + list_add_tail(&msi->list, &msi_head); | |
| 314 | 376 | |
| 315 | − WARN_ON(ppc_md.setup_msi_irqs); | |
| 316 | − ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; | |
| 317 | − ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; | |
| 318 | − ppc_md.msi_check_device = fsl_msi_check_device; | |
| 377 | + /* The multiple setting ppc_md.setup_msi_irqs will not harm things */ | |
| 378 | + if (!ppc_md.setup_msi_irqs) { | |
| 379 | + ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; | |
| 380 | + ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; | |
| 381 | + ppc_md.msi_check_device = fsl_msi_check_device; | |
| 382 | + } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) { | |
| 383 | + dev_err(&dev->dev, "Different MSI driver already installed!\n"); | |
| 384 | + err = -ENODEV; | |
| 385 | + goto error_out; | |
| 386 | + } | |
| 319 | 387 | return 0; |
| 320 | 388 | error_out: |
| 321 | − kfree(msi); | |
| 389 | + fsl_of_msi_remove(dev); | |
| 322 | 390 | return err; |
| 323 | 391 | } |
| 324 | 392 | |
| @@ -351,6 +419,7 @@ static struct of_platform_driver fsl_of_msi_driver = { · 26 unmodified lines | ||
| 351 | 419 | .of_match_table = fsl_of_msi_ids, |
| 352 | 420 | }, |
| 353 | 421 | .probe = fsl_of_msi_probe, |
| 422 | + .remove = fsl_of_msi_remove, | |
| 354 | 423 | }; |
| 355 | 424 | |
| 356 | 425 | static __init int fsl_of_msi_init(void) |
| @@ -32,8 +32,11 @@ struct fsl_msi { · 31 unmodified lines | ||
| 32 | 32 | u32 msi_addr_hi; |
| 33 | 33 | void __iomem *msi_regs; |
| 34 | 34 | u32 feature; |
| 35 | + int msi_virqs[NR_MSI_REG]; | |
| 35 | 36 | |
| 36 | 37 | struct msi_bitmap bitmap; |
| 38 | + | |
| 39 | + struct list_head list; /* support multiple MSI banks */ | |
| 37 | 40 | }; |
| 38 | 41 | |
| 39 | 42 | #endif /* _POWERPC_SYSDEV_FSL_MSI_H */ |
| @@ -1426,7 +1426,7 @@ int fsl_rio_setup(struct of_device *dev) · 1425 unmodified lines | ||
| 1426 | 1426 | port->iores.flags = IORESOURCE_MEM; |
| 1427 | 1427 | port->iores.name = "rio_io_win"; |
| 1428 | 1428 | |
| 1429 | − priv->pwirq = irq_of_parse_and_map(dev->node, 0); | |
| 1429 | + priv->pwirq = irq_of_parse_and_map(dev->dev.of_node, 0); | |
| 1430 | 1430 | priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2); |
| 1431 | 1431 | priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3); |
| 1432 | 1432 | priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4); |
| @@ -974,6 +974,123 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = · 973 unmodified lines | ||
| 974 | 974 | .setup_utl = ppc460ex_pciex_init_utl, |
| 975 | 975 | }; |
| 976 | 976 | |
| 977 | +static int __init ppc460sx_pciex_core_init(struct device_node *np) | |
| 978 | +{ | |
| 979 | + /* HSS drive amplitude */ | |
| 980 | + mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211); | |
| 981 | + mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211); | |
| 982 | + mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211); | |
| 983 | + mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211); | |
| 984 | + mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211); | |
| 985 | + mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211); | |
| 986 | + mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211); | |
| 987 | + mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211); | |
| 988 | + | |
| 989 | + mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211); | |
| 990 | + mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211); | |
| 991 | + mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211); | |
| 992 | + mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211); | |
| 993 | + | |
| 994 | + mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211); | |
| 995 | + mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211); | |
| 996 | + mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211); | |
| 997 | + mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211); | |
| 998 | + | |
| 999 | + /* HSS TX pre-emphasis */ | |
| 1000 | + mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987); | |
| 1001 | + mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987); | |
| 1002 | + mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987); | |
| 1003 | + mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987); | |
| 1004 | + mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987); | |
| 1005 | + mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987); | |
| 1006 | + mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987); | |
| 1007 | + mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987); | |
| 1008 | + | |
| 1009 | + mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987); | |
| 1010 | + mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987); | |
| 1011 | + mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987); | |
| 1012 | + mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987); | |
| 1013 | + | |
| 1014 | + mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987); | |
| 1015 | + mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987); | |
| 1016 | + mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987); | |
| 1017 | + mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987); | |
| 1018 | + | |
| 1019 | + /* HSS TX calibration control */ | |
| 1020 | + mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222); | |
| 1021 | + mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000); | |
| 1022 | + mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000); | |
| 1023 | + | |
| 1024 | + /* HSS TX slew control */ | |
| 1025 | + mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF); | |
| 1026 | + mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); | |
| 1027 | + mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); | |
| 1028 | + | |
| 1029 | + udelay(100); | |
| 1030 | + | |
| 1031 | + /* De-assert PLLRESET */ | |
| 1032 | + dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0); | |
| 1033 | + | |
| 1034 | + /* Reset DL, UTL, GPL before configuration */ | |
| 1035 | + mtdcri(SDR0, PESDR0_460SX_RCSSET, | |
| 1036 | + PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | |
| 1037 | + mtdcri(SDR0, PESDR1_460SX_RCSSET, | |
| 1038 | + PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | |
| 1039 | + mtdcri(SDR0, PESDR2_460SX_RCSSET, | |
| 1040 | + PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | |
| 1041 | + | |
| 1042 | + udelay(100); | |
| 1043 | + | |
| 1044 | + /* | |
| 1045 | + * If bifurcation is not enabled, u-boot would have disabled the | |
| 1046 | + * third PCIe port | |
| 1047 | + */ | |
| 1048 | + if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) == | |
| 1049 | + 0x00000001)) { | |
| 1050 | + printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n"); | |
| 1051 | + printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n"); | |
| 1052 | + return 3; | |
| 1053 | + } | |
| 1054 | + | |
| 1055 | + printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n"); | |
| 1056 | + return 2; | |
| 1057 | +} | |
| 1058 | + | |
| 1059 | +static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | |
| 1060 | +{ | |
| 1061 | + | |
| 1062 | + if (port->endpoint) | |
| 1063 | + dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | |
| 1064 | + 0x01000000, 0); | |
| 1065 | + else | |
| 1066 | + dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | |
| 1067 | + 0, 0x01000000); | |
| 1068 | + | |
| 1069 | + /*Gen-1*/ | |
| 1070 | + mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000); | |
| 1071 | + | |
| 1072 | + dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, | |
| 1073 | + (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), | |
| 1074 | + PESDRx_RCSSET_RSTPYN); | |
| 1075 | + | |
| 1076 | + port->has_ibpre = 1; | |
| 1077 | + | |
| 1078 | + return 0; | |
| 1079 | +} | |
| 1080 | + | |
| 1081 | +static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) | |
| 1082 | +{ | |
| 1083 | + /* Max 128 Bytes */ | |
| 1084 | + out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); | |
| 1085 | + return 0; | |
| 1086 | +} | |
| 1087 | + | |
| 1088 | +static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { | |
| 1089 | + .core_init = ppc460sx_pciex_core_init, | |
| 1090 | + .port_init_hw = ppc460sx_pciex_init_port_hw, | |
| 1091 | + .setup_utl = ppc460sx_pciex_init_utl, | |
| 1092 | +}; | |
| 1093 | + | |
| 977 | 1094 | #endif /* CONFIG_44x */ |
| 978 | 1095 | |
| 979 | 1096 | #ifdef CONFIG_40x |
| @@ -1089,6 +1206,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) · 109 unmodified lines | ||
| 1089 | 1206 | } |
| 1090 | 1207 | if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) |
| 1091 | 1208 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; |
| 1209 | + if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) | |
| 1210 | + ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; | |
| 1092 | 1211 | #endif /* CONFIG_44x */ |
| 1093 | 1212 | #ifdef CONFIG_40x |
| 1094 | 1213 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) |
| @@ -323,6 +323,64 @@ · 322 unmodified lines | ||
| 323 | 323 | #define PESDR0_460EX_IHS1 0x036C |
| 324 | 324 | #define PESDR0_460EX_IHS2 0x036D |
| 325 | 325 | |
| 326 | +/* | |
| 327 | + * 460SX addtional DCRs | |
| 328 | + */ | |
| 329 | +#define PESDRn_460SX_RCEI 0x02 | |
| 330 | + | |
| 331 | +#define PESDR0_460SX_HSSL0DAMP 0x320 | |
| 332 | +#define PESDR0_460SX_HSSL1DAMP 0x321 | |
| 333 | +#define PESDR0_460SX_HSSL2DAMP 0x322 | |
| 334 | +#define PESDR0_460SX_HSSL3DAMP 0x323 | |
| 335 | +#define PESDR0_460SX_HSSL4DAMP 0x324 | |
| 336 | +#define PESDR0_460SX_HSSL5DAMP 0x325 | |
| 337 | +#define PESDR0_460SX_HSSL6DAMP 0x326 | |
| 338 | +#define PESDR0_460SX_HSSL7DAMP 0x327 | |
| 339 | + | |
| 340 | +#define PESDR1_460SX_HSSL0DAMP 0x354 | |
| 341 | +#define PESDR1_460SX_HSSL1DAMP 0x355 | |
| 342 | +#define PESDR1_460SX_HSSL2DAMP 0x356 | |
| 343 | +#define PESDR1_460SX_HSSL3DAMP 0x357 | |
| 344 | + | |
| 345 | +#define PESDR2_460SX_HSSL0DAMP 0x384 | |
| 346 | +#define PESDR2_460SX_HSSL1DAMP 0x385 | |
| 347 | +#define PESDR2_460SX_HSSL2DAMP 0x386 | |
| 348 | +#define PESDR2_460SX_HSSL3DAMP 0x387 | |
| 349 | + | |
| 350 | +#define PESDR0_460SX_HSSL0COEFA 0x328 | |
| 351 | +#define PESDR0_460SX_HSSL1COEFA 0x329 | |
| 352 | +#define PESDR0_460SX_HSSL2COEFA 0x32A | |
| 353 | +#define PESDR0_460SX_HSSL3COEFA 0x32B | |
| 354 | +#define PESDR0_460SX_HSSL4COEFA 0x32C | |
| 355 | +#define PESDR0_460SX_HSSL5COEFA 0x32D | |
| 356 | +#define PESDR0_460SX_HSSL6COEFA 0x32E | |
| 357 | +#define PESDR0_460SX_HSSL7COEFA 0x32F | |
| 358 | + | |
| 359 | +#define PESDR1_460SX_HSSL0COEFA 0x358 | |
| 360 | +#define PESDR1_460SX_HSSL1COEFA 0x359 | |
| 361 | +#define PESDR1_460SX_HSSL2COEFA 0x35A | |
| 362 | +#define PESDR1_460SX_HSSL3COEFA 0x35B | |
| 363 | + | |
| 364 | +#define PESDR2_460SX_HSSL0COEFA 0x388 | |
| 365 | +#define PESDR2_460SX_HSSL1COEFA 0x389 | |
| 366 | +#define PESDR2_460SX_HSSL2COEFA 0x38A | |
| 367 | +#define PESDR2_460SX_HSSL3COEFA 0x38B | |
| 368 | + | |
| 369 | +#define PESDR0_460SX_HSSL1CALDRV 0x339 | |
| 370 | +#define PESDR1_460SX_HSSL1CALDRV 0x361 | |
| 371 | +#define PESDR2_460SX_HSSL1CALDRV 0x391 | |
| 372 | + | |
| 373 | +#define PESDR0_460SX_HSSSLEW 0x338 | |
| 374 | +#define PESDR1_460SX_HSSSLEW 0x360 | |
| 375 | +#define PESDR2_460SX_HSSSLEW 0x390 | |
| 376 | + | |
| 377 | +#define PESDR0_460SX_HSSCTLSET 0x31E | |
| 378 | +#define PESDR1_460SX_HSSCTLSET 0x352 | |
| 379 | +#define PESDR2_460SX_HSSCTLSET 0x382 | |
| 380 | + | |
| 381 | +#define PESDR0_460SX_RCSSET 0x304 | |
| 382 | +#define PESDR1_460SX_RCSSET 0x344 | |
| 383 | +#define PESDR2_460SX_RCSSET 0x374 | |
| 326 | 384 | /* |
| 327 | 385 | * Of the above, some are common offsets from the base |
| 328 | 386 | */ |
| @@ -181,7 +181,7 @@ static int __init appldata_os_init(void) · 180 unmodified lines | ||
| 181 | 181 | goto out; |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | − appldata_os_data = kzalloc(max_size, GFP_DMA); | |
| 184 | + appldata_os_data = kzalloc(max_size, GFP_KERNEL | GFP_DMA); | |
| 185 | 185 | if (appldata_os_data == NULL) { |
| 186 | 186 | rc = -ENOMEM; |
| 187 | 187 | goto out; |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | # |
| 2 | 2 | # Automatically generated make config: don't edit |
| 3 | −# Linux kernel version: 2.6.34-rc3 | |
| 4 | −# Fri Apr 9 09:57:10 2010 | |
| 3 | +# Linux kernel version: 2.6.35-rc1 | |
| 4 | +# Fri Jun 4 11:32:40 2010 | |
| 5 | 5 | # |
| 6 | 6 | CONFIG_SCHED_MC=y |
| 7 | 7 | CONFIG_MMU=y |
| @@ -35,11 +35,13 @@ CONFIG_CONSTRUCTORS=y · 27 unmodified lines | ||
| 35 | 35 | CONFIG_EXPERIMENTAL=y |
| 36 | 36 | CONFIG_LOCK_KERNEL=y |
| 37 | 37 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
| 38 | +CONFIG_CROSS_COMPILE="" | |
| 38 | 39 | CONFIG_LOCALVERSION="" |
| 39 | 40 | CONFIG_LOCALVERSION_AUTO=y |
| 40 | 41 | CONFIG_HAVE_KERNEL_GZIP=y |
| 41 | 42 | CONFIG_HAVE_KERNEL_BZIP2=y |
| 42 | 43 | CONFIG_HAVE_KERNEL_LZMA=y |
| 44 | +CONFIG_HAVE_KERNEL_LZO=y | |
| 43 | 45 | CONFIG_KERNEL_GZIP=y |
| 44 | 46 | # CONFIG_KERNEL_BZIP2 is not set |
| 45 | 47 | # CONFIG_KERNEL_LZMA is not set |
| @@ -77,6 +79,7 @@ CONFIG_CGROUP_NS=y · 31 unmodified lines | ||
| 77 | 79 | # CONFIG_CGROUP_CPUACCT is not set |
| 78 | 80 | # CONFIG_RESOURCE_COUNTERS is not set |
| 79 | 81 | # CONFIG_CGROUP_SCHED is not set |
| 82 | +# CONFIG_BLK_CGROUP is not set | |
| 80 | 83 | CONFIG_SYSFS_DEPRECATED=y |
| 81 | 84 | CONFIG_SYSFS_DEPRECATED_V2=y |
| 82 | 85 | # CONFIG_RELAY is not set |
| @@ -157,7 +160,6 @@ CONFIG_STOP_MACHINE=y · 74 unmodified lines | ||
| 157 | 160 | CONFIG_BLOCK=y |
| 158 | 161 | CONFIG_BLK_DEV_BSG=y |
| 159 | 162 | # CONFIG_BLK_DEV_INTEGRITY is not set |
| 160 | −# CONFIG_BLK_CGROUP is not set | |
| 161 | 163 | CONFIG_BLOCK_COMPAT=y |
| 162 | 164 | |
| 163 | 165 | # |
| @@ -166,7 +168,6 @@ CONFIG_BLOCK_COMPAT=y · 2 unmodified lines | ||
| 166 | 168 | CONFIG_IOSCHED_NOOP=y |
| 167 | 169 | CONFIG_IOSCHED_DEADLINE=y |
| 168 | 170 | CONFIG_IOSCHED_CFQ=y |
| 169 | −# CONFIG_CFQ_GROUP_IOSCHED is not set | |
| 170 | 171 | CONFIG_DEFAULT_DEADLINE=y |
| 171 | 172 | # CONFIG_DEFAULT_CFQ is not set |
| 172 | 173 | # CONFIG_DEFAULT_NOOP is not set |
| @@ -247,7 +248,6 @@ CONFIG_64BIT=y · 74 unmodified lines | ||
| 247 | 248 | CONFIG_SMP=y |
| 248 | 249 | CONFIG_NR_CPUS=32 |
| 249 | 250 | CONFIG_HOTPLUG_CPU=y |
| 250 | −# CONFIG_SCHED_BOOK is not set | |
| 251 | 251 | CONFIG_COMPAT=y |
| 252 | 252 | CONFIG_SYSVIPC_COMPAT=y |
| 253 | 253 | CONFIG_AUDIT_ARCH=y |
| @@ -320,7 +320,6 @@ CONFIG_COMPAT_BINFMT_ELF=y · 66 unmodified lines | ||
| 320 | 320 | # CONFIG_HAVE_AOUT is not set |
| 321 | 321 | CONFIG_BINFMT_MISC=m |
| 322 | 322 | CONFIG_FORCE_MAX_ZONEORDER=9 |
| 323 | −# CONFIG_PROCESS_DEBUG is not set | |
| 324 | 323 | CONFIG_PFAULT=y |
| 325 | 324 | # CONFIG_SHARED_KERNEL is not set |
| 326 | 325 | # CONFIG_CMM is not set |
| @@ -457,6 +456,7 @@ CONFIG_NF_CONNTRACK=m · 130 unmodified lines | ||
| 457 | 456 | # CONFIG_IP6_NF_IPTABLES is not set |
| 458 | 457 | # CONFIG_IP_DCCP is not set |
| 459 | 458 | CONFIG_IP_SCTP=m |
| 459 | +# CONFIG_NET_SCTPPROBE is not set | |
| 460 | 460 | # CONFIG_SCTP_DBG_MSG is not set |
| 461 | 461 | # CONFIG_SCTP_DBG_OBJCNT is not set |
| 462 | 462 | # CONFIG_SCTP_HMAC_NONE is not set |
| @@ -465,6 +465,7 @@ CONFIG_SCTP_HMAC_MD5=y · 2 unmodified lines | ||
| 465 | 465 | # CONFIG_RDS is not set |
| 466 | 466 | # CONFIG_TIPC is not set |
| 467 | 467 | # CONFIG_ATM is not set |
| 468 | +# CONFIG_L2TP is not set | |
| 468 | 469 | # CONFIG_BRIDGE is not set |
| 469 | 470 | # CONFIG_VLAN_8021Q is not set |
| 470 | 471 | # CONFIG_DECNET is not set |
| @@ -525,6 +526,7 @@ CONFIG_NET_ACT_NAT=m · 54 unmodified lines | ||
| 525 | 526 | # CONFIG_NET_CLS_IND is not set |
| 526 | 527 | CONFIG_NET_SCH_FIFO=y |
| 527 | 528 | # CONFIG_DCB is not set |
| 529 | +CONFIG_RPS=y | |
| 528 | 530 | |
| 529 | 531 | # |
| 530 | 532 | # Network testing |
| @@ -546,6 +548,7 @@ CONFIG_CAN_VCAN=m · 15 unmodified lines | ||
| 546 | 548 | # CONFIG_WIMAX is not set |
| 547 | 549 | # CONFIG_RFKILL is not set |
| 548 | 550 | # CONFIG_NET_9P is not set |
| 551 | +# CONFIG_CAIF is not set | |
| 549 | 552 | # CONFIG_PCMCIA is not set |
| 550 | 553 | CONFIG_CCW=y |
| 551 | 554 | |
| @@ -728,6 +731,7 @@ CONFIG_VIRTIO_NET=m · 176 unmodified lines | ||
| 728 | 731 | # Character devices |
| 729 | 732 | # |
| 730 | 733 | CONFIG_DEVKMEM=y |
| 734 | +# CONFIG_N_GSM is not set | |
| 731 | 735 | CONFIG_UNIX98_PTYS=y |
| 732 | 736 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set |
| 733 | 737 | CONFIG_LEGACY_PTYS=y |
| @@ -775,6 +779,7 @@ CONFIG_S390_TAPE_34XX=m · 41 unmodified lines | ||
| 775 | 779 | # CONFIG_MONREADER is not set |
| 776 | 780 | CONFIG_MONWRITER=m |
| 777 | 781 | CONFIG_S390_VMUR=m |
| 782 | +# CONFIG_RAMOOPS is not set | |
| 778 | 783 | |
| 779 | 784 | # |
| 780 | 785 | # PPS support |
| @@ -788,10 +793,6 @@ CONFIG_S390_VMUR=m · 7 unmodified lines | ||
| 788 | 793 | # CONFIG_NEW_LEDS is not set |
| 789 | 794 | CONFIG_ACCESSIBILITY=y |
| 790 | 795 | # CONFIG_AUXDISPLAY is not set |
| 791 | − | |
| 792 | −# | |
| 793 | −# TI VLYNQ | |
| 794 | −# | |
| 795 | 796 | # CONFIG_STAGING is not set |
| 796 | 797 | |
| 797 | 798 | # |
| @@ -976,6 +977,7 @@ CONFIG_DEBUG_MEMORY_INIT=y · 178 unmodified lines | ||
| 976 | 977 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set |
| 977 | 978 | CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y |
| 978 | 979 | # CONFIG_LKDTM is not set |
| 980 | +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set | |
| 979 | 981 | # CONFIG_FAULT_INJECTION is not set |
| 980 | 982 | # CONFIG_LATENCYTOP is not set |
| 981 | 983 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
| @@ -1010,6 +1012,7 @@ CONFIG_BRANCH_PROFILE_NONE=y · 28 unmodified lines | ||
| 1010 | 1012 | CONFIG_KPROBE_EVENT=y |
| 1011 | 1013 | # CONFIG_RING_BUFFER_BENCHMARK is not set |
| 1012 | 1014 | # CONFIG_DYNAMIC_DEBUG is not set |
| 1015 | +# CONFIG_ATOMIC64_SELFTEST is not set | |
| 1013 | 1016 | CONFIG_SAMPLES=y |
| 1014 | 1017 | # CONFIG_SAMPLE_TRACEPOINTS is not set |
| 1015 | 1018 | # CONFIG_SAMPLE_TRACE_EVENTS is not set |
| @@ -14,6 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | #define L1_CACHE_BYTES 256 |
| 15 | 15 | #define L1_CACHE_SHIFT 8 |
| 16 | 16 | |
| 17 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 17 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 18 | 18 | |
| 19 | 19 | #endif |
| @@ -55,8 +55,10 @@ void *module_alloc(unsigned long size) · 54 unmodified lines | ||
| 55 | 55 | /* Free memory returned from module_alloc */ |
| 56 | 56 | void module_free(struct module *mod, void *module_region) |
| 57 | 57 | { |
| 58 | − vfree(mod->arch.syminfo); | |
| 59 | − mod->arch.syminfo = NULL; | |
| 58 | + if (mod) { | |
| 59 | + vfree(mod->arch.syminfo); | |
| 60 | + mod->arch.syminfo = NULL; | |
| 61 | + } | |
| 60 | 62 | vfree(module_region); |
| 61 | 63 | } |
| 62 | 64 | |
| @@ -264,7 +264,7 @@ restore_registers: · 263 unmodified lines | ||
| 264 | 264 | lghi %r2,0 |
| 265 | 265 | br %r14 |
| 266 | 266 | |
| 267 | − .section .data.nosave,"aw",@progbits | |
| 267 | + .section .data..nosave,"aw",@progbits | |
| 268 | 268 | .align 8 |
| 269 | 269 | .Ldisabled_wait_31: |
| 270 | 270 | .long 0x000a0000,0x00000000 |
| @@ -761,7 +761,7 @@ static int __init kvm_s390_init(void) · 760 unmodified lines | ||
| 761 | 761 | * to hold the maximum amount of facilites. On the other hand, we |
| 762 | 762 | * only set facilities that are known to work in KVM. |
| 763 | 763 | */ |
| 764 | − facilities = (unsigned long long *) get_zeroed_page(GFP_DMA); | |
| 764 | + facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); | |
| 765 | 765 | if (!facilities) { |
| 766 | 766 | kvm_exit(); |
| 767 | 767 | return -ENOMEM; |
| @@ -113,7 +113,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) · 112 unmodified lines | ||
| 113 | 113 | { |
| 114 | 114 | struct kvm_s390_interrupt_info *inti; |
| 115 | 115 | |
| 116 | − inti = kzalloc(sizeof(*inti), GFP_KERNEL); | |
| 116 | + inti = kzalloc(sizeof(*inti), GFP_ATOMIC); | |
| 117 | 117 | if (!inti) |
| 118 | 118 | return -ENOMEM; |
| 119 | 119 | inti->type = KVM_S390_SIGP_STOP; |
| @@ -105,7 +105,7 @@ static int · 104 unmodified lines | ||
| 105 | 105 | dcss_set_subcodes(void) |
| 106 | 106 | { |
| 107 | 107 | #ifdef CONFIG_64BIT |
| 108 | − char *name = kmalloc(8 * sizeof(char), GFP_DMA); | |
| 108 | + char *name = kmalloc(8 * sizeof(char), GFP_KERNEL | GFP_DMA); | |
| 109 | 109 | unsigned long rx, ry; |
| 110 | 110 | int rc; |
| 111 | 111 | |
| @@ -252,12 +252,13 @@ dcss_diag_translate_rc (int vm_rc) { · 140 unmodified lines | ||
| 252 | 252 | static int |
| 253 | 253 | query_segment_type (struct dcss_segment *seg) |
| 254 | 254 | { |
| 255 | − struct qin64 *qin = kmalloc (sizeof(struct qin64), GFP_DMA); | |
| 256 | − struct qout64 *qout = kmalloc (sizeof(struct qout64), GFP_DMA); | |
| 257 | − | |
| 258 | − int diag_cc, rc, i; | |
| 259 | 255 | unsigned long dummy, vmrc; |
| 256 | + int diag_cc, rc, i; | |
| 257 | + struct qout64 *qout; | |
| 258 | + struct qin64 *qin; | |
| 260 | 259 | |
| 260 | + qin = kmalloc(sizeof(*qin), GFP_KERNEL | GFP_DMA); | |
| 261 | + qout = kmalloc(sizeof(*qout), GFP_KERNEL | GFP_DMA); | |
| 261 | 262 | if ((qin == NULL) || (qout == NULL)) { |
| 262 | 263 | rc = -ENOMEM; |
| 263 | 264 | goto out_free; |
| @@ -286,7 +287,7 @@ query_segment_type (struct dcss_segment *seg) · 22 unmodified lines | ||
| 286 | 287 | copy data for the new format. */ |
| 287 | 288 | if (segext_scode == DCSS_SEGEXT) { |
| 288 | 289 | struct qout64_old *qout_old; |
| 289 | − qout_old = kzalloc(sizeof(struct qout64_old), GFP_DMA); | |
| 290 | + qout_old = kzalloc(sizeof(*qout_old), GFP_KERNEL | GFP_DMA); | |
| 290 | 291 | if (qout_old == NULL) { |
| 291 | 292 | rc = -ENOMEM; |
| 292 | 293 | goto out_free; |
| @@ -407,11 +408,11 @@ segment_overlaps_others (struct dcss_segment *seg) · 114 unmodified lines | ||
| 407 | 408 | static int |
| 408 | 409 | __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long *end) |
| 409 | 410 | { |
| 410 | − struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment), | |
| 411 | − GFP_DMA); | |
| 412 | − int rc, diag_cc; | |
| 413 | 411 | unsigned long start_addr, end_addr, dummy; |
| 412 | + struct dcss_segment *seg; | |
| 413 | + int rc, diag_cc; | |
| 414 | 414 | |
| 415 | + seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA); | |
| 415 | 416 | if (seg == NULL) { |
| 416 | 417 | rc = -ENOMEM; |
| 417 | 418 | goto out; |
| @@ -9,7 +9,7 @@ config SUPERH · 8 unmodified lines | ||
| 9 | 9 | def_bool y |
| 10 | 10 | select EMBEDDED |
| 11 | 11 | select HAVE_CLK |
| 12 | − select HAVE_IDE | |
| 12 | + select HAVE_IDE if HAS_IOPORT | |
| 13 | 13 | select HAVE_LMB |
| 14 | 14 | select HAVE_OPROFILE |
| 15 | 15 | select HAVE_GENERIC_DMA_COHERENT |
| @@ -174,6 +174,9 @@ config ARCH_HAS_DEFAULT_IDLE · 158 unmodified lines | ||
| 174 | 174 | config ARCH_HAS_CPU_IDLE_WAIT |
| 175 | 175 | def_bool y |
| 176 | 176 | |
| 177 | +config NO_IOPORT | |
| 178 | + bool | |
| 179 | + | |
| 177 | 180 | config IO_TRAPPED |
| 178 | 181 | bool |
| 179 | 182 | |
| @@ -776,6 +779,17 @@ config ENTRY_OFFSET · 596 unmodified lines | ||
| 776 | 779 | default "0x00010000" if PAGE_SIZE_64KB |
| 777 | 780 | default "0x00000000" |
| 778 | 781 | |
| 782 | +config ROMIMAGE_MMCIF | |
| 783 | + bool "Include MMCIF loader in romImage (EXPERIMENTAL)" | |
| 784 | + depends on CPU_SUBTYPE_SH7724 && EXPERIMENTAL | |
| 785 | + help | |
| 786 | + Say Y here to include experimental MMCIF loading code in | |
| 787 | + romImage. With this enabled it is possible to write the romImage | |
| 788 | + kernel image to an MMC card and boot the kernel straight from | |
| 789 | + the reset vector. At reset the processor Mask ROM will load the | |
| 790 | + first part of the romImage which in turn loads the rest the kernel | |
| 791 | + image to RAM using the MMCIF hardware block. | |
| 792 | + | |
| 779 | 793 | choice |
| 780 | 794 | prompt "Kernel command line" |
| 781 | 795 | optional |
| @@ -154,6 +154,7 @@ config SH_SDK7786 · 153 unmodified lines | ||
| 154 | 154 | bool "SDK7786" |
| 155 | 155 | depends on CPU_SUBTYPE_SH7786 |
| 156 | 156 | select SYS_SUPPORTS_PCI |
| 157 | + select NO_IOPORT if !PCI | |
| 157 | 158 | help |
| 158 | 159 | Select SDK7786 if configuring for a Renesas Technology Europe |
| 159 | 160 | SH7786-65nm board. |
| @@ -190,6 +191,7 @@ config SH_URQUELL · 30 unmodified lines | ||
| 190 | 191 | depends on CPU_SUBTYPE_SH7786 |
| 191 | 192 | select ARCH_REQUIRE_GPIOLIB |
| 192 | 193 | select SYS_SUPPORTS_PCI |
| 194 | + select NO_IOPORT if !PCI | |
| 193 | 195 | |
| 194 | 196 | config SH_MIGOR |
| 195 | 197 | bool "Migo-R" |
| @@ -286,6 +288,7 @@ config SH_LBOX_RE2 · 90 unmodified lines | ||
| 286 | 288 | config SH_X3PROTO |
| 287 | 289 | bool "SH-X3 Prototype board" |
| 288 | 290 | depends on CPU_SUBTYPE_SHX3 |
| 291 | + select NO_IOPORT if !PCI | |
| 289 | 292 | |
| 290 | 293 | config SH_MAGIC_PANEL_R2 |
| 291 | 294 | bool "Magic Panel R2" |
| @@ -328,7 +328,7 @@ static struct soc_camera_platform_info camera_info = { · 327 unmodified lines | ||
| 328 | 328 | .set_capture = camera_set_capture, |
| 329 | 329 | }; |
| 330 | 330 | |
| 331 | −struct soc_camera_link camera_link = { | |
| 331 | +static struct soc_camera_link camera_link = { | |
| 332 | 332 | .bus_id = 0, |
| 333 | 333 | .add_device = ap325rxa_camera_add, |
| 334 | 334 | .del_device = ap325rxa_camera_del, |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/device.h> |
| 13 | 13 | #include <linux/platform_device.h> |
| 14 | 14 | #include <linux/mfd/sh_mobile_sdhi.h> |
| 15 | +#include <linux/mmc/host.h> | |
| 16 | +#include <linux/mmc/sh_mmcif.h> | |
| 15 | 17 | #include <linux/mtd/physmap.h> |
| 16 | 18 | #include <linux/gpio.h> |
| 17 | 19 | #include <linux/interrupt.h> |
| @@ -26,7 +28,6 @@ · 8 unmodified lines | ||
| 26 | 28 | #include <linux/mmc/host.h> |
| 27 | 29 | #include <linux/input.h> |
| 28 | 30 | #include <linux/input/sh_keysc.h> |
| 29 | −#include <linux/mfd/sh_mobile_sdhi.h> | |
| 30 | 31 | #include <video/sh_mobile_lcdc.h> |
| 31 | 32 | #include <sound/sh_fsi.h> |
| 32 | 33 | #include <media/sh_mobile_ceu.h> |
| @@ -139,7 +140,7 @@ static struct resource sh_eth_resources[] = { · 106 unmodified lines | ||
| 139 | 140 | }, |
| 140 | 141 | }; |
| 141 | 142 | |
| 142 | −struct sh_eth_plat_data sh_eth_plat = { | |
| 143 | +static struct sh_eth_plat_data sh_eth_plat = { | |
| 143 | 144 | .phy = 0x1f, /* SMSC LAN8700 */ |
| 144 | 145 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
| 145 | 146 | .ether_link_active_low = 1 |
| @@ -159,7 +160,7 @@ static struct platform_device sh_eth_device = { · 13 unmodified lines | ||
| 159 | 160 | }; |
| 160 | 161 | |
| 161 | 162 | /* USB0 host */ |
| 162 | −void usb0_port_power(int port, int power) | |
| 163 | +static void usb0_port_power(int port, int power) | |
| 163 | 164 | { |
| 164 | 165 | gpio_set_value(GPIO_PTB4, power); |
| 165 | 166 | } |
| @@ -195,7 +196,7 @@ static struct platform_device usb0_host_device = { · 29 unmodified lines | ||
| 195 | 196 | }; |
| 196 | 197 | |
| 197 | 198 | /* USB1 host/function */ |
| 198 | −void usb1_port_power(int port, int power) | |
| 199 | +static void usb1_port_power(int port, int power) | |
| 199 | 200 | { |
| 200 | 201 | gpio_set_value(GPIO_PTB5, power); |
| 201 | 202 | } |
| @@ -421,7 +422,7 @@ static int ts_init(void) · 219 unmodified lines | ||
| 421 | 422 | return 0; |
| 422 | 423 | } |
| 423 | 424 | |
| 424 | −struct tsc2007_platform_data tsc2007_info = { | |
| 425 | +static struct tsc2007_platform_data tsc2007_info = { | |
| 425 | 426 | .model = 2007, |
| 426 | 427 | .x_plate_ohms = 180, |
| 427 | 428 | .get_pendown_state = ts_get_pendown_state, |
| @@ -436,7 +437,7 @@ static struct i2c_board_info ts_i2c_clients = { · 8 unmodified lines | ||
| 436 | 437 | }; |
| 437 | 438 | |
| 438 | 439 | #ifdef CONFIG_MFD_SH_MOBILE_SDHI |
| 439 | −/* SHDI0 */ | |
| 440 | +/* SDHI0 */ | |
| 440 | 441 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) |
| 441 | 442 | { |
| 442 | 443 | gpio_set_value(GPIO_PTB6, state); |
| @@ -474,7 +475,8 @@ static struct platform_device sdhi0_device = { · 31 unmodified lines | ||
| 474 | 475 | }, |
| 475 | 476 | }; |
| 476 | 477 | |
| 477 | −/* SHDI1 */ | |
| 478 | +#if !defined(CONFIG_MMC_SH_MMCIF) | |
| 479 | +/* SDHI1 */ | |
| 478 | 480 | static void sdhi1_set_pwr(struct platform_device *pdev, int state) |
| 479 | 481 | { |
| 480 | 482 | gpio_set_value(GPIO_PTB7, state); |
| @@ -511,6 +513,7 @@ static struct platform_device sdhi1_device = { · 30 unmodified lines | ||
| 511 | 513 | .hwblk_id = HWBLK_SDHI1, |
| 512 | 514 | }, |
| 513 | 515 | }; |
| 516 | +#endif /* CONFIG_MMC_SH_MMCIF */ | |
| 514 | 517 | |
| 515 | 518 | #else |
| 516 | 519 | |
| @@ -720,7 +723,7 @@ static struct clk fsimckb_clk = { · 203 unmodified lines | ||
| 720 | 723 | .rate = 0, /* unknown */ |
| 721 | 724 | }; |
| 722 | 725 | |
| 723 | −struct sh_fsi_platform_info fsi_info = { | |
| 726 | +static struct sh_fsi_platform_info fsi_info = { | |
| 724 | 727 | .portb_flags = SH_FSI_BRS_INV | |
| 725 | 728 | SH_FSI_OUT_SLAVE_MODE | |
| 726 | 729 | SH_FSI_IN_SLAVE_MODE | |
| @@ -777,7 +780,7 @@ static struct platform_device irda_device = { · 50 unmodified lines | ||
| 777 | 780 | #include <media/ak881x.h> |
| 778 | 781 | #include <media/sh_vou.h> |
| 779 | 782 | |
| 780 | −struct ak881x_pdata ak881x_pdata = { | |
| 783 | +static struct ak881x_pdata ak881x_pdata = { | |
| 781 | 784 | .flags = AK881X_IF_MODE_SLAVE, |
| 782 | 785 | }; |
| 783 | 786 | |
| @@ -786,7 +789,7 @@ static struct i2c_board_info ak8813 = { · 2 unmodified lines | ||
| 786 | 789 | .platform_data = &ak881x_pdata, |
| 787 | 790 | }; |
| 788 | 791 | |
| 789 | −struct sh_vou_pdata sh_vou_pdata = { | |
| 792 | +static struct sh_vou_pdata sh_vou_pdata = { | |
| 790 | 793 | .bus_fmt = SH_VOU_BUS_8BIT, |
| 791 | 794 | .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, |
| 792 | 795 | .board_info = &ak8813, |
| @@ -819,6 +822,58 @@ static struct platform_device vou_device = { · 26 unmodified lines | ||
| 819 | 822 | }, |
| 820 | 823 | }; |
| 821 | 824 | |
| 825 | +#if defined(CONFIG_MMC_SH_MMCIF) | |
| 826 | +/* SH_MMCIF */ | |
| 827 | +static void mmcif_set_pwr(struct platform_device *pdev, int state) | |
| 828 | +{ | |
| 829 | + gpio_set_value(GPIO_PTB7, state); | |
| 830 | +} | |
| 831 | + | |
| 832 | +static void mmcif_down_pwr(struct platform_device *pdev) | |
| 833 | +{ | |
| 834 | + gpio_set_value(GPIO_PTB7, 0); | |
| 835 | +} | |
| 836 | + | |
| 837 | +static struct resource sh_mmcif_resources[] = { | |
| 838 | + [0] = { | |
| 839 | + .name = "SH_MMCIF", | |
| 840 | + .start = 0xA4CA0000, | |
| 841 | + .end = 0xA4CA00FF, | |
| 842 | + .flags = IORESOURCE_MEM, | |
| 843 | + }, | |
| 844 | + [1] = { | |
| 845 | + /* MMC2I */ | |
| 846 | + .start = 29, | |
| 847 | + .flags = IORESOURCE_IRQ, | |
| 848 | + }, | |
| 849 | + [2] = { | |
| 850 | + /* MMC3I */ | |
| 851 | + .start = 30, | |
| 852 | + .flags = IORESOURCE_IRQ, | |
| 853 | + }, | |
| 854 | +}; | |
| 855 | + | |
| 856 | +static struct sh_mmcif_plat_data sh_mmcif_plat = { | |
| 857 | + .set_pwr = mmcif_set_pwr, | |
| 858 | + .down_pwr = mmcif_down_pwr, | |
| 859 | + .sup_pclk = 0, /* SH7724: Max Pclk/2 */ | |
| 860 | + .caps = MMC_CAP_4_BIT_DATA | | |
| 861 | + MMC_CAP_8_BIT_DATA | | |
| 862 | + MMC_CAP_NEEDS_POLL, | |
| 863 | + .ocr = MMC_VDD_32_33 | MMC_VDD_33_34, | |
| 864 | +}; | |
| 865 | + | |
| 866 | +static struct platform_device sh_mmcif_device = { | |
| 867 | + .name = "sh_mmcif", | |
| 868 | + .id = 0, | |
| 869 | + .dev = { | |
| 870 | + .platform_data = &sh_mmcif_plat, | |
| 871 | + }, | |
| 872 | + .num_resources = ARRAY_SIZE(sh_mmcif_resources), | |
| 873 | + .resource = sh_mmcif_resources, | |
| 874 | +}; | |
| 875 | +#endif | |
| 876 | + | |
| 822 | 877 | static struct platform_device *ecovec_devices[] __initdata = { |
| 823 | 878 | &heartbeat_device, |
| 824 | 879 | &nor_flash_device, |
| @@ -831,7 +886,9 @@ static struct platform_device *ecovec_devices[] __initdata = { · 6 unmodified lines | ||
| 831 | 886 | &keysc_device, |
| 832 | 887 | #ifdef CONFIG_MFD_SH_MOBILE_SDHI |
| 833 | 888 | &sdhi0_device, |
| 889 | +#if !defined(CONFIG_MMC_SH_MMCIF) | |
| 834 | 890 | &sdhi1_device, |
| 891 | +#endif | |
| 835 | 892 | #else |
| 836 | 893 | &msiof0_device, |
| 837 | 894 | #endif |
| @@ -841,6 +898,9 @@ static struct platform_device *ecovec_devices[] __initdata = { · 3 unmodified lines | ||
| 841 | 898 | &fsi_device, |
| 842 | 899 | &irda_device, |
| 843 | 900 | &vou_device, |
| 901 | +#if defined(CONFIG_MMC_SH_MMCIF) | |
| 902 | + &sh_mmcif_device, | |
| 903 | +#endif | |
| 844 | 904 | }; |
| 845 | 905 | |
| 846 | 906 | #ifdef CONFIG_I2C |
| @@ -1134,6 +1194,7 @@ static int __init arch_setup(void) · 287 unmodified lines | ||
| 1134 | 1194 | gpio_request(GPIO_PTB6, NULL); |
| 1135 | 1195 | gpio_direction_output(GPIO_PTB6, 0); |
| 1136 | 1196 | |
| 1197 | +#if !defined(CONFIG_MMC_SH_MMCIF) | |
| 1137 | 1198 | /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ |
| 1138 | 1199 | gpio_request(GPIO_FN_SDHI1CD, NULL); |
| 1139 | 1200 | gpio_request(GPIO_FN_SDHI1WP, NULL); |
| @@ -1148,6 +1209,7 @@ static int __init arch_setup(void) · 8 unmodified lines | ||
| 1148 | 1209 | |
| 1149 | 1210 | /* I/O buffer drive ability is high for SDHI1 */ |
| 1150 | 1211 | __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); |
| 1212 | +#endif /* CONFIG_MMC_SH_MMCIF */ | |
| 1151 | 1213 | #else |
| 1152 | 1214 | /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ |
| 1153 | 1215 | gpio_request(GPIO_FN_MSIOF0_TXD, NULL); |
| @@ -1223,6 +1285,25 @@ static int __init arch_setup(void) · 69 unmodified lines | ||
| 1223 | 1285 | gpio_request(GPIO_PTU5, NULL); |
| 1224 | 1286 | gpio_direction_output(GPIO_PTU5, 0); |
| 1225 | 1287 | |
| 1288 | +#if defined(CONFIG_MMC_SH_MMCIF) | |
| 1289 | + /* enable MMCIF (needs DS2.6,7 set to OFF,ON) */ | |
| 1290 | + gpio_request(GPIO_FN_MMC_D7, NULL); | |
| 1291 | + gpio_request(GPIO_FN_MMC_D6, NULL); | |
| 1292 | + gpio_request(GPIO_FN_MMC_D5, NULL); | |
| 1293 | + gpio_request(GPIO_FN_MMC_D4, NULL); | |
| 1294 | + gpio_request(GPIO_FN_MMC_D3, NULL); | |
| 1295 | + gpio_request(GPIO_FN_MMC_D2, NULL); | |
| 1296 | + gpio_request(GPIO_FN_MMC_D1, NULL); | |
| 1297 | + gpio_request(GPIO_FN_MMC_D0, NULL); | |
| 1298 | + gpio_request(GPIO_FN_MMC_CLK, NULL); | |
| 1299 | + gpio_request(GPIO_FN_MMC_CMD, NULL); | |
| 1300 | + gpio_request(GPIO_PTB7, NULL); | |
| 1301 | + gpio_direction_output(GPIO_PTB7, 0); | |
| 1302 | + | |
| 1303 | + /* I/O buffer drive ability is high for MMCIF */ | |
| 1304 | + __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); | |
| 1305 | +#endif | |
| 1306 | + | |
| 1226 | 1307 | /* enable I2C device */ |
| 1227 | 1308 | i2c_register_board_info(0, i2c0_devices, |
| 1228 | 1309 | ARRAY_SIZE(i2c0_devices)); |
| @@ -181,7 +181,7 @@ static int migor_nand_flash_ready(struct mtd_info *mtd) · 180 unmodified lines | ||
| 181 | 181 | return gpio_get_value(GPIO_PTA1); /* NAND_RBn */ |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | −struct platform_nand_data migor_nand_flash_data = { | |
| 184 | +static struct platform_nand_data migor_nand_flash_data = { | |
| 185 | 185 | .chip = { |
| 186 | 186 | .nr_chips = 1, |
| 187 | 187 | .partitions = migor_nand_flash_partitions, |
| @@ -283,7 +283,7 @@ static struct clk fsimcka_clk = { · 282 unmodified lines | ||
| 283 | 283 | }; |
| 284 | 284 | |
| 285 | 285 | /* change J20, J21, J22 pin to 1-2 connection to use slave mode */ |
| 286 | −struct sh_fsi_platform_info fsi_info = { | |
| 286 | +static struct sh_fsi_platform_info fsi_info = { | |
| 287 | 287 | .porta_flags = SH_FSI_BRS_INV | |
| 288 | 288 | SH_FSI_OUT_SLAVE_MODE | |
| 289 | 289 | SH_FSI_IN_SLAVE_MODE | |
| @@ -371,7 +371,7 @@ static struct resource sh_eth_resources[] = { · 81 unmodified lines | ||
| 371 | 371 | }, |
| 372 | 372 | }; |
| 373 | 373 | |
| 374 | −struct sh_eth_plat_data sh_eth_plat = { | |
| 374 | +static struct sh_eth_plat_data sh_eth_plat = { | |
| 375 | 375 | .phy = 0x1f, /* SMSC LAN8187 */ |
| 376 | 376 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
| 377 | 377 | }; |
| @@ -535,7 +535,7 @@ static struct platform_device irda_device = { · 157 unmodified lines | ||
| 535 | 535 | #include <media/ak881x.h> |
| 536 | 536 | #include <media/sh_vou.h> |
| 537 | 537 | |
| 538 | −struct ak881x_pdata ak881x_pdata = { | |
| 538 | +static struct ak881x_pdata ak881x_pdata = { | |
| 539 | 539 | .flags = AK881X_IF_MODE_SLAVE, |
| 540 | 540 | }; |
| 541 | 541 | |
| @@ -545,7 +545,7 @@ static struct i2c_board_info ak8813 = { · 3 unmodified lines | ||
| 545 | 545 | .platform_data = &ak881x_pdata, |
| 546 | 546 | }; |
| 547 | 547 | |
| 548 | −struct sh_vou_pdata sh_vou_pdata = { | |
| 548 | +static struct sh_vou_pdata sh_vou_pdata = { | |
| 549 | 549 | .bus_fmt = SH_VOU_BUS_8BIT, |
| 550 | 550 | .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, |
| 551 | 551 | .board_info = &ak8813, |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | SECTIONS |
| 2 | 2 | { |
| 3 | − .rodata.compressed : { | |
| 3 | + .rodata..compressed : { | |
| 4 | 4 | input_len = .; |
| 5 | 5 | LONG(input_data_end - input_data) input_data = .; |
| 6 | 6 | *(.data) |
| @@ -1,16 +1,21 @@ | ||
| 1 | 1 | # |
| 2 | 2 | # linux/arch/sh/boot/romimage/Makefile |
| 3 | 3 | # |
| 4 | −# create an image suitable for burning to flash from zImage | |
| 4 | +# create an romImage file suitable for burning to flash/mmc from zImage | |
| 5 | 5 | # |
| 6 | 6 | |
| 7 | 7 | targets := vmlinux head.o zeropage.bin piggy.o |
| 8 | +load-y := 0 | |
| 8 | 9 | |
| 9 | −OBJECTS = $(obj)/head.o | |
| 10 | −LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart \ | |
| 10 | +mmcif-load-$(CONFIG_CPU_SUBTYPE_SH7724) := 0xe5200000 # ILRAM | |
| 11 | +mmcif-obj-$(CONFIG_CPU_SUBTYPE_SH7724) := $(obj)/mmcif-sh7724.o | |
| 12 | +load-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-load-y) | |
| 13 | +obj-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-obj-y) | |
| 14 | + | |
| 15 | +LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(load-y) -e romstart \ | |
| 11 | 16 | -T $(obj)/../../kernel/vmlinux.lds |
| 12 | 17 | |
| 13 | −$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE | |
| 18 | +$(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE | |
| 14 | 19 | $(call if_changed,ld) |
| 15 | 20 | @: |
| 16 | 21 | |
| @@ -12,8 +12,40 @@ romstart: · 11 unmodified lines | ||
| 12 | 12 | /* include board specific setup code */ |
| 13 | 13 | #include <mach/romimage.h> |
| 14 | 14 | |
| 15 | +#ifdef CONFIG_ROMIMAGE_MMCIF | |
| 16 | + /* load the romImage to above the empty zero page */ | |
| 17 | + mov.l empty_zero_page_dst, r4 | |
| 18 | + mov.l empty_zero_page_dst_adj, r5 | |
| 19 | + add r5, r4 | |
| 20 | + mov.l bytes_to_load, r5 | |
| 21 | + mov.l loader_function, r7 | |
| 22 | + jsr @r7 | |
| 23 | + mov r4, r15 | |
| 24 | + | |
| 25 | + mov.l empty_zero_page_dst, r4 | |
| 26 | + mov.l empty_zero_page_dst_adj, r5 | |
| 27 | + add r5, r4 | |
| 28 | + mov.l loaded_code_offs, r5 | |
| 29 | + add r5, r4 | |
| 30 | + jmp @r4 | |
| 31 | + nop | |
| 32 | + | |
| 33 | + .balign 4 | |
| 34 | +empty_zero_page_dst_adj: | |
| 35 | + .long PAGE_SIZE | |
| 36 | +bytes_to_load: | |
| 37 | + .long end_data - romstart | |
| 38 | +loader_function: | |
| 39 | + .long mmcif_loader | |
| 40 | +loaded_code_offs: | |
| 41 | + .long loaded_code - romstart | |
| 42 | +loaded_code: | |
| 43 | +#endif /* CONFIG_ROMIMAGE_MMCIF */ | |
| 44 | + | |
| 15 | 45 | /* copy the empty_zero_page contents to where vmlinux expects it */ |
| 16 | − mova empty_zero_page_src, r0 | |
| 46 | + mova extra_data_pos, r0 | |
| 47 | + mov.l extra_data_size, r1 | |
| 48 | + add r1, r0 | |
| 17 | 49 | mov.l empty_zero_page_dst, r1 |
| 18 | 50 | mov #(PAGE_SHIFT - 4), r4 |
| 19 | 51 | mov #1, r3 |
| @@ -37,7 +69,9 @@ romstart: · 17 unmodified lines | ||
| 37 | 69 | mov #PAGE_SHIFT, r4 |
| 38 | 70 | mov #1, r1 |
| 39 | 71 | shld r4, r1 |
| 40 | − mova empty_zero_page_src, r0 | |
| 72 | + mova extra_data_pos, r0 | |
| 73 | + add r1, r0 | |
| 74 | + mov.l extra_data_size, r1 | |
| 41 | 75 | add r1, r0 |
| 42 | 76 | jmp @r0 |
| 43 | 77 | nop |
| @@ -45,4 +79,6 @@ romstart: · 1 unmodified line | ||
| 45 | 79 | .align 2 |
| 46 | 80 | empty_zero_page_dst: |
| 47 | 81 | .long _text |
| 48 | −empty_zero_page_src: | |
| 82 | +extra_data_pos: | |
| 83 | +extra_data_size: | |
| 84 | + .long zero_page_pos - extra_data_pos | |
| @@ -0,0 +1,72 @@ | ||
| 1 | +/* | |
| 2 | + * sh7724 MMCIF loader | |
| 3 | + * | |
| 4 | + * Copyright (C) 2010 Magnus Damm | |
| 5 | + * | |
| 6 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 7 | + * License. See the file "COPYING" in the main directory of this archive | |
| 8 | + * for more details. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <linux/mmc/sh_mmcif.h> | |
| 12 | +#include <mach/romimage.h> | |
| 13 | + | |
| 14 | +#define MMCIF_BASE (void __iomem *)0xa4ca0000 | |
| 15 | + | |
| 16 | +#define MSTPCR2 0xa4150038 | |
| 17 | +#define PTWCR 0xa4050146 | |
| 18 | +#define PTXCR 0xa4050148 | |
| 19 | +#define PSELA 0xa405014e | |
| 20 | +#define PSELE 0xa4050156 | |
| 21 | +#define HIZCRC 0xa405015c | |
| 22 | +#define DRVCRA 0xa405018a | |
| 23 | + | |
| 24 | +enum { MMCIF_PROGRESS_ENTER, MMCIF_PROGRESS_INIT, | |
| 25 | + MMCIF_PROGRESS_LOAD, MMCIF_PROGRESS_DONE }; | |
| 26 | + | |
| 27 | +/* SH7724 specific MMCIF loader | |
| 28 | + * | |
| 29 | + * loads the romImage from an MMC card starting from block 512 | |
| 30 | + * use the following line to write the romImage to an MMC card | |
| 31 | + * # dd if=arch/sh/boot/romImage of=/dev/sdx bs=512 seek=512 | |
| 32 | + */ | |
| 33 | +asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) | |
| 34 | +{ | |
| 35 | + mmcif_update_progress(MMCIF_PROGRESS_ENTER); | |
| 36 | + | |
| 37 | + /* enable clock to the MMCIF hardware block */ | |
| 38 | + __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2); | |
| 39 | + | |
| 40 | + /* setup pins D7-D0 */ | |
| 41 | + __raw_writew(0x0000, PTWCR); | |
| 42 | + | |
| 43 | + /* setup pins MMC_CLK, MMC_CMD */ | |
| 44 | + __raw_writew(__raw_readw(PTXCR) & ~0x000f, PTXCR); | |
| 45 | + | |
| 46 | + /* select D3-D0 pin function */ | |
| 47 | + __raw_writew(__raw_readw(PSELA) & ~0x2000, PSELA); | |
| 48 | + | |
| 49 | + /* select D7-D4 pin function */ | |
| 50 | + __raw_writew(__raw_readw(PSELE) & ~0x3000, PSELE); | |
| 51 | + | |
| 52 | + /* disable Hi-Z for the MMC pins */ | |
| 53 | + __raw_writew(__raw_readw(HIZCRC) & ~0x0620, HIZCRC); | |
| 54 | + | |
| 55 | + /* high drive capability for MMC pins */ | |
| 56 | + __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA); | |
| 57 | + | |
| 58 | + mmcif_update_progress(MMCIF_PROGRESS_INIT); | |
| 59 | + | |
| 60 | + /* setup MMCIF hardware */ | |
| 61 | + sh_mmcif_boot_init(MMCIF_BASE); | |
| 62 | + | |
| 63 | + mmcif_update_progress(MMCIF_PROGRESS_LOAD); | |
| 64 | + | |
| 65 | + /* load kernel via MMCIF interface */ | |
| 66 | + sh_mmcif_boot_slurp(MMCIF_BASE, buf, no_bytes); | |
| 67 | + | |
| 68 | + /* disable clock to the MMCIF hardware block */ | |
| 69 | + __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); | |
| 70 | + | |
| 71 | + mmcif_update_progress(MMCIF_PROGRESS_DONE); | |
| 72 | +} | |
| @@ -1,6 +1,8 @@ | ||
| 1 | 1 | SECTIONS |
| 2 | 2 | { |
| 3 | 3 | .text : { |
| 4 | + zero_page_pos = .; | |
| 4 | 5 | *(.data) |
| 6 | + end_data = .; | |
| 5 | 7 | } |
| 6 | 8 | } |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) |
| 16 | 16 | |
| 17 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 17 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 18 | 18 | |
| 19 | 19 | #ifndef __ASSEMBLY__ |
| 20 | 20 | struct cache_info { |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | #include <asm/io_generic.h> |
| 40 | 40 | #include <asm/io_trapped.h> |
| 41 | 41 | |
| 42 | +#ifdef CONFIG_HAS_IOPORT | |
| 43 | + | |
| 42 | 44 | #define inb(p) sh_mv.mv_inb((p)) |
| 43 | 45 | #define inw(p) sh_mv.mv_inw((p)) |
| 44 | 46 | #define inl(p) sh_mv.mv_inl((p)) |
| @@ -60,6 +62,8 @@ · 15 unmodified lines | ||
| 60 | 62 | #define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c)) |
| 61 | 63 | #define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c)) |
| 62 | 64 | |
| 65 | +#endif | |
| 66 | + | |
| 63 | 67 | #define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v)) |
| 64 | 68 | #define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v)) |
| 65 | 69 | #define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v)) |
| @@ -240,6 +244,8 @@ __BUILD_MEMORY_STRING(q, u64) · 174 unmodified lines | ||
| 240 | 244 | |
| 241 | 245 | #define IO_SPACE_LIMIT 0xffffffff |
| 242 | 246 | |
| 247 | +#ifdef CONFIG_HAS_IOPORT | |
| 248 | + | |
| 243 | 249 | /* |
| 244 | 250 | * This function provides a method for the generic case where a |
| 245 | 251 | * board-specific ioport_map simply needs to return the port + some |
| @@ -255,6 +261,8 @@ static inline void __set_io_port_base(unsigned long pbase) · 9 unmodified lines | ||
| 255 | 261 | |
| 256 | 262 | #define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n)) |
| 257 | 263 | |
| 264 | +#endif | |
| 265 | + | |
| 258 | 266 | /* We really want to try and get these to memcpy etc */ |
| 259 | 267 | void memcpy_fromio(void *, const volatile void __iomem *, unsigned long); |
| 260 | 268 | void memcpy_toio(volatile void __iomem *, const void *, unsigned long); |
| @@ -19,6 +19,10 @@ struct sh_machine_vector { · 18 unmodified lines | ||
| 19 | 19 | const char *mv_name; |
| 20 | 20 | int mv_nr_irqs; |
| 21 | 21 | |
| 22 | + int (*mv_irq_demux)(int irq); | |
| 23 | + void (*mv_init_irq)(void); | |
| 24 | + | |
| 25 | +#ifdef CONFIG_HAS_IOPORT | |
| 22 | 26 | u8 (*mv_inb)(unsigned long); |
| 23 | 27 | u16 (*mv_inw)(unsigned long); |
| 24 | 28 | u32 (*mv_inl)(unsigned long); |
| @@ -40,12 +44,9 @@ struct sh_machine_vector { · 15 unmodified lines | ||
| 40 | 44 | void (*mv_outsw)(unsigned long, const void *src, unsigned long count); |
| 41 | 45 | void (*mv_outsl)(unsigned long, const void *src, unsigned long count); |
| 42 | 46 | |
| 43 | − int (*mv_irq_demux)(int irq); | |
| 44 | − | |
| 45 | − void (*mv_init_irq)(void); | |
| 46 | − | |
| 47 | 47 | void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size); |
| 48 | 48 | void (*mv_ioport_unmap)(void __iomem *); |
| 49 | +#endif | |
| 49 | 50 | |
| 50 | 51 | int (*mv_clk_init)(void); |
| 51 | 52 | int (*mv_mode_pins)(void); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | * MD3: BSC - Area0 Bus Width (16/32-bit) [CS0BCR.9,10] |
| 10 | 10 | * MD5: BSC - Endian Mode (L: Big, H: Little) [CMNCR.3] |
| 11 | 11 | * MD8: Test Mode |
| 12 | + * BOOT: FBR - Boot Mode (L: MMCIF, H: Area0) | |
| 12 | 13 | */ |
| 13 | 14 | |
| 14 | 15 | /* Pin Function Controller: |
| @@ -1 +1,11 @@ | ||
| 1 | +#ifdef __ASSEMBLY__ | |
| 2 | + | |
| 1 | 3 | /* do nothing here by default */ |
| 4 | + | |
| 5 | +#else /* __ASSEMBLY__ */ | |
| 6 | + | |
| 7 | +extern inline void mmcif_update_progress(int nr) | |
| 8 | +{ | |
| 9 | +} | |
| 10 | + | |
| 11 | +#endif /* __ASSEMBLY__ */ | |
| @@ -1,3 +1,5 @@ | ||
| 1 | +#ifdef __ASSEMBLY__ | |
| 2 | + | |
| 1 | 3 | /* EcoVec board specific boot code: |
| 2 | 4 | * converts the "partner-jet-script.txt" script into assembly |
| 3 | 5 | * the assembly code is the first code to be executed in the romImage |
| @@ -18,3 +20,28 @@ · 14 unmodified lines | ||
| 18 | 20 | .align 2 |
| 19 | 21 | 1 : .long 0xa8000000 |
| 20 | 22 | 2 : |
| 23 | + | |
| 24 | +#else /* __ASSEMBLY__ */ | |
| 25 | + | |
| 26 | +/* Ecovec board specific information: | |
| 27 | + * | |
| 28 | + * Set the following to enable MMCIF boot from the MMC card in CN12: | |
| 29 | + * | |
| 30 | + * DS1.5 = OFF (SH BOOT pin set to L) | |
| 31 | + * DS2.6 = OFF (Select MMCIF on CN12 instead of SDHI1) | |
| 32 | + * DS2.7 = ON (Select MMCIF on CN12 instead of SDHI1) | |
| 33 | + * | |
| 34 | + */ | |
| 35 | +#define HIZCRA 0xa4050158 | |
| 36 | +#define PGDR 0xa405012c | |
| 37 | + | |
| 38 | +extern inline void mmcif_update_progress(int nr) | |
| 39 | +{ | |
| 40 | + /* disable Hi-Z for LED pins */ | |
| 41 | + __raw_writew(__raw_readw(HIZCRA) & ~(1 << 1), HIZCRA); | |
| 42 | + | |
| 43 | + /* update progress on LED4, LED5, LED6 and LED7 */ | |
| 44 | + __raw_writeb(1 << (nr - 1), PGDR); | |
| 45 | +} | |
| 46 | + | |
| 47 | +#endif /* __ASSEMBLY__ */ | |
| @@ -1,3 +1,5 @@ | ||
| 1 | +#ifdef __ASSEMBLY__ | |
| 2 | + | |
| 1 | 3 | /* kfr2r09 board specific boot code: |
| 2 | 4 | * converts the "partner-jet-script.txt" script into assembly |
| 3 | 5 | * the assembly code is the first code to be executed in the romImage |
| @@ -18,3 +20,11 @@ · 14 unmodified lines | ||
| 18 | 20 | .align 2 |
| 19 | 21 | 1: .long 0xa8000000 |
| 20 | 22 | 2: |
| 23 | + | |
| 24 | +#else /* __ASSEMBLY__ */ | |
| 25 | + | |
| 26 | +extern inline void mmcif_update_progress(int nr) | |
| 27 | +{ | |
| 28 | +} | |
| 29 | + | |
| 30 | +#endif /* __ASSEMBLY__ */ | |
| @@ -12,7 +12,7 @@ endif · 11 unmodified lines | ||
| 12 | 12 | CFLAGS_REMOVE_return_address.o = -pg |
| 13 | 13 | |
| 14 | 14 | obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \ |
| 15 | − idle.o io.o io_generic.o irq.o \ | |
| 15 | + idle.o io.o irq.o \ | |
| 16 | 16 | irq_$(BITS).o machvec.o nmi_debug.o process.o \ |
| 17 | 17 | process_$(BITS).o ptrace_$(BITS).o \ |
| 18 | 18 | reboot.o return_address.o \ |
| @@ -39,6 +39,7 @@ obj-$(CONFIG_DUMP_CODE) += disassemble.o · 20 unmodified lines | ||
| 39 | 39 | obj-$(CONFIG_HIBERNATION) += swsusp.o |
| 40 | 40 | obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o |
| 41 | 41 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o |
| 42 | +obj-$(CONFIG_HAS_IOPORT) += io_generic.o | |
| 42 | 43 | |
| 43 | 44 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
| 44 | 45 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o |
| @@ -49,6 +49,8 @@ static DEFINE_SPINLOCK(dwarf_fde_lock); · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | static struct dwarf_cie *cached_cie; |
| 51 | 51 | |
| 52 | +static unsigned int dwarf_unwinder_ready; | |
| 53 | + | |
| 52 | 54 | /** |
| 53 | 55 | * dwarf_frame_alloc_reg - allocate memory for a DWARF register |
| 54 | 56 | * @frame: the DWARF frame whose list of registers we insert on |
| @@ -581,6 +583,13 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, · 526 unmodified lines | ||
| 581 | 583 | struct dwarf_reg *reg; |
| 582 | 584 | unsigned long addr; |
| 583 | 585 | |
| 586 | + /* | |
| 587 | + * If we've been called in to before initialization has | |
| 588 | + * completed, bail out immediately. | |
| 589 | + */ | |
| 590 | + if (!dwarf_unwinder_ready) | |
| 591 | + return NULL; | |
| 592 | + | |
| 584 | 593 | /* |
| 585 | 594 | * If we're starting at the top of the stack we need get the |
| 586 | 595 | * contents of a physical register to get the CFA in order to |
| @@ -1167,7 +1176,7 @@ void module_dwarf_cleanup(struct module *mod) · 580 unmodified lines | ||
| 1167 | 1176 | */ |
| 1168 | 1177 | static int __init dwarf_unwinder_init(void) |
| 1169 | 1178 | { |
| 1170 | − int err; | |
| 1179 | + int err = -ENOMEM; | |
| 1171 | 1180 | |
| 1172 | 1181 | dwarf_frame_cachep = kmem_cache_create("dwarf_frames", |
| 1173 | 1182 | sizeof(struct dwarf_frame), 0, |
| @@ -1181,11 +1190,15 @@ static int __init dwarf_unwinder_init(void) · 7 unmodified lines | ||
| 1181 | 1190 | mempool_alloc_slab, |
| 1182 | 1191 | mempool_free_slab, |
| 1183 | 1192 | dwarf_frame_cachep); |
| 1193 | + if (!dwarf_frame_pool) | |
| 1194 | + goto out; | |
| 1184 | 1195 | |
| 1185 | 1196 | dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ, |
| 1186 | 1197 | mempool_alloc_slab, |
| 1187 | 1198 | mempool_free_slab, |
| 1188 | 1199 | dwarf_reg_cachep); |
| 1200 | + if (!dwarf_reg_pool) | |
| 1201 | + goto out; | |
| 1189 | 1202 | |
| 1190 | 1203 | err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL); |
| 1191 | 1204 | if (err) |
| @@ -1195,11 +1208,13 @@ static int __init dwarf_unwinder_init(void) · 3 unmodified lines | ||
| 1195 | 1208 | if (err) |
| 1196 | 1209 | goto out; |
| 1197 | 1210 | |
| 1211 | + dwarf_unwinder_ready = 1; | |
| 1212 | + | |
| 1198 | 1213 | return 0; |
| 1199 | 1214 | |
| 1200 | 1215 | out: |
| 1201 | 1216 | printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err); |
| 1202 | 1217 | dwarf_unwinder_cleanup(); |
| 1203 | − return -EINVAL; | |
| 1218 | + return err; | |
| 1204 | 1219 | } |
| 1205 | 1220 | early_initcall(dwarf_unwinder_init); |
| @@ -112,25 +112,3 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count) · 111 unmodified lines | ||
| 112 | 112 | } |
| 113 | 113 | } |
| 114 | 114 | EXPORT_SYMBOL(memset_io); |
| 115 | − | |
| 116 | −#ifndef CONFIG_GENERIC_IOMAP | |
| 117 | − | |
| 118 | −void __iomem *ioport_map(unsigned long port, unsigned int nr) | |
| 119 | −{ | |
| 120 | − void __iomem *ret; | |
| 121 | − | |
| 122 | − ret = __ioport_map_trapped(port, nr); | |
| 123 | − if (ret) | |
| 124 | − return ret; | |
| 125 | − | |
| 126 | − return __ioport_map(port, nr); | |
| 127 | −} | |
| 128 | −EXPORT_SYMBOL(ioport_map); | |
| 129 | − | |
| 130 | −void ioport_unmap(void __iomem *addr) | |
| 131 | −{ | |
| 132 | − sh_mv.mv_ioport_unmap(addr); | |
| 133 | −} | |
| 134 | −EXPORT_SYMBOL(ioport_unmap); | |
| 135 | − | |
| 136 | −#endif /* CONFIG_GENERIC_IOMAP */ | |
| @@ -158,3 +158,23 @@ void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) · 157 unmodified lines | ||
| 158 | 158 | void generic_ioport_unmap(void __iomem *addr) |
| 159 | 159 | { |
| 160 | 160 | } |
| 161 | + | |
| 162 | +#ifndef CONFIG_GENERIC_IOMAP | |
| 163 | +void __iomem *ioport_map(unsigned long port, unsigned int nr) | |
| 164 | +{ | |
| 165 | + void __iomem *ret; | |
| 166 | + | |
| 167 | + ret = __ioport_map_trapped(port, nr); | |
| 168 | + if (ret) | |
| 169 | + return ret; | |
| 170 | + | |
| 171 | + return __ioport_map(port, nr); | |
| 172 | +} | |
| 173 | +EXPORT_SYMBOL(ioport_map); | |
| 174 | + | |
| 175 | +void ioport_unmap(void __iomem *addr) | |
| 176 | +{ | |
| 177 | + sh_mv.mv_ioport_unmap(addr); | |
| 178 | +} | |
| 179 | +EXPORT_SYMBOL(ioport_unmap); | |
| 180 | +#endif /* CONFIG_GENERIC_IOMAP */ | |
| @@ -91,10 +91,14 @@ int register_trapped_io(struct trapped_io *tiop) · 90 unmodified lines | ||
| 91 | 91 | tiop->magic = IO_TRAPPED_MAGIC; |
| 92 | 92 | INIT_LIST_HEAD(&tiop->list); |
| 93 | 93 | spin_lock_irq(&trapped_lock); |
| 94 | +#ifdef CONFIG_HAS_IOPORT | |
| 94 | 95 | if (flags & IORESOURCE_IO) |
| 95 | 96 | list_add(&tiop->list, &trapped_io); |
| 97 | +#endif | |
| 98 | +#ifdef CONFIG_HAS_IOMEM | |
| 96 | 99 | if (flags & IORESOURCE_MEM) |
| 97 | 100 | list_add(&tiop->list, &trapped_mem); |
| 101 | +#endif | |
| 98 | 102 | spin_unlock_irq(&trapped_lock); |
| 99 | 103 | |
| 100 | 104 | return 0; |
| @@ -118,6 +118,14 @@ void __init sh_mv_setup(void) · 117 unmodified lines | ||
| 118 | 118 | sh_mv.mv_##elem = generic_##elem; \ |
| 119 | 119 | } while (0) |
| 120 | 120 | |
| 121 | +#ifdef CONFIG_HAS_IOPORT | |
| 122 | + | |
| 123 | +#ifdef P2SEG | |
| 124 | + __set_io_port_base(P2SEG); | |
| 125 | +#else | |
| 126 | + __set_io_port_base(0); | |
| 127 | +#endif | |
| 128 | + | |
| 121 | 129 | mv_set(inb); mv_set(inw); mv_set(inl); |
| 122 | 130 | mv_set(outb); mv_set(outw); mv_set(outl); |
| 123 | 131 | |
| @@ -129,16 +137,13 @@ void __init sh_mv_setup(void) · 5 unmodified lines | ||
| 129 | 137 | |
| 130 | 138 | mv_set(ioport_map); |
| 131 | 139 | mv_set(ioport_unmap); |
| 140 | + | |
| 141 | +#endif | |
| 142 | + | |
| 132 | 143 | mv_set(irq_demux); |
| 133 | 144 | mv_set(mode_pins); |
| 134 | 145 | mv_set(mem_init); |
| 135 | 146 | |
| 136 | 147 | if (!sh_mv.mv_nr_irqs) |
| 137 | 148 | sh_mv.mv_nr_irqs = NR_IRQS; |
| 138 | − | |
| 139 | −#ifdef P2SEG | |
| 140 | − __set_io_port_base(P2SEG); | |
| 141 | −#else | |
| 142 | − __set_io_port_base(0); | |
| 143 | −#endif | |
| 144 | 149 | } |
| @@ -24,6 +24,8 @@ void *return_address(unsigned int depth) · 23 unmodified lines | ||
| 24 | 24 | struct dwarf_frame *tmp; |
| 25 | 25 | |
| 26 | 26 | tmp = dwarf_unwind_stack(ra, frame); |
| 27 | + if (!tmp) | |
| 28 | + return NULL; | |
| 27 | 29 | |
| 28 | 30 | if (frame) |
| 29 | 31 | dwarf_free_frame(frame); |
| @@ -325,7 +325,7 @@ main1: · 324 unmodified lines | ||
| 325 | 325 | (*rr)->next = NULL; |
| 326 | 326 | } |
| 327 | 327 | printf("! Generated by btfixupprep. Do not edit.\n\n"); |
| 328 | − printf("\t.section\t\".data.init\",#alloc,#write\n\t.align\t4\n\n"); | |
| 328 | + printf("\t.section\t\".data..init\",#alloc,#write\n\t.align\t4\n\n"); | |
| 329 | 329 | printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n"); |
| 330 | 330 | for (i = 0; i < last; i++) { |
| 331 | 331 | f = array + i; |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) |
| 23 | 23 | |
| 24 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 24 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 25 | 25 | |
| 26 | 26 | #ifdef CONFIG_SPARC32 |
| 27 | 27 | #include <asm/asi.h> |
| @@ -94,7 +94,7 @@ SECTIONS · 93 unmodified lines | ||
| 94 | 94 | .data : { |
| 95 | 95 | INIT_TASK_DATA(KERNEL_STACK_SIZE) |
| 96 | 96 | . = ALIGN(KERNEL_STACK_SIZE); |
| 97 | − *(.data.init_irqstack) | |
| 97 | + *(.data..init_irqstack) | |
| 98 | 98 | DATA_DATA |
| 99 | 99 | *(.data.* .gnu.linkonce.d.*) |
| 100 | 100 | SORT(CONSTRUCTORS) |
| @@ -34,5 +34,5 @@ union thread_union init_thread_union __init_task_data = · 33 unmodified lines | ||
| 34 | 34 | { INIT_THREAD_INFO(init_task) }; |
| 35 | 35 | |
| 36 | 36 | union thread_union cpu0_irqstack |
| 37 | − __attribute__((__section__(".data.init_irqstack"))) = | |
| 37 | + __attribute__((__section__(".data..init_irqstack"))) = | |
| 38 | 38 | { INIT_THREAD_INFO(init_task) }; |
| @@ -81,7 +81,7 @@ static int do_op_one_page(unsigned long addr, int len, int is_write, · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | current->thread.fault_catcher = NULL; |
| 83 | 83 | |
| 84 | − kunmap_atomic(page, KM_UML_USERCOPY); | |
| 84 | + kunmap_atomic((void *)addr, KM_UML_USERCOPY); | |
| 85 | 85 | |
| 86 | 86 | return n; |
| 87 | 87 | } |
| @@ -50,7 +50,7 @@ SECTIONS · 49 unmodified lines | ||
| 50 | 50 | { |
| 51 | 51 | INIT_TASK_DATA(KERNEL_STACK_SIZE) |
| 52 | 52 | . = ALIGN(KERNEL_STACK_SIZE); |
| 53 | − *(.data.init_irqstack) | |
| 53 | + *(.data..init_irqstack) | |
| 54 | 54 | DATA_DATA |
| 55 | 55 | *(.gnu.linkonce.d*) |
| 56 | 56 | CONSTRUCTORS |
| @@ -0,0 +1,3 @@ | ||
| 1 | +boot/compressed/vmlinux | |
| 2 | +tools/test_get_len | |
| 3 | + | |
| @@ -77,7 +77,7 @@ int main(int argc, char *argv[]) · 76 unmodified lines | ||
| 77 | 77 | offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */ |
| 78 | 78 | offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ |
| 79 | 79 | |
| 80 | − printf(".section \".rodata.compressed\",\"a\",@progbits\n"); | |
| 80 | + printf(".section \".rodata..compressed\",\"a\",@progbits\n"); | |
| 81 | 81 | printf(".globl z_input_len\n"); |
| 82 | 82 | printf("z_input_len = %lu\n", ilen); |
| 83 | 83 | printf(".globl z_output_len\n"); |
| @@ -26,8 +26,8 @@ SECTIONS · 25 unmodified lines | ||
| 26 | 26 | HEAD_TEXT |
| 27 | 27 | _ehead = . ; |
| 28 | 28 | } |
| 29 | − .rodata.compressed : { | |
| 30 | − *(.rodata.compressed) | |
| 29 | + .rodata..compressed : { | |
| 30 | + *(.rodata..compressed) | |
| 31 | 31 | } |
| 32 | 32 | .text : { |
| 33 | 33 | _text = .; /* Text */ |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) |
| 8 | 8 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) |
| 9 | 9 | |
| 10 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 10 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 11 | 11 | |
| 12 | 12 | #define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT |
| 13 | 13 | #define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT) |
| @@ -110,6 +110,7 @@ · 109 unmodified lines | ||
| 110 | 110 | #define MSR_AMD64_PATCH_LOADER 0xc0010020 |
| 111 | 111 | #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 |
| 112 | 112 | #define MSR_AMD64_OSVW_STATUS 0xc0010141 |
| 113 | +#define MSR_AMD64_DC_CFG 0xc0011022 | |
| 113 | 114 | #define MSR_AMD64_IBSFETCHCTL 0xc0011030 |
| 114 | 115 | #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 |
| 115 | 116 | #define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 |
| @@ -53,6 +53,8 @@ extern int pcibios_last_bus; · 52 unmodified lines | ||
| 53 | 53 | extern struct pci_bus *pci_root_bus; |
| 54 | 54 | extern struct pci_ops pci_root_ops; |
| 55 | 55 | |
| 56 | +void pcibios_scan_specific_bus(int busn); | |
| 57 | + | |
| 56 | 58 | /* pci-irq.c */ |
| 57 | 59 | |
| 58 | 60 | struct irq_info { |
| @@ -15,6 +15,8 @@ static inline int arch_prepare_suspend(void) { return 0; } · 14 unmodified lines | ||
| 15 | 15 | struct saved_context { |
| 16 | 16 | u16 es, fs, gs, ss; |
| 17 | 17 | unsigned long cr0, cr2, cr3, cr4; |
| 18 | + u64 misc_enable; | |
| 19 | + bool misc_enable_saved; | |
| 18 | 20 | struct desc_ptr gdt; |
| 19 | 21 | struct desc_ptr idt; |
| 20 | 22 | u16 ldt; |
| @@ -27,6 +27,8 @@ struct saved_context { · 26 unmodified lines | ||
| 27 | 27 | u16 ds, es, fs, gs, ss; |
| 28 | 28 | unsigned long gs_base, gs_kernel_base, fs_base; |
| 29 | 29 | unsigned long cr0, cr2, cr3, cr4, cr8; |
| 30 | + u64 misc_enable; | |
| 31 | + bool misc_enable_saved; | |
| 30 | 32 | unsigned long efer; |
| 31 | 33 | u16 gdt_pad; |
| 32 | 34 | u16 gdt_limit; |
| @@ -1,4 +1,4 @@ | ||
| 1 | − .section .text.page_aligned | |
| 1 | + .section .text..page_aligned | |
| 2 | 2 | #include <linux/linkage.h> |
| 3 | 3 | #include <asm/segment.h> |
| 4 | 4 | #include <asm/page_types.h> |
| @@ -1487,6 +1487,7 @@ static int __attach_device(struct device *dev, · 1486 unmodified lines | ||
| 1487 | 1487 | struct protection_domain *domain) |
| 1488 | 1488 | { |
| 1489 | 1489 | struct iommu_dev_data *dev_data, *alias_data; |
| 1490 | + int ret; | |
| 1490 | 1491 | |
| 1491 | 1492 | dev_data = get_dev_data(dev); |
| 1492 | 1493 | alias_data = get_dev_data(dev_data->alias); |
| @@ -1498,13 +1499,14 @@ static int __attach_device(struct device *dev, · 5 unmodified lines | ||
| 1498 | 1499 | spin_lock(&domain->lock); |
| 1499 | 1500 | |
| 1500 | 1501 | /* Some sanity checks */ |
| 1502 | + ret = -EBUSY; | |
| 1501 | 1503 | if (alias_data->domain != NULL && |
| 1502 | 1504 | alias_data->domain != domain) |
| 1503 | − return -EBUSY; | |
| 1505 | + goto out_unlock; | |
| 1504 | 1506 | |
| 1505 | 1507 | if (dev_data->domain != NULL && |
| 1506 | 1508 | dev_data->domain != domain) |
| 1507 | − return -EBUSY; | |
| 1509 | + goto out_unlock; | |
| 1508 | 1510 | |
| 1509 | 1511 | /* Do real assignment */ |
| 1510 | 1512 | if (dev_data->alias != dev) { |
| @@ -1520,10 +1522,14 @@ static int __attach_device(struct device *dev, · 9 unmodified lines | ||
| 1520 | 1522 | |
| 1521 | 1523 | atomic_inc(&dev_data->bind); |
| 1522 | 1524 | |
| 1525 | + ret = 0; | |
| 1526 | + | |
| 1527 | +out_unlock: | |
| 1528 | + | |
| 1523 | 1529 | /* ready */ |
| 1524 | 1530 | spin_unlock(&domain->lock); |
| 1525 | 1531 | |
| 1526 | − return 0; | |
| 1532 | + return ret; | |
| 1527 | 1533 | } |
| 1528 | 1534 | |
| 1529 | 1535 | /* |
| @@ -2324,10 +2330,6 @@ int __init amd_iommu_init_dma_ops(void) · 794 unmodified lines | ||
| 2324 | 2330 | |
| 2325 | 2331 | iommu_detected = 1; |
| 2326 | 2332 | swiotlb = 0; |
| 2327 | −#ifdef CONFIG_GART_IOMMU | |
| 2328 | − gart_iommu_aperture_disabled = 1; | |
| 2329 | − gart_iommu_aperture = 0; | |
| 2330 | −#endif | |
| 2331 | 2333 | |
| 2332 | 2334 | /* Make the driver finally visible to the drivers */ |
| 2333 | 2335 | dma_ops = &amd_iommu_dma_ops; |
| @@ -287,8 +287,12 @@ static u8 * __init iommu_map_mmio_space(u64 address) · 286 unmodified lines | ||
| 287 | 287 | { |
| 288 | 288 | u8 *ret; |
| 289 | 289 | |
| 290 | − if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu")) | |
| 290 | + if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu")) { | |
| 291 | + pr_err("AMD-Vi: Can not reserve memory region %llx for mmio\n", | |
| 292 | + address); | |
| 293 | + pr_err("AMD-Vi: This is a BIOS bug. Please contact your hardware vendor\n"); | |
| 291 | 294 | return NULL; |
| 295 | + } | |
| 292 | 296 | |
| 293 | 297 | ret = ioremap_nocache(address, MMIO_REGION_LENGTH); |
| 294 | 298 | if (ret != NULL) |
| @@ -1314,7 +1318,7 @@ static int __init amd_iommu_init(void) · 1019 unmodified lines | ||
| 1314 | 1318 | ret = amd_iommu_init_dma_ops(); |
| 1315 | 1319 | |
| 1316 | 1320 | if (ret) |
| 1317 | − goto free; | |
| 1321 | + goto free_disable; | |
| 1318 | 1322 | |
| 1319 | 1323 | amd_iommu_init_api(); |
| 1320 | 1324 | |
| @@ -1332,9 +1336,10 @@ static int __init amd_iommu_init(void) · 11 unmodified lines | ||
| 1332 | 1336 | out: |
| 1333 | 1337 | return ret; |
| 1334 | 1338 | |
| 1335 | −free: | |
| 1339 | +free_disable: | |
| 1336 | 1340 | disable_iommus(); |
| 1337 | 1341 | |
| 1342 | +free: | |
| 1338 | 1343 | amd_iommu_uninit_devices(); |
| 1339 | 1344 | |
| 1340 | 1345 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, |
| @@ -1353,6 +1358,15 @@ free: · 12 unmodified lines | ||
| 1353 | 1358 | |
| 1354 | 1359 | free_unity_maps(); |
| 1355 | 1360 | |
| 1361 | +#ifdef CONFIG_GART_IOMMU | |
| 1362 | + /* | |
| 1363 | + * We failed to initialize the AMD IOMMU - try fallback to GART | |
| 1364 | + * if possible. | |
| 1365 | + */ | |
| 1366 | + gart_iommu_init(); | |
| 1367 | + | |
| 1368 | +#endif | |
| 1369 | + | |
| 1356 | 1370 | goto out; |
| 1357 | 1371 | } |
| 1358 | 1372 | |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <linux/fs.h> |
| 37 | 37 | #include <linux/mm.h> |
| 38 | 38 | #include <linux/debugfs.h> |
| 39 | +#include <linux/edac_mce.h> | |
| 39 | 40 | |
| 40 | 41 | #include <asm/processor.h> |
| 41 | 42 | #include <asm/hw_irq.h> |
| @@ -168,6 +169,15 @@ void mce_log(struct mce *mce) · 126 unmodified lines | ||
| 168 | 169 | for (;;) { |
| 169 | 170 | entry = rcu_dereference_check_mce(mcelog.next); |
| 170 | 171 | for (;;) { |
| 172 | + /* | |
| 173 | + * If edac_mce is enabled, it will check the error type | |
| 174 | + * and will process it, if it is a known error. | |
| 175 | + * Otherwise, the error will be sent through mcelog | |
| 176 | + * interface | |
| 177 | + */ | |
| 178 | + if (edac_mce_parse(mce)) | |
| 179 | + return; | |
| 180 | + | |
| 171 | 181 | /* |
| 172 | 182 | * When the buffer fills up discard new entries. |
| 173 | 183 | * Assume that the earlier errors are the more |
| @@ -34,7 +34,7 @@ EXPORT_SYMBOL(init_task); · 33 unmodified lines | ||
| 34 | 34 | /* |
| 35 | 35 | * per-CPU TSS segments. Threads are completely 'soft' on Linux, |
| 36 | 36 | * no more per-task TSS's. The TSS size is kept cacheline-aligned |
| 37 | − * so they are allowed to end up in the .data.cacheline_aligned | |
| 37 | + * so they are allowed to end up in the .data..cacheline_aligned | |
| 38 | 38 | * section. Since TSS's are completely CPU-local, we want them |
| 39 | 39 | * on exact cacheline boundaries, to eliminate cacheline ping-pong. |
| 40 | 40 | */ |
| @@ -21,12 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <asm/cpu.h> |
| 22 | 22 | #include <asm/stackprotector.h> |
| 23 | 23 | |
| 24 | −#ifdef CONFIG_DEBUG_PER_CPU_MAPS | |
| 25 | −# define DBG(fmt, ...) pr_dbg(fmt, ##__VA_ARGS__) | |
| 26 | −#else | |
| 27 | −# define DBG(fmt, ...) do { if (0) pr_dbg(fmt, ##__VA_ARGS__); } while (0) | |
| 28 | −#endif | |
| 29 | − | |
| 30 | 24 | DEFINE_PER_CPU(int, cpu_number); |
| 31 | 25 | EXPORT_PER_CPU_SYMBOL(cpu_number); |
| 32 | 26 | |
| @@ -247,7 +241,7 @@ void __init setup_per_cpu_areas(void) · 214 unmodified lines | ||
| 247 | 241 | #endif |
| 248 | 242 | #endif |
| 249 | 243 | /* |
| 250 | − * Up to this point, the boot CPU has been using .data.init | |
| 244 | + * Up to this point, the boot CPU has been using .init.data | |
| 251 | 245 | * area. Reload any changed state for the boot CPU. |
| 252 | 246 | */ |
| 253 | 247 | if (cpu == boot_cpu_id) |
| @@ -686,7 +686,7 @@ static void __cpuinit do_fork_idle(struct work_struct *work) · 685 unmodified lines | ||
| 686 | 686 | static void __cpuinit announce_cpu(int cpu, int apicid) |
| 687 | 687 | { |
| 688 | 688 | static int current_node = -1; |
| 689 | − int node = cpu_to_node(cpu); | |
| 689 | + int node = early_cpu_to_node(cpu); | |
| 690 | 690 | |
| 691 | 691 | if (system_state == SYSTEM_BOOTING) { |
| 692 | 692 | if (node != current_node) { |
| @@ -97,7 +97,7 @@ SECTIONS · 96 unmodified lines | ||
| 97 | 97 | HEAD_TEXT |
| 98 | 98 | #ifdef CONFIG_X86_32 |
| 99 | 99 | . = ALIGN(PAGE_SIZE); |
| 100 | − *(.text.page_aligned) | |
| 100 | + *(.text..page_aligned) | |
| 101 | 101 | #endif |
| 102 | 102 | . = ALIGN(8); |
| 103 | 103 | _stext = .; |
| @@ -305,7 +305,7 @@ SECTIONS · 201 unmodified lines | ||
| 305 | 305 | . = ALIGN(PAGE_SIZE); |
| 306 | 306 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { |
| 307 | 307 | __bss_start = .; |
| 308 | − *(.bss.page_aligned) | |
| 308 | + *(.bss..page_aligned) | |
| 309 | 309 | *(.bss) |
| 310 | 310 | . = ALIGN(4); |
| 311 | 311 | __bss_stop = .; |
| @@ -1815,6 +1815,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, · 1814 unmodified lines | ||
| 1815 | 1815 | |
| 1816 | 1816 | spte |= PT_WRITABLE_MASK; |
| 1817 | 1817 | |
| 1818 | + if (!tdp_enabled && !(pte_access & ACC_WRITE_MASK)) | |
| 1819 | + spte &= ~PT_USER_MASK; | |
| 1820 | + | |
| 1818 | 1821 | /* |
| 1819 | 1822 | * Optimization: for pte sync, if spte was writable the hash |
| 1820 | 1823 | * lookup is unnecessary (and expensive). Write protection |
| @@ -1870,6 +1873,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, · 49 unmodified lines | ||
| 1870 | 1873 | |
| 1871 | 1874 | child = page_header(pte & PT64_BASE_ADDR_MASK); |
| 1872 | 1875 | mmu_page_remove_parent_pte(child, sptep); |
| 1876 | + __set_spte(sptep, shadow_trap_nonpresent_pte); | |
| 1877 | + kvm_flush_remote_tlbs(vcpu->kvm); | |
| 1873 | 1878 | } else if (pfn != spte_to_pfn(*sptep)) { |
| 1874 | 1879 | pgprintk("hfn old %lx new %lx\n", |
| 1875 | 1880 | spte_to_pfn(*sptep), pfn); |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/ftrace_event.h> |
| 29 | 29 | #include <linux/slab.h> |
| 30 | 30 | |
| 31 | +#include <asm/tlbflush.h> | |
| 31 | 32 | #include <asm/desc.h> |
| 32 | 33 | |
| 33 | 34 | #include <asm/virtext.h> |
| @@ -56,6 +57,8 @@ MODULE_LICENSE("GPL"); · 22 unmodified lines | ||
| 56 | 57 | |
| 57 | 58 | #define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) |
| 58 | 59 | |
| 60 | +static bool erratum_383_found __read_mostly; | |
| 61 | + | |
| 59 | 62 | static const u32 host_save_user_msrs[] = { |
| 60 | 63 | #ifdef CONFIG_X86_64 |
| 61 | 64 | MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, |
| @@ -374,6 +377,31 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, · 312 unmodified lines | ||
| 374 | 377 | svm->vmcb->control.event_inj_err = error_code; |
| 375 | 378 | } |
| 376 | 379 | |
| 380 | +static void svm_init_erratum_383(void) | |
| 381 | +{ | |
| 382 | + u32 low, high; | |
| 383 | + int err; | |
| 384 | + u64 val; | |
| 385 | + | |
| 386 | + /* Only Fam10h is affected */ | |
| 387 | + if (boot_cpu_data.x86 != 0x10) | |
| 388 | + return; | |
| 389 | + | |
| 390 | + /* Use _safe variants to not break nested virtualization */ | |
| 391 | + val = native_read_msr_safe(MSR_AMD64_DC_CFG, &err); | |
| 392 | + if (err) | |
| 393 | + return; | |
| 394 | + | |
| 395 | + val |= (1ULL << 47); | |
| 396 | + | |
| 397 | + low = lower_32_bits(val); | |
| 398 | + high = upper_32_bits(val); | |
| 399 | + | |
| 400 | + native_write_msr_safe(MSR_AMD64_DC_CFG, low, high); | |
| 401 | + | |
| 402 | + erratum_383_found = true; | |
| 403 | +} | |
| 404 | + | |
| 377 | 405 | static int has_svm(void) |
| 378 | 406 | { |
| 379 | 407 | const char *msg; |
| @@ -429,6 +457,8 @@ static int svm_hardware_enable(void *garbage) · 49 unmodified lines | ||
| 429 | 457 | |
| 430 | 458 | wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT); |
| 431 | 459 | |
| 460 | + svm_init_erratum_383(); | |
| 461 | + | |
| 432 | 462 | return 0; |
| 433 | 463 | } |
| 434 | 464 | |
| @@ -1410,8 +1440,59 @@ static int nm_interception(struct vcpu_svm *svm) · 975 unmodified lines | ||
| 1410 | 1440 | return 1; |
| 1411 | 1441 | } |
| 1412 | 1442 | |
| 1413 | −static int mc_interception(struct vcpu_svm *svm) | |
| 1443 | +static bool is_erratum_383(void) | |
| 1414 | 1444 | { |
| 1445 | + int err, i; | |
| 1446 | + u64 value; | |
| 1447 | + | |
| 1448 | + if (!erratum_383_found) | |
| 1449 | + return false; | |
| 1450 | + | |
| 1451 | + value = native_read_msr_safe(MSR_IA32_MC0_STATUS, &err); | |
| 1452 | + if (err) | |
| 1453 | + return false; | |
| 1454 | + | |
| 1455 | + /* Bit 62 may or may not be set for this mce */ | |
| 1456 | + value &= ~(1ULL << 62); | |
| 1457 | + | |
| 1458 | + if (value != 0xb600000000010015ULL) | |
| 1459 | + return false; | |
| 1460 | + | |
| 1461 | + /* Clear MCi_STATUS registers */ | |
| 1462 | + for (i = 0; i < 6; ++i) | |
| 1463 | + native_write_msr_safe(MSR_IA32_MCx_STATUS(i), 0, 0); | |
| 1464 | + | |
| 1465 | + value = native_read_msr_safe(MSR_IA32_MCG_STATUS, &err); | |
| 1466 | + if (!err) { | |
| 1467 | + u32 low, high; | |
| 1468 | + | |
| 1469 | + value &= ~(1ULL << 2); | |
| 1470 | + low = lower_32_bits(value); | |
| 1471 | + high = upper_32_bits(value); | |
| 1472 | + | |
| 1473 | + native_write_msr_safe(MSR_IA32_MCG_STATUS, low, high); | |
| 1474 | + } | |
| 1475 | + | |
| 1476 | + /* Flush tlb to evict multi-match entries */ | |
| 1477 | + __flush_tlb_all(); | |
| 1478 | + | |
| 1479 | + return true; | |
| 1480 | +} | |
| 1481 | + | |
| 1482 | +static void svm_handle_mce(struct vcpu_svm *svm) | |
| 1483 | +{ | |
| 1484 | + if (is_erratum_383()) { | |
| 1485 | + /* | |
| 1486 | + * Erratum 383 triggered. Guest state is corrupt so kill the | |
| 1487 | + * guest. | |
| 1488 | + */ | |
| 1489 | + pr_err("KVM: Guest triggered AMD Erratum 383\n"); | |
| 1490 | + | |
| 1491 | + set_bit(KVM_REQ_TRIPLE_FAULT, &svm->vcpu.requests); | |
| 1492 | + | |
| 1493 | + return; | |
| 1494 | + } | |
| 1495 | + | |
| 1415 | 1496 | /* |
| 1416 | 1497 | * On an #MC intercept the MCE handler is not called automatically in |
| 1417 | 1498 | * the host. So do it by hand here. |
| @@ -1420,6 +1501,11 @@ static int mc_interception(struct vcpu_svm *svm) · 2 unmodified lines | ||
| 1420 | 1501 | "int $0x12\n"); |
| 1421 | 1502 | /* not sure if we ever come back to this point */ |
| 1422 | 1503 | |
| 1504 | + return; | |
| 1505 | +} | |
| 1506 | + | |
| 1507 | +static int mc_interception(struct vcpu_svm *svm) | |
| 1508 | +{ | |
| 1423 | 1509 | return 1; |
| 1424 | 1510 | } |
| 1425 | 1511 | |
| @@ -3088,6 +3174,14 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) · 1662 unmodified lines | ||
| 3088 | 3174 | vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR); |
| 3089 | 3175 | vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR); |
| 3090 | 3176 | } |
| 3177 | + | |
| 3178 | + /* | |
| 3179 | + * We need to handle MC intercepts here before the vcpu has a chance to | |
| 3180 | + * change the physical cpu | |
| 3181 | + */ | |
| 3182 | + if (unlikely(svm->vmcb->control.exit_code == | |
| 3183 | + SVM_EXIT_EXCP_BASE + MC_VECTOR)) | |
| 3184 | + svm_handle_mce(svm); | |
| 3091 | 3185 | } |
| 3092 | 3186 | |
| 3093 | 3187 | #undef R |
| @@ -3,12 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/module.h> |
| 4 | 4 | #include <linux/bootmem.h> |
| 5 | 5 | |
| 6 | −#ifdef CONFIG_DEBUG_PER_CPU_MAPS | |
| 7 | −# define DBG(x...) printk(KERN_DEBUG x) | |
| 8 | −#else | |
| 9 | −# define DBG(x...) | |
| 10 | −#endif | |
| 11 | − | |
| 12 | 6 | /* |
| 13 | 7 | * Which logical CPUs are on which nodes |
| 14 | 8 | */ |
| @@ -96,6 +96,7 @@ EXPORT_SYMBOL(pcibios_align_resource); · 95 unmodified lines | ||
| 96 | 96 | * the fact the PCI specs explicitly allow address decoders to be |
| 97 | 97 | * shared between expansion ROMs and other resource regions, it's |
| 98 | 98 | * at least dangerous) |
| 99 | + * - bad resource sizes or overlaps with other regions | |
| 99 | 100 | * |
| 100 | 101 | * Our solution: |
| 101 | 102 | * (1) Allocate resources for all buses behind PCI-to-PCI bridges. |
| @@ -136,6 +137,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) · 34 unmodified lines | ||
| 136 | 137 | * child resource allocations in this |
| 137 | 138 | * range. |
| 138 | 139 | */ |
| 140 | + r->start = r->end = 0; | |
| 139 | 141 | r->flags = 0; |
| 140 | 142 | } |
| 141 | 143 | } |
| @@ -11,28 +11,14 @@ · 10 unmodified lines | ||
| 11 | 11 | */ |
| 12 | 12 | static void __devinit pcibios_fixup_peer_bridges(void) |
| 13 | 13 | { |
| 14 | − int n, devfn; | |
| 15 | − long node; | |
| 14 | + int n; | |
| 16 | 15 | |
| 17 | 16 | if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff) |
| 18 | 17 | return; |
| 19 | 18 | DBG("PCI: Peer bridge fixup\n"); |
| 20 | 19 | |
| 21 | − for (n=0; n <= pcibios_last_bus; n++) { | |
| 22 | − u32 l; | |
| 23 | − if (pci_find_bus(0, n)) | |
| 24 | − continue; | |
| 25 | − node = get_mp_bus_to_node(n); | |
| 26 | − for (devfn = 0; devfn < 256; devfn += 8) { | |
| 27 | − if (!raw_pci_read(0, n, devfn, PCI_VENDOR_ID, 2, &l) && | |
| 28 | − l != 0x0000 && l != 0xffff) { | |
| 29 | − DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); | |
| 30 | − printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); | |
| 31 | − pci_scan_bus_on_node(n, &pci_root_ops, node); | |
| 32 | − break; | |
| 33 | − } | |
| 34 | − } | |
| 35 | − } | |
| 20 | + for (n=0; n <= pcibios_last_bus; n++) | |
| 21 | + pcibios_scan_specific_bus(n); | |
| 36 | 22 | } |
| 37 | 23 | |
| 38 | 24 | int __init pci_legacy_init(void) |
| @@ -50,6 +36,28 @@ int __init pci_legacy_init(void) · 11 unmodified lines | ||
| 50 | 36 | return 0; |
| 51 | 37 | } |
| 52 | 38 | |
| 39 | +void pcibios_scan_specific_bus(int busn) | |
| 40 | +{ | |
| 41 | + int devfn; | |
| 42 | + long node; | |
| 43 | + u32 l; | |
| 44 | + | |
| 45 | + if (pci_find_bus(0, busn)) | |
| 46 | + return; | |
| 47 | + | |
| 48 | + node = get_mp_bus_to_node(busn); | |
| 49 | + for (devfn = 0; devfn < 256; devfn += 8) { | |
| 50 | + if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) && | |
| 51 | + l != 0x0000 && l != 0xffff) { | |
| 52 | + DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l); | |
| 53 | + printk(KERN_INFO "PCI: Discovered peer bus %02x\n", busn); | |
| 54 | + pci_scan_bus_on_node(busn, &pci_root_ops, node); | |
| 55 | + return; | |
| 56 | + } | |
| 57 | + } | |
| 58 | +} | |
| 59 | +EXPORT_SYMBOL_GPL(pcibios_scan_specific_bus); | |
| 60 | + | |
| 53 | 61 | int __init pci_subsys_init(void) |
| 54 | 62 | { |
| 55 | 63 | /* |
| @@ -105,6 +105,8 @@ static void __save_processor_state(struct saved_context *ctxt) · 104 unmodified lines | ||
| 105 | 105 | ctxt->cr4 = read_cr4(); |
| 106 | 106 | ctxt->cr8 = read_cr8(); |
| 107 | 107 | #endif |
| 108 | + ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE, | |
| 109 | + &ctxt->misc_enable); | |
| 108 | 110 | } |
| 109 | 111 | |
| 110 | 112 | /* Needed by apm.c */ |
| @@ -152,6 +154,8 @@ static void fix_processor_context(void) · 41 unmodified lines | ||
| 152 | 154 | */ |
| 153 | 155 | static void __restore_processor_state(struct saved_context *ctxt) |
| 154 | 156 | { |
| 157 | + if (ctxt->misc_enable_saved) | |
| 158 | + wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable); | |
| 155 | 159 | /* |
| 156 | 160 | * control registers |
| 157 | 161 | */ |
| @@ -60,6 +60,6 @@ static void xen_vcpu_notify_restore(void *data) · 59 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | void xen_arch_resume(void) |
| 62 | 62 | { |
| 63 | − smp_call_function(xen_vcpu_notify_restore, | |
| 64 | − (void *)CLOCK_EVT_NOTIFY_RESUME, 1); | |
| 63 | + on_each_cpu(xen_vcpu_notify_restore, | |
| 64 | + (void *)CLOCK_EVT_NOTIFY_RESUME, 1); | |
| 65 | 65 | } |
| @@ -105,7 +105,6 @@ good_area: · 104 unmodified lines | ||
| 105 | 105 | * make sure we exit gracefully rather than endlessly redo |
| 106 | 106 | * the fault. |
| 107 | 107 | */ |
| 108 | −survive: | |
| 109 | 108 | fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); |
| 110 | 109 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 111 | 110 | if (fault & VM_FAULT_OOM) |
| @@ -146,15 +145,10 @@ bad_area: · 34 unmodified lines | ||
| 146 | 145 | */ |
| 147 | 146 | out_of_memory: |
| 148 | 147 | up_read(&mm->mmap_sem); |
| 149 | − if (is_global_init(current)) { | |
| 150 | − yield(); | |
| 151 | − down_read(&mm->mmap_sem); | |
| 152 | − goto survive; | |
| 153 | − } | |
| 154 | − printk("VM: killing process %s\n", current->comm); | |
| 155 | − if (user_mode(regs)) | |
| 156 | − do_group_exit(SIGKILL); | |
| 157 | − bad_page_fault(regs, address, SIGKILL); | |
| 148 | + if (!user_mode(regs)) | |
| 149 | + bad_page_fault(regs, address, SIGKILL); | |
| 150 | + else | |
| 151 | + pagefault_out_of_memory(); | |
| 158 | 152 | return; |
| 159 | 153 | |
| 160 | 154 | do_sigbus: |
| @@ -467,6 +467,9 @@ static int blk_init_free_list(struct request_queue *q) · 466 unmodified lines | ||
| 467 | 467 | { |
| 468 | 468 | struct request_list *rl = &q->rq; |
| 469 | 469 | |
| 470 | + if (unlikely(rl->rq_pool)) | |
| 471 | + return 0; | |
| 472 | + | |
| 470 | 473 | rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0; |
| 471 | 474 | rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0; |
| 472 | 475 | rl->elvpriv = 0; |
| @@ -570,9 +573,17 @@ EXPORT_SYMBOL(blk_init_queue); · 97 unmodified lines | ||
| 570 | 573 | struct request_queue * |
| 571 | 574 | blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) |
| 572 | 575 | { |
| 573 | − struct request_queue *q = blk_alloc_queue_node(GFP_KERNEL, node_id); | |
| 576 | + struct request_queue *uninit_q, *q; | |
| 577 | + | |
| 578 | + uninit_q = blk_alloc_queue_node(GFP_KERNEL, node_id); | |
| 579 | + if (!uninit_q) | |
| 580 | + return NULL; | |
| 581 | + | |
| 582 | + q = blk_init_allocated_queue_node(uninit_q, rfn, lock, node_id); | |
| 583 | + if (!q) | |
| 584 | + blk_cleanup_queue(uninit_q); | |
| 574 | 585 | |
| 575 | − return blk_init_allocated_queue_node(q, rfn, lock, node_id); | |
| 586 | + return q; | |
| 576 | 587 | } |
| 577 | 588 | EXPORT_SYMBOL(blk_init_queue_node); |
| 578 | 589 | |
| @@ -592,10 +603,8 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn, · 13 unmodified lines | ||
| 592 | 603 | return NULL; |
| 593 | 604 | |
| 594 | 605 | q->node = node_id; |
| 595 | − if (blk_init_free_list(q)) { | |
| 596 | − kmem_cache_free(blk_requestq_cachep, q); | |
| 606 | + if (blk_init_free_list(q)) | |
| 597 | 607 | return NULL; |
| 598 | − } | |
| 599 | 608 | |
| 600 | 609 | q->request_fn = rfn; |
| 601 | 610 | q->prep_rq_fn = NULL; |
| @@ -618,7 +627,6 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn, · 16 unmodified lines | ||
| 618 | 627 | return q; |
| 619 | 628 | } |
| 620 | 629 | |
| 621 | − blk_put_queue(q); | |
| 622 | 630 | return NULL; |
| 623 | 631 | } |
| 624 | 632 | EXPORT_SYMBOL(blk_init_allocated_queue_node); |
| @@ -64,6 +64,9 @@ static DEFINE_PER_CPU(unsigned long, cfq_ioc_count); · 63 unmodified lines | ||
| 64 | 64 | static struct completion *ioc_gone; |
| 65 | 65 | static DEFINE_SPINLOCK(ioc_gone_lock); |
| 66 | 66 | |
| 67 | +static DEFINE_SPINLOCK(cic_index_lock); | |
| 68 | +static DEFINE_IDA(cic_index_ida); | |
| 69 | + | |
| 67 | 70 | #define CFQ_PRIO_LISTS IOPRIO_BE_NR |
| 68 | 71 | #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) |
| 69 | 72 | #define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT) |
| @@ -271,6 +274,7 @@ struct cfq_data { · 201 unmodified lines | ||
| 271 | 274 | unsigned int cfq_latency; |
| 272 | 275 | unsigned int cfq_group_isolation; |
| 273 | 276 | |
| 277 | + unsigned int cic_index; | |
| 274 | 278 | struct list_head cic_list; |
| 275 | 279 | |
| 276 | 280 | /* |
| @@ -430,6 +434,24 @@ static inline void cic_set_cfqq(struct cfq_io_context *cic, · 153 unmodified lines | ||
| 430 | 434 | cic->cfqq[is_sync] = cfqq; |
| 431 | 435 | } |
| 432 | 436 | |
| 437 | +#define CIC_DEAD_KEY 1ul | |
| 438 | +#define CIC_DEAD_INDEX_SHIFT 1 | |
| 439 | + | |
| 440 | +static inline void *cfqd_dead_key(struct cfq_data *cfqd) | |
| 441 | +{ | |
| 442 | + return (void *)(cfqd->cic_index << CIC_DEAD_INDEX_SHIFT | CIC_DEAD_KEY); | |
| 443 | +} | |
| 444 | + | |
| 445 | +static inline struct cfq_data *cic_to_cfqd(struct cfq_io_context *cic) | |
| 446 | +{ | |
| 447 | + struct cfq_data *cfqd = cic->key; | |
| 448 | + | |
| 449 | + if (unlikely((unsigned long) cfqd & CIC_DEAD_KEY)) | |
| 450 | + return NULL; | |
| 451 | + | |
| 452 | + return cfqd; | |
| 453 | +} | |
| 454 | + | |
| 433 | 455 | /* |
| 434 | 456 | * We regard a request as SYNC, if it's either a read or has the SYNC bit |
| 435 | 457 | * set (in which case it could also be direct WRITE). |
| @@ -2510,11 +2532,12 @@ static void cfq_cic_free(struct cfq_io_context *cic) · 2074 unmodified lines | ||
| 2510 | 2532 | static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) |
| 2511 | 2533 | { |
| 2512 | 2534 | unsigned long flags; |
| 2535 | + unsigned long dead_key = (unsigned long) cic->key; | |
| 2513 | 2536 | |
| 2514 | − BUG_ON(!cic->dead_key); | |
| 2537 | + BUG_ON(!(dead_key & CIC_DEAD_KEY)); | |
| 2515 | 2538 | |
| 2516 | 2539 | spin_lock_irqsave(&ioc->lock, flags); |
| 2517 | − radix_tree_delete(&ioc->radix_root, cic->dead_key); | |
| 2540 | + radix_tree_delete(&ioc->radix_root, dead_key >> CIC_DEAD_INDEX_SHIFT); | |
| 2518 | 2541 | hlist_del_rcu(&cic->cic_list); |
| 2519 | 2542 | spin_unlock_irqrestore(&ioc->lock, flags); |
| 2520 | 2543 | |
| @@ -2537,15 +2560,10 @@ static void cfq_free_io_context(struct io_context *ioc) · 16 unmodified lines | ||
| 2537 | 2560 | __call_for_each_cic(ioc, cic_free_func); |
| 2538 | 2561 | } |
| 2539 | 2562 | |
| 2540 | −static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |
| 2563 | +static void cfq_put_cooperator(struct cfq_queue *cfqq) | |
| 2541 | 2564 | { |
| 2542 | 2565 | struct cfq_queue *__cfqq, *next; |
| 2543 | 2566 | |
| 2544 | − if (unlikely(cfqq == cfqd->active_queue)) { | |
| 2545 | − __cfq_slice_expired(cfqd, cfqq, 0); | |
| 2546 | − cfq_schedule_dispatch(cfqd); | |
| 2547 | − } | |
| 2548 | − | |
| 2549 | 2567 | /* |
| 2550 | 2568 | * If this queue was scheduled to merge with another queue, be |
| 2551 | 2569 | * sure to drop the reference taken on that queue (and others in |
| @@ -2561,6 +2579,16 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) · 9 unmodified lines | ||
| 2561 | 2579 | cfq_put_queue(__cfqq); |
| 2562 | 2580 | __cfqq = next; |
| 2563 | 2581 | } |
| 2582 | +} | |
| 2583 | + | |
| 2584 | +static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |
| 2585 | +{ | |
| 2586 | + if (unlikely(cfqq == cfqd->active_queue)) { | |
| 2587 | + __cfq_slice_expired(cfqd, cfqq, 0); | |
| 2588 | + cfq_schedule_dispatch(cfqd); | |
| 2589 | + } | |
| 2590 | + | |
| 2591 | + cfq_put_cooperator(cfqq); | |
| 2564 | 2592 | |
| 2565 | 2593 | cfq_put_queue(cfqq); |
| 2566 | 2594 | } |
| @@ -2573,11 +2601,10 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd, · 6 unmodified lines | ||
| 2573 | 2601 | list_del_init(&cic->queue_list); |
| 2574 | 2602 | |
| 2575 | 2603 | /* |
| 2576 | − * Make sure key == NULL is seen for dead queues | |
| 2604 | + * Make sure dead mark is seen for dead queues | |
| 2577 | 2605 | */ |
| 2578 | 2606 | smp_wmb(); |
| 2579 | − cic->dead_key = (unsigned long) cic->key; | |
| 2580 | − cic->key = NULL; | |
| 2607 | + cic->key = cfqd_dead_key(cfqd); | |
| 2581 | 2608 | |
| 2582 | 2609 | if (ioc->ioc_data == cic) |
| 2583 | 2610 | rcu_assign_pointer(ioc->ioc_data, NULL); |
| @@ -2596,7 +2623,7 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd, · 12 unmodified lines | ||
| 2596 | 2623 | static void cfq_exit_single_io_context(struct io_context *ioc, |
| 2597 | 2624 | struct cfq_io_context *cic) |
| 2598 | 2625 | { |
| 2599 | − struct cfq_data *cfqd = cic->key; | |
| 2626 | + struct cfq_data *cfqd = cic_to_cfqd(cic); | |
| 2600 | 2627 | |
| 2601 | 2628 | if (cfqd) { |
| 2602 | 2629 | struct request_queue *q = cfqd->queue; |
| @@ -2609,7 +2636,7 @@ static void cfq_exit_single_io_context(struct io_context *ioc, · 6 unmodified lines | ||
| 2609 | 2636 | * race between exiting task and queue |
| 2610 | 2637 | */ |
| 2611 | 2638 | smp_read_barrier_depends(); |
| 2612 | − if (cic->key) | |
| 2639 | + if (cic->key == cfqd) | |
| 2613 | 2640 | __cfq_exit_single_io_context(cfqd, cic); |
| 2614 | 2641 | |
| 2615 | 2642 | spin_unlock_irqrestore(q->queue_lock, flags); |
| @@ -2689,7 +2716,7 @@ static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc) · 73 unmodified lines | ||
| 2689 | 2716 | |
| 2690 | 2717 | static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic) |
| 2691 | 2718 | { |
| 2692 | − struct cfq_data *cfqd = cic->key; | |
| 2719 | + struct cfq_data *cfqd = cic_to_cfqd(cic); | |
| 2693 | 2720 | struct cfq_queue *cfqq; |
| 2694 | 2721 | unsigned long flags; |
| 2695 | 2722 | |
| @@ -2746,7 +2773,7 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq, · 50 unmodified lines | ||
| 2746 | 2773 | static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic) |
| 2747 | 2774 | { |
| 2748 | 2775 | struct cfq_queue *sync_cfqq = cic_to_cfqq(cic, 1); |
| 2749 | − struct cfq_data *cfqd = cic->key; | |
| 2776 | + struct cfq_data *cfqd = cic_to_cfqd(cic); | |
| 2750 | 2777 | unsigned long flags; |
| 2751 | 2778 | struct request_queue *q; |
| 2752 | 2779 | |
| @@ -2883,12 +2910,13 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc, · 130 unmodified lines | ||
| 2883 | 2910 | unsigned long flags; |
| 2884 | 2911 | |
| 2885 | 2912 | WARN_ON(!list_empty(&cic->queue_list)); |
| 2913 | + BUG_ON(cic->key != cfqd_dead_key(cfqd)); | |
| 2886 | 2914 | |
| 2887 | 2915 | spin_lock_irqsave(&ioc->lock, flags); |
| 2888 | 2916 | |
| 2889 | 2917 | BUG_ON(ioc->ioc_data == cic); |
| 2890 | 2918 | |
| 2891 | − radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd); | |
| 2919 | + radix_tree_delete(&ioc->radix_root, cfqd->cic_index); | |
| 2892 | 2920 | hlist_del_rcu(&cic->cic_list); |
| 2893 | 2921 | spin_unlock_irqrestore(&ioc->lock, flags); |
| 2894 | 2922 | |
| @@ -2900,7 +2928,6 @@ cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc) · 5 unmodified lines | ||
| 2900 | 2928 | { |
| 2901 | 2929 | struct cfq_io_context *cic; |
| 2902 | 2930 | unsigned long flags; |
| 2903 | − void *k; | |
| 2904 | 2931 | |
| 2905 | 2932 | if (unlikely(!ioc)) |
| 2906 | 2933 | return NULL; |
| @@ -2917,13 +2944,11 @@ cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc) · 10 unmodified lines | ||
| 2917 | 2944 | } |
| 2918 | 2945 | |
| 2919 | 2946 | do { |
| 2920 | − cic = radix_tree_lookup(&ioc->radix_root, (unsigned long) cfqd); | |
| 2947 | + cic = radix_tree_lookup(&ioc->radix_root, cfqd->cic_index); | |
| 2921 | 2948 | rcu_read_unlock(); |
| 2922 | 2949 | if (!cic) |
| 2923 | 2950 | break; |
| 2924 | − /* ->key must be copied to avoid race with cfq_exit_queue() */ | |
| 2925 | − k = cic->key; | |
| 2926 | − if (unlikely(!k)) { | |
| 2951 | + if (unlikely(cic->key != cfqd)) { | |
| 2927 | 2952 | cfq_drop_dead_cic(cfqd, ioc, cic); |
| 2928 | 2953 | rcu_read_lock(); |
| 2929 | 2954 | continue; |
| @@ -2956,7 +2981,7 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, · 26 unmodified lines | ||
| 2956 | 2981 | |
| 2957 | 2982 | spin_lock_irqsave(&ioc->lock, flags); |
| 2958 | 2983 | ret = radix_tree_insert(&ioc->radix_root, |
| 2959 | − (unsigned long) cfqd, cic); | |
| 2984 | + cfqd->cic_index, cic); | |
| 2960 | 2985 | if (!ret) |
| 2961 | 2986 | hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list); |
| 2962 | 2987 | spin_unlock_irqrestore(&ioc->lock, flags); |
| @@ -3516,6 +3541,9 @@ split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq) · 553 unmodified lines | ||
| 3516 | 3541 | } |
| 3517 | 3542 | |
| 3518 | 3543 | cic_set_cfqq(cic, NULL, 1); |
| 3544 | + | |
| 3545 | + cfq_put_cooperator(cfqq); | |
| 3546 | + | |
| 3519 | 3547 | cfq_put_queue(cfqq); |
| 3520 | 3548 | return NULL; |
| 3521 | 3549 | } |
| @@ -3708,10 +3736,32 @@ static void cfq_exit_queue(struct elevator_queue *e) · 186 unmodified lines | ||
| 3708 | 3736 | |
| 3709 | 3737 | cfq_shutdown_timer_wq(cfqd); |
| 3710 | 3738 | |
| 3739 | + spin_lock(&cic_index_lock); | |
| 3740 | + ida_remove(&cic_index_ida, cfqd->cic_index); | |
| 3741 | + spin_unlock(&cic_index_lock); | |
| 3742 | + | |
| 3711 | 3743 | /* Wait for cfqg->blkg->key accessors to exit their grace periods. */ |
| 3712 | 3744 | call_rcu(&cfqd->rcu, cfq_cfqd_free); |
| 3713 | 3745 | } |
| 3714 | 3746 | |
| 3747 | +static int cfq_alloc_cic_index(void) | |
| 3748 | +{ | |
| 3749 | + int index, error; | |
| 3750 | + | |
| 3751 | + do { | |
| 3752 | + if (!ida_pre_get(&cic_index_ida, GFP_KERNEL)) | |
| 3753 | + return -ENOMEM; | |
| 3754 | + | |
| 3755 | + spin_lock(&cic_index_lock); | |
| 3756 | + error = ida_get_new(&cic_index_ida, &index); | |
| 3757 | + spin_unlock(&cic_index_lock); | |
| 3758 | + if (error && error != -EAGAIN) | |
| 3759 | + return error; | |
| 3760 | + } while (error); | |
| 3761 | + | |
| 3762 | + return index; | |
| 3763 | +} | |
| 3764 | + | |
| 3715 | 3765 | static void *cfq_init_queue(struct request_queue *q) |
| 3716 | 3766 | { |
| 3717 | 3767 | struct cfq_data *cfqd; |
| @@ -3719,10 +3769,16 @@ static void *cfq_init_queue(struct request_queue *q) · 1 unmodified line | ||
| 3719 | 3769 | struct cfq_group *cfqg; |
| 3720 | 3770 | struct cfq_rb_root *st; |
| 3721 | 3771 | |
| 3772 | + i = cfq_alloc_cic_index(); | |
| 3773 | + if (i < 0) | |
| 3774 | + return NULL; | |
| 3775 | + | |
| 3722 | 3776 | cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node); |
| 3723 | 3777 | if (!cfqd) |
| 3724 | 3778 | return NULL; |
| 3725 | 3779 | |
| 3780 | + cfqd->cic_index = i; | |
| 3781 | + | |
| 3726 | 3782 | /* Init root service tree */ |
| 3727 | 3783 | cfqd->grp_service_tree = CFQ_RB_ROOT; |
| 3728 | 3784 | |
| @@ -3984,6 +4040,7 @@ static void __exit cfq_exit(void) · 255 unmodified lines | ||
| 3984 | 4040 | */ |
| 3985 | 4041 | if (elv_ioc_count_read(cfq_ioc_count)) |
| 3986 | 4042 | wait_for_completion(&all_gone); |
| 4043 | + ida_destroy(&cic_index_ida); | |
| 3987 | 4044 | cfq_slab_kill(); |
| 3988 | 4045 | } |
| 3989 | 4046 | |
| @@ -242,9 +242,11 @@ int elevator_init(struct request_queue *q, char *name) · 241 unmodified lines | ||
| 242 | 242 | { |
| 243 | 243 | struct elevator_type *e = NULL; |
| 244 | 244 | struct elevator_queue *eq; |
| 245 | − int ret = 0; | |
| 246 | 245 | void *data; |
| 247 | 246 | |
| 247 | + if (unlikely(q->elevator)) | |
| 248 | + return 0; | |
| 249 | + | |
| 248 | 250 | INIT_LIST_HEAD(&q->queue_head); |
| 249 | 251 | q->last_merge = NULL; |
| 250 | 252 | q->end_sector = 0; |
| @@ -284,7 +286,7 @@ int elevator_init(struct request_queue *q, char *name) · 33 unmodified lines | ||
| 284 | 286 | } |
| 285 | 287 | |
| 286 | 288 | elevator_attach(q, eq, data); |
| 287 | − return ret; | |
| 289 | + return 0; | |
| 288 | 290 | } |
| 289 | 291 | EXPORT_SYMBOL(elevator_init); |
| 290 | 292 | |
| @@ -1097,7 +1099,7 @@ ssize_t elv_iosched_show(struct request_queue *q, char *name) · 806 unmodified lines | ||
| 1097 | 1099 | struct elevator_type *__e; |
| 1098 | 1100 | int len = 0; |
| 1099 | 1101 | |
| 1100 | − if (!q->elevator) | |
| 1102 | + if (!q->elevator || !blk_queue_stackable(q)) | |
| 1101 | 1103 | return sprintf(name, "none\n"); |
| 1102 | 1104 | |
| 1103 | 1105 | elv = e->elevator_type; |
| @@ -79,7 +79,7 @@ enum { · 78 unmodified lines | ||
| 79 | 79 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
| 80 | 80 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
| 81 | 81 | * OpReg are installed */ |
| 82 | − EC_FLAGS_FROZEN, /* Transactions are suspended */ | |
| 82 | + EC_FLAGS_BLOCKED, /* Transactions are blocked */ | |
| 83 | 83 | }; |
| 84 | 84 | |
| 85 | 85 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
| @@ -293,7 +293,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) · 207 unmodified lines | ||
| 293 | 293 | if (t->rdata) |
| 294 | 294 | memset(t->rdata, 0, t->rlen); |
| 295 | 295 | mutex_lock(&ec->lock); |
| 296 | − if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) { | |
| 296 | + if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { | |
| 297 | 297 | status = -EINVAL; |
| 298 | 298 | goto unlock; |
| 299 | 299 | } |
| @@ -459,7 +459,7 @@ int ec_transaction(u8 command, · 159 unmodified lines | ||
| 459 | 459 | |
| 460 | 460 | EXPORT_SYMBOL(ec_transaction); |
| 461 | 461 | |
| 462 | −void acpi_ec_suspend_transactions(void) | |
| 462 | +void acpi_ec_block_transactions(void) | |
| 463 | 463 | { |
| 464 | 464 | struct acpi_ec *ec = first_ec; |
| 465 | 465 | |
| @@ -468,11 +468,11 @@ void acpi_ec_suspend_transactions(void) · 2 unmodified lines | ||
| 468 | 468 | |
| 469 | 469 | mutex_lock(&ec->lock); |
| 470 | 470 | /* Prevent transactions from being carried out */ |
| 471 | − set_bit(EC_FLAGS_FROZEN, &ec->flags); | |
| 471 | + set_bit(EC_FLAGS_BLOCKED, &ec->flags); | |
| 472 | 472 | mutex_unlock(&ec->lock); |
| 473 | 473 | } |
| 474 | 474 | |
| 475 | −void acpi_ec_resume_transactions(void) | |
| 475 | +void acpi_ec_unblock_transactions(void) | |
| 476 | 476 | { |
| 477 | 477 | struct acpi_ec *ec = first_ec; |
| 478 | 478 | |
| @@ -481,10 +481,20 @@ void acpi_ec_resume_transactions(void) · 2 unmodified lines | ||
| 481 | 481 | |
| 482 | 482 | mutex_lock(&ec->lock); |
| 483 | 483 | /* Allow transactions to be carried out again */ |
| 484 | − clear_bit(EC_FLAGS_FROZEN, &ec->flags); | |
| 484 | + clear_bit(EC_FLAGS_BLOCKED, &ec->flags); | |
| 485 | 485 | mutex_unlock(&ec->lock); |
| 486 | 486 | } |
| 487 | 487 | |
| 488 | +void acpi_ec_unblock_transactions_early(void) | |
| 489 | +{ | |
| 490 | + /* | |
| 491 | + * Allow transactions to happen again (this function is called from | |
| 492 | + * atomic context during wakeup, so we don't need to acquire the mutex). | |
| 493 | + */ | |
| 494 | + if (first_ec) | |
| 495 | + clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); | |
| 496 | +} | |
| 497 | + | |
| 488 | 498 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) |
| 489 | 499 | { |
| 490 | 500 | int result; |
| @@ -49,8 +49,9 @@ void acpi_early_processor_set_pdc(void); · 48 unmodified lines | ||
| 49 | 49 | int acpi_ec_init(void); |
| 50 | 50 | int acpi_ec_ecdt_probe(void); |
| 51 | 51 | int acpi_boot_ec_enable(void); |
| 52 | −void acpi_ec_suspend_transactions(void); | |
| 53 | −void acpi_ec_resume_transactions(void); | |
| 52 | +void acpi_ec_block_transactions(void); | |
| 53 | +void acpi_ec_unblock_transactions(void); | |
| 54 | +void acpi_ec_unblock_transactions_early(void); | |
| 54 | 55 | |
| 55 | 56 | /*-------------------------------------------------------------------------- |
| 56 | 57 | Suspend/Resume |
| @@ -80,7 +80,7 @@ module_param(nocst, uint, 0000); · 79 unmodified lines | ||
| 80 | 80 | static unsigned int latency_factor __read_mostly = 2; |
| 81 | 81 | module_param(latency_factor, uint, 0644); |
| 82 | 82 | |
| 83 | −static s64 us_to_pm_timer_ticks(s64 t) | |
| 83 | +static u64 us_to_pm_timer_ticks(s64 t) | |
| 84 | 84 | { |
| 85 | 85 | return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); |
| 86 | 86 | } |
| @@ -731,10 +731,10 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) · 644 unmodified lines | ||
| 731 | 731 | |
| 732 | 732 | seq_puts(seq, "demotion[--] "); |
| 733 | 733 | |
| 734 | − seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", | |
| 734 | + seq_printf(seq, "latency[%03d] usage[%08d] duration[%020Lu]\n", | |
| 735 | 735 | pr->power.states[i].latency, |
| 736 | 736 | pr->power.states[i].usage, |
| 737 | − (unsigned long long)pr->power.states[i].time); | |
| 737 | + us_to_pm_timer_ticks(pr->power.states[i].time)); | |
| 738 | 738 | } |
| 739 | 739 | |
| 740 | 740 | end: |
| @@ -861,7 +861,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, · 120 unmodified lines | ||
| 861 | 861 | ktime_t kt1, kt2; |
| 862 | 862 | s64 idle_time_ns; |
| 863 | 863 | s64 idle_time; |
| 864 | − s64 sleep_ticks = 0; | |
| 865 | 864 | |
| 866 | 865 | pr = __get_cpu_var(processors); |
| 867 | 866 | |
| @@ -906,8 +905,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, · 38 unmodified lines | ||
| 906 | 905 | idle_time = idle_time_ns; |
| 907 | 906 | do_div(idle_time, NSEC_PER_USEC); |
| 908 | 907 | |
| 909 | − sleep_ticks = us_to_pm_timer_ticks(idle_time); | |
| 910 | − | |
| 911 | 908 | /* Tell the scheduler how much we idled: */ |
| 912 | 909 | sched_clock_idle_wakeup_event(idle_time_ns); |
| 913 | 910 | |
| @@ -918,7 +915,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, · 4 unmodified lines | ||
| 918 | 915 | cx->usage++; |
| 919 | 916 | |
| 920 | 917 | lapic_timer_state_broadcast(pr, cx, 0); |
| 921 | − cx->time += sleep_ticks; | |
| 918 | + cx->time += idle_time; | |
| 922 | 919 | return idle_time; |
| 923 | 920 | } |
| 924 | 921 | |
| @@ -940,7 +937,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, · 15 unmodified lines | ||
| 940 | 937 | ktime_t kt1, kt2; |
| 941 | 938 | s64 idle_time_ns; |
| 942 | 939 | s64 idle_time; |
| 943 | − s64 sleep_ticks = 0; | |
| 944 | 940 | |
| 945 | 941 | |
| 946 | 942 | pr = __get_cpu_var(processors); |
| @@ -1022,11 +1018,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, · 75 unmodified lines | ||
| 1022 | 1018 | spin_unlock(&c3_lock); |
| 1023 | 1019 | } |
| 1024 | 1020 | kt2 = ktime_get_real(); |
| 1025 | − idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1)); | |
| 1021 | + idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1)); | |
| 1026 | 1022 | idle_time = idle_time_ns; |
| 1027 | 1023 | do_div(idle_time, NSEC_PER_USEC); |
| 1028 | 1024 | |
| 1029 | − sleep_ticks = us_to_pm_timer_ticks(idle_time); | |
| 1030 | 1025 | /* Tell the scheduler how much we idled: */ |
| 1031 | 1026 | sched_clock_idle_wakeup_event(idle_time_ns); |
| 1032 | 1027 | |
| @@ -1037,7 +1032,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, · 4 unmodified lines | ||
| 1037 | 1032 | cx->usage++; |
| 1038 | 1033 | |
| 1039 | 1034 | lapic_timer_state_broadcast(pr, cx, 0); |
| 1040 | − cx->time += sleep_ticks; | |
| 1035 | + cx->time += idle_time; | |
| 1041 | 1036 | return idle_time; |
| 1042 | 1037 | } |
| 1043 | 1038 | |
| @@ -94,11 +94,13 @@ void __init acpi_old_suspend_ordering(void) · 93 unmodified lines | ||
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | /** |
| 97 | − * acpi_pm_disable_gpes - Disable the GPEs. | |
| 97 | + * acpi_pm_freeze - Disable the GPEs and suspend EC transactions. | |
| 98 | 98 | */ |
| 99 | −static int acpi_pm_disable_gpes(void) | |
| 99 | +static int acpi_pm_freeze(void) | |
| 100 | 100 | { |
| 101 | 101 | acpi_disable_all_gpes(); |
| 102 | + acpi_os_wait_events_complete(NULL); | |
| 103 | + acpi_ec_block_transactions(); | |
| 102 | 104 | return 0; |
| 103 | 105 | } |
| 104 | 106 | |
| @@ -126,7 +128,8 @@ static int acpi_pm_prepare(void) · 21 unmodified lines | ||
| 126 | 128 | int error = __acpi_pm_prepare(); |
| 127 | 129 | |
| 128 | 130 | if (!error) |
| 129 | − acpi_disable_all_gpes(); | |
| 131 | + acpi_pm_freeze(); | |
| 132 | + | |
| 130 | 133 | return error; |
| 131 | 134 | } |
| 132 | 135 | |
| @@ -256,6 +259,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) · 123 unmodified lines | ||
| 256 | 259 | * acpi_leave_sleep_state will reenable specific GPEs later |
| 257 | 260 | */ |
| 258 | 261 | acpi_disable_all_gpes(); |
| 262 | + /* Allow EC transactions to happen. */ | |
| 263 | + acpi_ec_unblock_transactions_early(); | |
| 259 | 264 | |
| 260 | 265 | local_irq_restore(flags); |
| 261 | 266 | printk(KERN_DEBUG "Back to C!\n"); |
| @@ -267,6 +272,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state) · 5 unmodified lines | ||
| 267 | 272 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
| 268 | 273 | } |
| 269 | 274 | |
| 275 | +static void acpi_suspend_finish(void) | |
| 276 | +{ | |
| 277 | + acpi_ec_unblock_transactions(); | |
| 278 | + acpi_pm_finish(); | |
| 279 | +} | |
| 280 | + | |
| 270 | 281 | static int acpi_suspend_state_valid(suspend_state_t pm_state) |
| 271 | 282 | { |
| 272 | 283 | u32 acpi_state; |
| @@ -288,7 +299,7 @@ static struct platform_suspend_ops acpi_suspend_ops = { · 15 unmodified lines | ||
| 288 | 299 | .begin = acpi_suspend_begin, |
| 289 | 300 | .prepare_late = acpi_pm_prepare, |
| 290 | 301 | .enter = acpi_suspend_enter, |
| 291 | − .wake = acpi_pm_finish, | |
| 302 | + .wake = acpi_suspend_finish, | |
| 292 | 303 | .end = acpi_pm_end, |
| 293 | 304 | }; |
| 294 | 305 | |
| @@ -314,9 +325,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) · 19 unmodified lines | ||
| 314 | 325 | static struct platform_suspend_ops acpi_suspend_ops_old = { |
| 315 | 326 | .valid = acpi_suspend_state_valid, |
| 316 | 327 | .begin = acpi_suspend_begin_old, |
| 317 | − .prepare_late = acpi_pm_disable_gpes, | |
| 328 | + .prepare_late = acpi_pm_freeze, | |
| 318 | 329 | .enter = acpi_suspend_enter, |
| 319 | − .wake = acpi_pm_finish, | |
| 330 | + .wake = acpi_suspend_finish, | |
| 320 | 331 | .end = acpi_pm_end, |
| 321 | 332 | .recover = acpi_pm_finish, |
| 322 | 333 | }; |
| @@ -433,6 +444,7 @@ static int acpi_hibernation_enter(void) · 110 unmodified lines | ||
| 433 | 444 | static void acpi_hibernation_finish(void) |
| 434 | 445 | { |
| 435 | 446 | hibernate_nvs_free(); |
| 447 | + acpi_ec_unblock_transactions(); | |
| 436 | 448 | acpi_pm_finish(); |
| 437 | 449 | } |
| 438 | 450 | |
| @@ -453,19 +465,13 @@ static void acpi_hibernation_leave(void) · 14 unmodified lines | ||
| 453 | 465 | } |
| 454 | 466 | /* Restore the NVS memory area */ |
| 455 | 467 | hibernate_nvs_restore(); |
| 468 | + /* Allow EC transactions to happen. */ | |
| 469 | + acpi_ec_unblock_transactions_early(); | |
| 456 | 470 | } |
| 457 | 471 | |
| 458 | −static int acpi_pm_pre_restore(void) | |
| 459 | −{ | |
| 460 | − acpi_disable_all_gpes(); | |
| 461 | − acpi_os_wait_events_complete(NULL); | |
| 462 | − acpi_ec_suspend_transactions(); | |
| 463 | − return 0; | |
| 464 | −} | |
| 465 | − | |
| 466 | −static void acpi_pm_restore_cleanup(void) | |
| 472 | +static void acpi_pm_thaw(void) | |
| 467 | 473 | { |
| 468 | − acpi_ec_resume_transactions(); | |
| 474 | + acpi_ec_unblock_transactions(); | |
| 469 | 475 | acpi_enable_all_runtime_gpes(); |
| 470 | 476 | } |
| 471 | 477 | |
| @@ -477,8 +483,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { · 5 unmodified lines | ||
| 477 | 483 | .prepare = acpi_pm_prepare, |
| 478 | 484 | .enter = acpi_hibernation_enter, |
| 479 | 485 | .leave = acpi_hibernation_leave, |
| 480 | − .pre_restore = acpi_pm_pre_restore, | |
| 481 | − .restore_cleanup = acpi_pm_restore_cleanup, | |
| 486 | + .pre_restore = acpi_pm_freeze, | |
| 487 | + .restore_cleanup = acpi_pm_thaw, | |
| 482 | 488 | }; |
| 483 | 489 | |
| 484 | 490 | /** |
| @@ -510,12 +516,9 @@ static int acpi_hibernation_begin_old(void) · 25 unmodified lines | ||
| 510 | 516 | |
| 511 | 517 | static int acpi_hibernation_pre_snapshot_old(void) |
| 512 | 518 | { |
| 513 | − int error = acpi_pm_disable_gpes(); | |
| 514 | − | |
| 515 | − if (!error) | |
| 516 | − hibernate_nvs_save(); | |
| 517 | − | |
| 518 | − return error; | |
| 519 | + acpi_pm_freeze(); | |
| 520 | + hibernate_nvs_save(); | |
| 521 | + return 0; | |
| 519 | 522 | } |
| 520 | 523 | |
| 521 | 524 | /* |
| @@ -527,11 +530,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { · 5 unmodified lines | ||
| 527 | 530 | .end = acpi_pm_end, |
| 528 | 531 | .pre_snapshot = acpi_hibernation_pre_snapshot_old, |
| 529 | 532 | .finish = acpi_hibernation_finish, |
| 530 | − .prepare = acpi_pm_disable_gpes, | |
| 533 | + .prepare = acpi_pm_freeze, | |
| 531 | 534 | .enter = acpi_hibernation_enter, |
| 532 | 535 | .leave = acpi_hibernation_leave, |
| 533 | − .pre_restore = acpi_pm_pre_restore, | |
| 534 | − .restore_cleanup = acpi_pm_restore_cleanup, | |
| 536 | + .pre_restore = acpi_pm_freeze, | |
| 537 | + .restore_cleanup = acpi_pm_thaw, | |
| 535 | 538 | .recover = acpi_pm_finish, |
| 536 | 539 | }; |
| 537 | 540 | #endif /* CONFIG_HIBERNATION */ |
| @@ -168,10 +168,10 @@ config ATA_BMDMA · 167 unmodified lines | ||
| 168 | 168 | default y |
| 169 | 169 | help |
| 170 | 170 | This option adds support for SFF ATA controllers with BMDMA |
| 171 | − capability. BMDMA stands for bus-master DMA and the | |
| 172 | − de-facto DMA interface for SFF controllers. | |
| 171 | + capability. BMDMA stands for bus-master DMA and is the | |
| 172 | + de facto DMA interface for SFF controllers. | |
| 173 | 173 | |
| 174 | − If unuser, say Y. | |
| 174 | + If unsure, say Y. | |
| 175 | 175 | |
| 176 | 176 | if ATA_BMDMA |
| 177 | 177 | |
| @@ -541,29 +541,11 @@ static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) · 540 unmodified lines | ||
| 541 | 541 | return -EINVAL; |
| 542 | 542 | } |
| 543 | 543 | |
| 544 | −static int ahci_is_device_present(void __iomem *port_mmio) | |
| 545 | −{ | |
| 546 | − u8 status = readl(port_mmio + PORT_TFDATA) & 0xff; | |
| 547 | − | |
| 548 | − /* Make sure PxTFD.STS.BSY and PxTFD.STS.DRQ are 0 */ | |
| 549 | − if (status & (ATA_BUSY | ATA_DRQ)) | |
| 550 | − return 0; | |
| 551 | − | |
| 552 | − /* Make sure PxSSTS.DET is 3h */ | |
| 553 | − status = readl(port_mmio + PORT_SCR_STAT) & 0xf; | |
| 554 | − if (status != 3) | |
| 555 | − return 0; | |
| 556 | − return 1; | |
| 557 | −} | |
| 558 | − | |
| 559 | 544 | void ahci_start_engine(struct ata_port *ap) |
| 560 | 545 | { |
| 561 | 546 | void __iomem *port_mmio = ahci_port_base(ap); |
| 562 | 547 | u32 tmp; |
| 563 | 548 | |
| 564 | − if (!ahci_is_device_present(port_mmio)) | |
| 565 | − return; | |
| 566 | − | |
| 567 | 549 | /* start DMA */ |
| 568 | 550 | tmp = readl(port_mmio + PORT_CMD); |
| 569 | 551 | tmp |= PORT_CMD_START; |
| @@ -1892,6 +1874,9 @@ static void ahci_error_handler(struct ata_port *ap) · 1322 unmodified lines | ||
| 1892 | 1874 | } |
| 1893 | 1875 | |
| 1894 | 1876 | sata_pmp_error_handler(ap); |
| 1877 | + | |
| 1878 | + if (!ata_dev_enabled(ap->link.device)) | |
| 1879 | + ahci_stop_engine(ap); | |
| 1895 | 1880 | } |
| 1896 | 1881 | |
| 1897 | 1882 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) |
| @@ -4119,9 +4119,8 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, · 4118 unmodified lines | ||
| 4119 | 4119 | dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) { |
| 4120 | 4120 | ata_dev_printk(dev, KERN_WARNING, |
| 4121 | 4121 | "new n_sectors matches native, probably " |
| 4122 | − "late HPA unlock, continuing\n"); | |
| 4123 | − /* keep using the old n_sectors */ | |
| 4124 | − dev->n_sectors = n_sectors; | |
| 4122 | + "late HPA unlock, n_sectors updated\n"); | |
| 4123 | + /* use the larger n_sectors */ | |
| 4125 | 4124 | return 0; |
| 4126 | 4125 | } |
| 4127 | 4126 | |
| @@ -6669,6 +6668,7 @@ EXPORT_SYMBOL_GPL(ata_dummy_port_info); · 2541 unmodified lines | ||
| 6669 | 6668 | EXPORT_SYMBOL_GPL(ata_link_next); |
| 6670 | 6669 | EXPORT_SYMBOL_GPL(ata_dev_next); |
| 6671 | 6670 | EXPORT_SYMBOL_GPL(ata_std_bios_param); |
| 6671 | +EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity); | |
| 6672 | 6672 | EXPORT_SYMBOL_GPL(ata_host_init); |
| 6673 | 6673 | EXPORT_SYMBOL_GPL(ata_host_alloc); |
| 6674 | 6674 | EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); |
| @@ -414,6 +414,35 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, · 413 unmodified lines | ||
| 414 | 414 | return 0; |
| 415 | 415 | } |
| 416 | 416 | |
| 417 | +/** | |
| 418 | + * ata_scsi_unlock_native_capacity - unlock native capacity | |
| 419 | + * @sdev: SCSI device to adjust device capacity for | |
| 420 | + * | |
| 421 | + * This function is called if a partition on @sdev extends beyond | |
| 422 | + * the end of the device. It requests EH to unlock HPA. | |
| 423 | + * | |
| 424 | + * LOCKING: | |
| 425 | + * Defined by the SCSI layer. Might sleep. | |
| 426 | + */ | |
| 427 | +void ata_scsi_unlock_native_capacity(struct scsi_device *sdev) | |
| 428 | +{ | |
| 429 | + struct ata_port *ap = ata_shost_to_port(sdev->host); | |
| 430 | + struct ata_device *dev; | |
| 431 | + unsigned long flags; | |
| 432 | + | |
| 433 | + spin_lock_irqsave(ap->lock, flags); | |
| 434 | + | |
| 435 | + dev = ata_scsi_find_dev(ap, sdev); | |
| 436 | + if (dev && dev->n_sectors < dev->n_native_sectors) { | |
| 437 | + dev->flags |= ATA_DFLAG_UNLOCK_HPA; | |
| 438 | + dev->link->eh_info.action |= ATA_EH_RESET; | |
| 439 | + ata_port_schedule_eh(ap); | |
| 440 | + } | |
| 441 | + | |
| 442 | + spin_unlock_irqrestore(ap->lock, flags); | |
| 443 | + ata_port_wait_eh(ap); | |
| 444 | +} | |
| 445 | + | |
| 417 | 446 | /** |
| 418 | 447 | * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl |
| 419 | 448 | * @ap: target port |
| @@ -1355,8 +1355,11 @@ static struct of_device_id pata_macio_match[] = · 1354 unmodified lines | ||
| 1355 | 1355 | |
| 1356 | 1356 | static struct macio_driver pata_macio_driver = |
| 1357 | 1357 | { |
| 1358 | − .name = "pata-macio", | |
| 1359 | − .match_table = pata_macio_match, | |
| 1358 | + .driver = { | |
| 1359 | + .name = "pata-macio", | |
| 1360 | + .owner = THIS_MODULE, | |
| 1361 | + .of_match_table = pata_macio_match, | |
| 1362 | + }, | |
| 1360 | 1363 | .probe = pata_macio_attach, |
| 1361 | 1364 | .remove = pata_macio_detach, |
| 1362 | 1365 | #ifdef CONFIG_PM |
| @@ -1366,9 +1369,6 @@ static struct macio_driver pata_macio_driver = · 3 unmodified lines | ||
| 1366 | 1369 | #ifdef CONFIG_PMAC_MEDIABAY |
| 1367 | 1370 | .mediabay_event = pata_macio_mb_event, |
| 1368 | 1371 | #endif |
| 1369 | − .driver = { | |
| 1370 | − .owner = THIS_MODULE, | |
| 1371 | − }, | |
| 1372 | 1372 | }; |
| 1373 | 1373 | |
| 1374 | 1374 | static const struct pci_device_id pata_macio_pci_match[] = { |
| @@ -1669,7 +1669,6 @@ static void nv_mcp55_freeze(struct ata_port *ap) · 1668 unmodified lines | ||
| 1669 | 1669 | mask = readl(mmio_base + NV_INT_ENABLE_MCP55); |
| 1670 | 1670 | mask &= ~(NV_INT_ALL_MCP55 << shift); |
| 1671 | 1671 | writel(mask, mmio_base + NV_INT_ENABLE_MCP55); |
| 1672 | − ata_sff_freeze(ap); | |
| 1673 | 1672 | } |
| 1674 | 1673 | |
| 1675 | 1674 | static void nv_mcp55_thaw(struct ata_port *ap) |
| @@ -1683,7 +1682,6 @@ static void nv_mcp55_thaw(struct ata_port *ap) · 7 unmodified lines | ||
| 1683 | 1682 | mask = readl(mmio_base + NV_INT_ENABLE_MCP55); |
| 1684 | 1683 | mask |= (NV_INT_MASK_MCP55 << shift); |
| 1685 | 1684 | writel(mask, mmio_base + NV_INT_ENABLE_MCP55); |
| 1686 | − ata_sff_thaw(ap); | |
| 1687 | 1685 | } |
| 1688 | 1686 | |
| 1689 | 1687 | static void nv_adma_error_handler(struct ata_port *ap) |
| @@ -539,12 +539,12 @@ static void sil24_config_port(struct ata_port *ap) · 538 unmodified lines | ||
| 539 | 539 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); |
| 540 | 540 | |
| 541 | 541 | /* zero error counters. */ |
| 542 | − writel(0x8000, port + PORT_DECODE_ERR_THRESH); | |
| 543 | − writel(0x8000, port + PORT_CRC_ERR_THRESH); | |
| 544 | − writel(0x8000, port + PORT_HSHK_ERR_THRESH); | |
| 545 | − writel(0x0000, port + PORT_DECODE_ERR_CNT); | |
| 546 | − writel(0x0000, port + PORT_CRC_ERR_CNT); | |
| 547 | − writel(0x0000, port + PORT_HSHK_ERR_CNT); | |
| 542 | + writew(0x8000, port + PORT_DECODE_ERR_THRESH); | |
| 543 | + writew(0x8000, port + PORT_CRC_ERR_THRESH); | |
| 544 | + writew(0x8000, port + PORT_HSHK_ERR_THRESH); | |
| 545 | + writew(0x0000, port + PORT_DECODE_ERR_CNT); | |
| 546 | + writew(0x0000, port + PORT_CRC_ERR_CNT); | |
| 547 | + writew(0x0000, port + PORT_HSHK_ERR_CNT); | |
| 548 | 548 | |
| 549 | 549 | /* always use 64bit activation */ |
| 550 | 550 | writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR); |
| @@ -622,6 +622,11 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp, · 71 unmodified lines | ||
| 622 | 622 | irq_enabled = readl(port + PORT_IRQ_ENABLE_SET); |
| 623 | 623 | writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR); |
| 624 | 624 | |
| 625 | + /* | |
| 626 | + * The barrier is required to ensure that writes to cmd_block reach | |
| 627 | + * the memory before the write to PORT_CMD_ACTIVATE. | |
| 628 | + */ | |
| 629 | + wmb(); | |
| 625 | 630 | writel((u32)paddr, port + PORT_CMD_ACTIVATE); |
| 626 | 631 | writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); |
| 627 | 632 | |
| @@ -865,7 +870,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) · 237 unmodified lines | ||
| 865 | 870 | } else { |
| 866 | 871 | prb = &cb->atapi.prb; |
| 867 | 872 | sge = cb->atapi.sge; |
| 868 | − memset(cb->atapi.cdb, 0, 32); | |
| 873 | + memset(cb->atapi.cdb, 0, sizeof(cb->atapi.cdb)); | |
| 869 | 874 | memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len); |
| 870 | 875 | |
| 871 | 876 | if (ata_is_data(qc->tf.protocol)) { |
| @@ -895,6 +900,11 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) · 23 unmodified lines | ||
| 895 | 900 | paddr = pp->cmd_block_dma + tag * sizeof(*pp->cmd_block); |
| 896 | 901 | activate = port + PORT_CMD_ACTIVATE + tag * 8; |
| 897 | 902 | |
| 903 | + /* | |
| 904 | + * The barrier is required to ensure that writes to cmd_block reach | |
| 905 | + * the memory before the write to PORT_CMD_ACTIVATE. | |
| 906 | + */ | |
| 907 | + wmb(); | |
| 898 | 908 | writel((u32)paddr, activate); |
| 899 | 909 | writel((u64)paddr >> 32, activate + 4); |
| 900 | 910 | |
| @@ -575,6 +575,33 @@ static void svia_configure(struct pci_dev *pdev) · 574 unmodified lines | ||
| 575 | 575 | tmp8 |= NATIVE_MODE_ALL; |
| 576 | 576 | pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); |
| 577 | 577 | } |
| 578 | + | |
| 579 | + /* | |
| 580 | + * vt6421 has problems talking to some drives. The following | |
| 581 | + * is the fix from Joseph Chan <JosephChan@via.com.tw>. | |
| 582 | + * | |
| 583 | + * When host issues HOLD, device may send up to 20DW of data | |
| 584 | + * before acknowledging it with HOLDA and the host should be | |
| 585 | + * able to buffer them in FIFO. Unfortunately, some WD drives | |
| 586 | + * send upto 40DW before acknowledging HOLD and, in the | |
| 587 | + * default configuration, this ends up overflowing vt6421's | |
| 588 | + * FIFO, making the controller abort the transaction with | |
| 589 | + * R_ERR. | |
| 590 | + * | |
| 591 | + * Rx52[2] is the internal 128DW FIFO Flow control watermark | |
| 592 | + * adjusting mechanism enable bit and the default value 0 | |
| 593 | + * means host will issue HOLD to device when the left FIFO | |
| 594 | + * size goes below 32DW. Setting it to 1 makes the watermark | |
| 595 | + * 64DW. | |
| 596 | + * | |
| 597 | + * https://bugzilla.kernel.org/show_bug.cgi?id=15173 | |
| 598 | + * http://article.gmane.org/gmane.linux.ide/46352 | |
| 599 | + */ | |
| 600 | + if (pdev->device == 0x3249) { | |
| 601 | + pci_read_config_byte(pdev, 0x52, &tmp8); | |
| 602 | + tmp8 |= 1 << 2; | |
| 603 | + pci_write_config_byte(pdev, 0x52, tmp8); | |
| 604 | + } | |
| 578 | 605 | } |
| 579 | 606 | |
| 580 | 607 | static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| @@ -133,6 +133,28 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) · 132 unmodified lines | ||
| 133 | 133 | return page; |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | +static void brd_free_page(struct brd_device *brd, sector_t sector) | |
| 137 | +{ | |
| 138 | + struct page *page; | |
| 139 | + pgoff_t idx; | |
| 140 | + | |
| 141 | + spin_lock(&brd->brd_lock); | |
| 142 | + idx = sector >> PAGE_SECTORS_SHIFT; | |
| 143 | + page = radix_tree_delete(&brd->brd_pages, idx); | |
| 144 | + spin_unlock(&brd->brd_lock); | |
| 145 | + if (page) | |
| 146 | + __free_page(page); | |
| 147 | +} | |
| 148 | + | |
| 149 | +static void brd_zero_page(struct brd_device *brd, sector_t sector) | |
| 150 | +{ | |
| 151 | + struct page *page; | |
| 152 | + | |
| 153 | + page = brd_lookup_page(brd, sector); | |
| 154 | + if (page) | |
| 155 | + clear_highpage(page); | |
| 156 | +} | |
| 157 | + | |
| 136 | 158 | /* |
| 137 | 159 | * Free all backing store pages and radix tree. This must only be called when |
| 138 | 160 | * there are no other users of the device. |
| @@ -189,6 +211,24 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n) · 50 unmodified lines | ||
| 189 | 211 | return 0; |
| 190 | 212 | } |
| 191 | 213 | |
| 214 | +static void discard_from_brd(struct brd_device *brd, | |
| 215 | + sector_t sector, size_t n) | |
| 216 | +{ | |
| 217 | + while (n >= PAGE_SIZE) { | |
| 218 | + /* | |
| 219 | + * Don't want to actually discard pages here because | |
| 220 | + * re-allocating the pages can result in writeback | |
| 221 | + * deadlocks under heavy load. | |
| 222 | + */ | |
| 223 | + if (0) | |
| 224 | + brd_free_page(brd, sector); | |
| 225 | + else | |
| 226 | + brd_zero_page(brd, sector); | |
| 227 | + sector += PAGE_SIZE >> SECTOR_SHIFT; | |
| 228 | + n -= PAGE_SIZE; | |
| 229 | + } | |
| 230 | +} | |
| 231 | + | |
| 192 | 232 | /* |
| 193 | 233 | * Copy n bytes from src to the brd starting at sector. Does not sleep. |
| 194 | 234 | */ |
| @@ -300,6 +340,12 @@ static int brd_make_request(struct request_queue *q, struct bio *bio) · 105 unmodified lines | ||
| 300 | 340 | get_capacity(bdev->bd_disk)) |
| 301 | 341 | goto out; |
| 302 | 342 | |
| 343 | + if (unlikely(bio_rw_flagged(bio, BIO_RW_DISCARD))) { | |
| 344 | + err = 0; | |
| 345 | + discard_from_brd(brd, sector, bio->bi_size); | |
| 346 | + goto out; | |
| 347 | + } | |
| 348 | + | |
| 303 | 349 | rw = bio_rw(bio); |
| 304 | 350 | if (rw == READA) |
| 305 | 351 | rw = READ; |
| @@ -320,7 +366,7 @@ out: · 14 unmodified lines | ||
| 320 | 366 | } |
| 321 | 367 | |
| 322 | 368 | #ifdef CONFIG_BLK_DEV_XIP |
| 323 | −static int brd_direct_access (struct block_device *bdev, sector_t sector, | |
| 369 | +static int brd_direct_access(struct block_device *bdev, sector_t sector, | |
| 324 | 370 | void **kaddr, unsigned long *pfn) |
| 325 | 371 | { |
| 326 | 372 | struct brd_device *brd = bdev->bd_disk->private_data; |
| @@ -437,6 +483,11 @@ static struct brd_device *brd_alloc(int i) · 110 unmodified lines | ||
| 437 | 483 | blk_queue_max_hw_sectors(brd->brd_queue, 1024); |
| 438 | 484 | blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); |
| 439 | 485 | |
| 486 | + brd->brd_queue->limits.discard_granularity = PAGE_SIZE; | |
| 487 | + brd->brd_queue->limits.max_discard_sectors = UINT_MAX; | |
| 488 | + brd->brd_queue->limits.discard_zeroes_data = 1; | |
| 489 | + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, brd->brd_queue); | |
| 490 | + | |
| 440 | 491 | disk = brd->brd_disk = alloc_disk(1 << part_shift); |
| 441 | 492 | if (!disk) |
| 442 | 493 | goto out_free_queue; |
| @@ -188,11 +188,11 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) · 187 unmodified lines | ||
| 188 | 188 | |
| 189 | 189 | sa = h->scsi_ctlr; |
| 190 | 190 | stk = &sa->cmd_stack; |
| 191 | + stk->top++; | |
| 191 | 192 | if (stk->top >= CMD_STACK_SIZE) { |
| 192 | 193 | printk("cciss: scsi_cmd_free called too many times.\n"); |
| 193 | 194 | BUG(); |
| 194 | 195 | } |
| 195 | − stk->top++; | |
| 196 | 196 | stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd; |
| 197 | 197 | } |
| 198 | 198 | |
| @@ -943,8 +943,7 @@ struct drbd_conf { · 942 unmodified lines | ||
| 943 | 943 | struct drbd_work resync_work, |
| 944 | 944 | unplug_work, |
| 945 | 945 | md_sync_work, |
| 946 | − delay_probe_work, | |
| 947 | − uuid_work; | |
| 946 | + delay_probe_work; | |
| 948 | 947 | struct timer_list resync_timer; |
| 949 | 948 | struct timer_list md_sync_timer; |
| 950 | 949 | struct timer_list delay_probe_timer; |
| @@ -1069,7 +1068,6 @@ struct drbd_conf { · 118 unmodified lines | ||
| 1069 | 1068 | struct timeval dps_time; /* delay-probes-start-time */ |
| 1070 | 1069 | unsigned int dp_volume_last; /* send_cnt of last delay probe */ |
| 1071 | 1070 | int c_sync_rate; /* current resync rate after delay_probe magic */ |
| 1072 | − atomic_t new_c_uuid; | |
| 1073 | 1071 | }; |
| 1074 | 1072 | |
| 1075 | 1073 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) |
| @@ -1476,7 +1474,6 @@ extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int); · 400 unmodified lines | ||
| 1476 | 1474 | extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int); |
| 1477 | 1475 | extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int); |
| 1478 | 1476 | extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int); |
| 1479 | −extern int w_io_error(struct drbd_conf *, struct drbd_work *, int); | |
| 1480 | 1477 | extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int); |
| 1481 | 1478 | extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int); |
| 1482 | 1479 | extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int); |
| @@ -1542,7 +1539,7 @@ static inline void drbd_tcp_nodelay(struct socket *sock) · 59 unmodified lines | ||
| 1542 | 1539 | |
| 1543 | 1540 | static inline void drbd_tcp_quickack(struct socket *sock) |
| 1544 | 1541 | { |
| 1545 | − int __user val = 1; | |
| 1542 | + int __user val = 2; | |
| 1546 | 1543 | (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, |
| 1547 | 1544 | (char __user *)&val, sizeof(val)); |
| 1548 | 1545 | } |
| @@ -1728,7 +1725,7 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, · 179 unmodified lines | ||
| 1728 | 1725 | switch (mdev->ldev->dc.on_io_error) { |
| 1729 | 1726 | case EP_PASS_ON: |
| 1730 | 1727 | if (!forcedetach) { |
| 1731 | − if (printk_ratelimit()) | |
| 1728 | + if (__ratelimit(&drbd_ratelimit_state)) | |
| 1732 | 1729 | dev_err(DEV, "Local IO failed in %s." |
| 1733 | 1730 | "Passing error on...\n", where); |
| 1734 | 1731 | break; |
| @@ -2219,8 +2216,6 @@ static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) · 484 unmodified lines | ||
| 2219 | 2216 | return 0; |
| 2220 | 2217 | if (test_bit(BITMAP_IO, &mdev->flags)) |
| 2221 | 2218 | return 0; |
| 2222 | − if (atomic_read(&mdev->new_c_uuid)) | |
| 2223 | − return 0; | |
| 2224 | 2219 | return 1; |
| 2225 | 2220 | } |
| 2226 | 2221 | |
| @@ -2241,9 +2236,6 @@ static inline void inc_ap_bio(struct drbd_conf *mdev, int count) · 14 unmodified lines | ||
| 2241 | 2236 | * to avoid races with the reconnect code, |
| 2242 | 2237 | * we need to atomic_inc within the spinlock. */ |
| 2243 | 2238 | |
| 2244 | − if (atomic_read(&mdev->new_c_uuid) && atomic_add_unless(&mdev->new_c_uuid, -1, 1)) | |
| 2245 | − drbd_queue_work_front(&mdev->data.work, &mdev->uuid_work); | |
| 2246 | − | |
| 2247 | 2239 | spin_lock_irq(&mdev->req_lock); |
| 2248 | 2240 | while (!__inc_ap_bio_cond(mdev)) { |
| 2249 | 2241 | prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); |
| @@ -1215,18 +1215,17 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, · 1214 unmodified lines | ||
| 1215 | 1215 | ns.pdsk == D_OUTDATED)) { |
| 1216 | 1216 | if (get_ldev(mdev)) { |
| 1217 | 1217 | if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && |
| 1218 | − mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE && | |
| 1219 | − !atomic_read(&mdev->new_c_uuid)) | |
| 1220 | − atomic_set(&mdev->new_c_uuid, 2); | |
| 1218 | + mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) { | |
| 1219 | + drbd_uuid_new_current(mdev); | |
| 1220 | + drbd_send_uuids(mdev); | |
| 1221 | + } | |
| 1221 | 1222 | put_ldev(mdev); |
| 1222 | 1223 | } |
| 1223 | 1224 | } |
| 1224 | 1225 | |
| 1225 | 1226 | if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { |
| 1226 | − /* Diskless peer becomes primary or got connected do diskless, primary peer. */ | |
| 1227 | − if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0 && | |
| 1228 | − !atomic_read(&mdev->new_c_uuid)) | |
| 1229 | − atomic_set(&mdev->new_c_uuid, 2); | |
| 1227 | + if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0) | |
| 1228 | + drbd_uuid_new_current(mdev); | |
| 1230 | 1229 | |
| 1231 | 1230 | /* D_DISKLESS Peer becomes secondary */ |
| 1232 | 1231 | if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) |
| @@ -1350,24 +1349,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, · 117 unmodified lines | ||
| 1350 | 1349 | drbd_md_sync(mdev); |
| 1351 | 1350 | } |
| 1352 | 1351 | |
| 1353 | −static int w_new_current_uuid(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | |
| 1354 | −{ | |
| 1355 | − if (get_ldev(mdev)) { | |
| 1356 | − if (mdev->ldev->md.uuid[UI_BITMAP] == 0) { | |
| 1357 | − drbd_uuid_new_current(mdev); | |
| 1358 | − if (get_net_conf(mdev)) { | |
| 1359 | − drbd_send_uuids(mdev); | |
| 1360 | − put_net_conf(mdev); | |
| 1361 | − } | |
| 1362 | − drbd_md_sync(mdev); | |
| 1363 | − } | |
| 1364 | − put_ldev(mdev); | |
| 1365 | − } | |
| 1366 | − atomic_dec(&mdev->new_c_uuid); | |
| 1367 | − wake_up(&mdev->misc_wait); | |
| 1368 | − | |
| 1369 | − return 1; | |
| 1370 | −} | |
| 1371 | 1352 | |
| 1372 | 1353 | static int drbd_thread_setup(void *arg) |
| 1373 | 1354 | { |
| @@ -2291,9 +2272,9 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket * · 917 unmodified lines | ||
| 2291 | 2272 | * with page_count == 0 or PageSlab. |
| 2292 | 2273 | */ |
| 2293 | 2274 | static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, |
| 2294 | − int offset, size_t size) | |
| 2275 | + int offset, size_t size, unsigned msg_flags) | |
| 2295 | 2276 | { |
| 2296 | − int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0); | |
| 2277 | + int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, msg_flags); | |
| 2297 | 2278 | kunmap(page); |
| 2298 | 2279 | if (sent == size) |
| 2299 | 2280 | mdev->send_cnt += size>>9; |
| @@ -2301,7 +2282,7 @@ static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, · 1 unmodified line | ||
| 2301 | 2282 | } |
| 2302 | 2283 | |
| 2303 | 2284 | static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, |
| 2304 | − int offset, size_t size) | |
| 2285 | + int offset, size_t size, unsigned msg_flags) | |
| 2305 | 2286 | { |
| 2306 | 2287 | mm_segment_t oldfs = get_fs(); |
| 2307 | 2288 | int sent, ok; |
| @@ -2314,14 +2295,15 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, · 6 unmodified lines | ||
| 2314 | 2295 | * __page_cache_release a page that would actually still be referenced |
| 2315 | 2296 | * by someone, leading to some obscure delayed Oops somewhere else. */ |
| 2316 | 2297 | if (disable_sendpage || (page_count(page) < 1) || PageSlab(page)) |
| 2317 | − return _drbd_no_send_page(mdev, page, offset, size); | |
| 2298 | + return _drbd_no_send_page(mdev, page, offset, size, msg_flags); | |
| 2318 | 2299 | |
| 2300 | + msg_flags |= MSG_NOSIGNAL; | |
| 2319 | 2301 | drbd_update_congested(mdev); |
| 2320 | 2302 | set_fs(KERNEL_DS); |
| 2321 | 2303 | do { |
| 2322 | 2304 | sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page, |
| 2323 | 2305 | offset, len, |
| 2324 | − MSG_NOSIGNAL); | |
| 2306 | + msg_flags); | |
| 2325 | 2307 | if (sent == -EAGAIN) { |
| 2326 | 2308 | if (we_should_drop_the_connection(mdev, |
| 2327 | 2309 | mdev->data.socket)) |
| @@ -2350,9 +2332,11 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio) · 22 unmodified lines | ||
| 2350 | 2332 | { |
| 2351 | 2333 | struct bio_vec *bvec; |
| 2352 | 2334 | int i; |
| 2335 | + /* hint all but last page with MSG_MORE */ | |
| 2353 | 2336 | __bio_for_each_segment(bvec, bio, i, 0) { |
| 2354 | 2337 | if (!_drbd_no_send_page(mdev, bvec->bv_page, |
| 2355 | − bvec->bv_offset, bvec->bv_len)) | |
| 2338 | + bvec->bv_offset, bvec->bv_len, | |
| 2339 | + i == bio->bi_vcnt -1 ? 0 : MSG_MORE)) | |
| 2356 | 2340 | return 0; |
| 2357 | 2341 | } |
| 2358 | 2342 | return 1; |
| @@ -2362,12 +2346,13 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) · 3 unmodified lines | ||
| 2362 | 2346 | { |
| 2363 | 2347 | struct bio_vec *bvec; |
| 2364 | 2348 | int i; |
| 2349 | + /* hint all but last page with MSG_MORE */ | |
| 2365 | 2350 | __bio_for_each_segment(bvec, bio, i, 0) { |
| 2366 | 2351 | if (!_drbd_send_page(mdev, bvec->bv_page, |
| 2367 | − bvec->bv_offset, bvec->bv_len)) | |
| 2352 | + bvec->bv_offset, bvec->bv_len, | |
| 2353 | + i == bio->bi_vcnt -1 ? 0 : MSG_MORE)) | |
| 2368 | 2354 | return 0; |
| 2369 | 2355 | } |
| 2370 | − | |
| 2371 | 2356 | return 1; |
| 2372 | 2357 | } |
| 2373 | 2358 | |
| @@ -2375,9 +2360,11 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) · 1 unmodified line | ||
| 2375 | 2360 | { |
| 2376 | 2361 | struct page *page = e->pages; |
| 2377 | 2362 | unsigned len = e->size; |
| 2363 | + /* hint all but last page with MSG_MORE */ | |
| 2378 | 2364 | page_chain_for_each(page) { |
| 2379 | 2365 | unsigned l = min_t(unsigned, len, PAGE_SIZE); |
| 2380 | − if (!_drbd_send_page(mdev, page, 0, l)) | |
| 2366 | + if (!_drbd_send_page(mdev, page, 0, l, | |
| 2367 | + page_chain_next(page) ? MSG_MORE : 0)) | |
| 2381 | 2368 | return 0; |
| 2382 | 2369 | len -= l; |
| 2383 | 2370 | } |
| @@ -2457,11 +2444,11 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) · 73 unmodified lines | ||
| 2457 | 2444 | p.dp_flags = cpu_to_be32(dp_flags); |
| 2458 | 2445 | set_bit(UNPLUG_REMOTE, &mdev->flags); |
| 2459 | 2446 | ok = (sizeof(p) == |
| 2460 | − drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE)); | |
| 2447 | + drbd_send(mdev, mdev->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0)); | |
| 2461 | 2448 | if (ok && dgs) { |
| 2462 | 2449 | dgb = mdev->int_dig_out; |
| 2463 | 2450 | drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); |
| 2464 | − ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); | |
| 2451 | + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); | |
| 2465 | 2452 | } |
| 2466 | 2453 | if (ok) { |
| 2467 | 2454 | if (mdev->net_conf->wire_protocol == DRBD_PROT_A) |
| @@ -2510,11 +2497,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, · 42 unmodified lines | ||
| 2510 | 2497 | return 0; |
| 2511 | 2498 | |
| 2512 | 2499 | ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, |
| 2513 | − sizeof(p), MSG_MORE); | |
| 2500 | + sizeof(p), dgs ? MSG_MORE : 0); | |
| 2514 | 2501 | if (ok && dgs) { |
| 2515 | 2502 | dgb = mdev->int_dig_out; |
| 2516 | 2503 | drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb); |
| 2517 | − ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); | |
| 2504 | + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); | |
| 2518 | 2505 | } |
| 2519 | 2506 | if (ok) |
| 2520 | 2507 | ok = _drbd_send_zc_ee(mdev, e); |
| @@ -2708,7 +2695,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) · 187 unmodified lines | ||
| 2708 | 2695 | atomic_set(&mdev->net_cnt, 0); |
| 2709 | 2696 | atomic_set(&mdev->packet_seq, 0); |
| 2710 | 2697 | atomic_set(&mdev->pp_in_use, 0); |
| 2711 | − atomic_set(&mdev->new_c_uuid, 0); | |
| 2712 | 2698 | |
| 2713 | 2699 | mutex_init(&mdev->md_io_mutex); |
| 2714 | 2700 | mutex_init(&mdev->data.mutex); |
| @@ -2739,14 +2725,12 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) · 24 unmodified lines | ||
| 2739 | 2725 | INIT_LIST_HEAD(&mdev->bm_io_work.w.list); |
| 2740 | 2726 | INIT_LIST_HEAD(&mdev->delay_probes); |
| 2741 | 2727 | INIT_LIST_HEAD(&mdev->delay_probe_work.list); |
| 2742 | − INIT_LIST_HEAD(&mdev->uuid_work.list); | |
| 2743 | 2728 | |
| 2744 | 2729 | mdev->resync_work.cb = w_resync_inactive; |
| 2745 | 2730 | mdev->unplug_work.cb = w_send_write_hint; |
| 2746 | 2731 | mdev->md_sync_work.cb = w_md_sync; |
| 2747 | 2732 | mdev->bm_io_work.w.cb = w_bitmap_io; |
| 2748 | 2733 | mdev->delay_probe_work.cb = w_delay_probes; |
| 2749 | − mdev->uuid_work.cb = w_new_current_uuid; | |
| 2750 | 2734 | init_timer(&mdev->resync_timer); |
| 2751 | 2735 | init_timer(&mdev->md_sync_timer); |
| 2752 | 2736 | init_timer(&mdev->delay_probe_timer); |
| @@ -3799,7 +3783,7 @@ _drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) · 1046 unmodified lines | ||
| 3799 | 3783 | if (ret) { |
| 3800 | 3784 | fault_count++; |
| 3801 | 3785 | |
| 3802 | − if (printk_ratelimit()) | |
| 3786 | + if (__ratelimit(&drbd_ratelimit_state)) | |
| 3803 | 3787 | dev_warn(DEV, "***Simulating %s failure\n", |
| 3804 | 3788 | _drbd_fault_str(type)); |
| 3805 | 3789 | } |
| @@ -42,7 +42,6 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <linux/unistd.h> |
| 43 | 43 | #include <linux/vmalloc.h> |
| 44 | 44 | #include <linux/random.h> |
| 45 | −#include <linux/mm.h> | |
| 46 | 45 | #include <linux/string.h> |
| 47 | 46 | #include <linux/scatterlist.h> |
| 48 | 47 | #include "drbd_int.h" |
| @@ -571,6 +570,25 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size) · 522 unmodified lines | ||
| 571 | 570 | return rv; |
| 572 | 571 | } |
| 573 | 572 | |
| 573 | +/* quoting tcp(7): | |
| 574 | + * On individual connections, the socket buffer size must be set prior to the | |
| 575 | + * listen(2) or connect(2) calls in order to have it take effect. | |
| 576 | + * This is our wrapper to do so. | |
| 577 | + */ | |
| 578 | +static void drbd_setbufsize(struct socket *sock, unsigned int snd, | |
| 579 | + unsigned int rcv) | |
| 580 | +{ | |
| 581 | + /* open coded SO_SNDBUF, SO_RCVBUF */ | |
| 582 | + if (snd) { | |
| 583 | + sock->sk->sk_sndbuf = snd; | |
| 584 | + sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK; | |
| 585 | + } | |
| 586 | + if (rcv) { | |
| 587 | + sock->sk->sk_rcvbuf = rcv; | |
| 588 | + sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK; | |
| 589 | + } | |
| 590 | +} | |
| 591 | + | |
| 574 | 592 | static struct socket *drbd_try_connect(struct drbd_conf *mdev) |
| 575 | 593 | { |
| 576 | 594 | const char *what; |
| @@ -592,6 +610,8 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev) · 15 unmodified lines | ||
| 592 | 610 | |
| 593 | 611 | sock->sk->sk_rcvtimeo = |
| 594 | 612 | sock->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ; |
| 613 | + drbd_setbufsize(sock, mdev->net_conf->sndbuf_size, | |
| 614 | + mdev->net_conf->rcvbuf_size); | |
| 595 | 615 | |
| 596 | 616 | /* explicitly bind to the configured IP as source IP |
| 597 | 617 | * for the outgoing connections. |
| @@ -670,6 +690,8 @@ static struct socket *drbd_wait_for_connect(struct drbd_conf *mdev) · 72 unmodified lines | ||
| 670 | 690 | s_listen->sk->sk_reuse = 1; /* SO_REUSEADDR */ |
| 671 | 691 | s_listen->sk->sk_rcvtimeo = timeo; |
| 672 | 692 | s_listen->sk->sk_sndtimeo = timeo; |
| 693 | + drbd_setbufsize(s_listen, mdev->net_conf->sndbuf_size, | |
| 694 | + mdev->net_conf->rcvbuf_size); | |
| 673 | 695 | |
| 674 | 696 | what = "bind before listen"; |
| 675 | 697 | err = s_listen->ops->bind(s_listen, |
| @@ -856,16 +878,6 @@ retry: · 180 unmodified lines | ||
| 856 | 878 | sock->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK; |
| 857 | 879 | msock->sk->sk_priority = TC_PRIO_INTERACTIVE; |
| 858 | 880 | |
| 859 | − if (mdev->net_conf->sndbuf_size) { | |
| 860 | − sock->sk->sk_sndbuf = mdev->net_conf->sndbuf_size; | |
| 861 | − sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK; | |
| 862 | − } | |
| 863 | − | |
| 864 | − if (mdev->net_conf->rcvbuf_size) { | |
| 865 | − sock->sk->sk_rcvbuf = mdev->net_conf->rcvbuf_size; | |
| 866 | − sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK; | |
| 867 | − } | |
| 868 | − | |
| 869 | 881 | /* NOT YET ... |
| 870 | 882 | * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; |
| 871 | 883 | * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; |
| @@ -1154,17 +1166,6 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, · 282 unmodified lines | ||
| 1154 | 1166 | unsigned n_bios = 0; |
| 1155 | 1167 | unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; |
| 1156 | 1168 | |
| 1157 | − if (atomic_read(&mdev->new_c_uuid)) { | |
| 1158 | − if (atomic_add_unless(&mdev->new_c_uuid, -1, 1)) { | |
| 1159 | − drbd_uuid_new_current(mdev); | |
| 1160 | − drbd_md_sync(mdev); | |
| 1161 | − | |
| 1162 | − atomic_dec(&mdev->new_c_uuid); | |
| 1163 | − wake_up(&mdev->misc_wait); | |
| 1164 | − } | |
| 1165 | − wait_event(mdev->misc_wait, !atomic_read(&mdev->new_c_uuid)); | |
| 1166 | − } | |
| 1167 | − | |
| 1168 | 1169 | /* In most cases, we will only need one bio. But in case the lower |
| 1169 | 1170 | * level restrictions happen to be different at this offset on this |
| 1170 | 1171 | * side than those of the sending peer, we may need to submit the |
| @@ -102,32 +102,7 @@ static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const · 101 unmodified lines | ||
| 102 | 102 | } |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | − /* if it was a local io error, we want to notify our | |
| 106 | − * peer about that, and see if we need to | |
| 107 | − * detach the disk and stuff. | |
| 108 | − * to avoid allocating some special work | |
| 109 | − * struct, reuse the request. */ | |
| 110 | − | |
| 111 | − /* THINK | |
| 112 | − * why do we do this not when we detect the error, | |
| 113 | − * but delay it until it is "done", i.e. possibly | |
| 114 | − * until the next barrier ack? */ | |
| 115 | − | |
| 116 | − if (rw == WRITE && | |
| 117 | − ((s & RQ_LOCAL_MASK) && !(s & RQ_LOCAL_OK))) { | |
| 118 | − if (!(req->w.list.next == LIST_POISON1 || | |
| 119 | − list_empty(&req->w.list))) { | |
| 120 | − /* DEBUG ASSERT only; if this triggers, we | |
| 121 | − * probably corrupt the worker list here */ | |
| 122 | − dev_err(DEV, "req->w.list.next = %p\n", req->w.list.next); | |
| 123 | − dev_err(DEV, "req->w.list.prev = %p\n", req->w.list.prev); | |
| 124 | − } | |
| 125 | − req->w.cb = w_io_error; | |
| 126 | − drbd_queue_work(&mdev->data.work, &req->w); | |
| 127 | − /* drbd_req_free() is done in w_io_error */ | |
| 128 | − } else { | |
| 129 | − drbd_req_free(req); | |
| 130 | − } | |
| 105 | + drbd_req_free(req); | |
| 131 | 106 | } |
| 132 | 107 | |
| 133 | 108 | static void queue_barrier(struct drbd_conf *mdev) |
| @@ -453,9 +428,6 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what, · 319 unmodified lines | ||
| 453 | 428 | req->rq_state |= RQ_LOCAL_COMPLETED; |
| 454 | 429 | req->rq_state &= ~RQ_LOCAL_PENDING; |
| 455 | 430 | |
| 456 | − dev_alert(DEV, "Local WRITE failed sec=%llus size=%u\n", | |
| 457 | − (unsigned long long)req->sector, req->size); | |
| 458 | − /* and now: check how to handle local io error. */ | |
| 459 | 431 | __drbd_chk_io_error(mdev, FALSE); |
| 460 | 432 | _req_may_be_done(req, m); |
| 461 | 433 | put_ldev(mdev); |
| @@ -475,22 +447,21 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what, · 13 unmodified lines | ||
| 475 | 447 | req->rq_state |= RQ_LOCAL_COMPLETED; |
| 476 | 448 | req->rq_state &= ~RQ_LOCAL_PENDING; |
| 477 | 449 | |
| 478 | − dev_alert(DEV, "Local READ failed sec=%llus size=%u\n", | |
| 479 | − (unsigned long long)req->sector, req->size); | |
| 480 | − /* _req_mod(req,to_be_send); oops, recursion... */ | |
| 481 | 450 | D_ASSERT(!(req->rq_state & RQ_NET_MASK)); |
| 482 | − req->rq_state |= RQ_NET_PENDING; | |
| 483 | − inc_ap_pending(mdev); | |
| 484 | 451 | |
| 485 | 452 | __drbd_chk_io_error(mdev, FALSE); |
| 486 | 453 | put_ldev(mdev); |
| 487 | − /* NOTE: if we have no connection, | |
| 488 | − * or know the peer has no good data either, | |
| 489 | − * then we don't actually need to "queue_for_net_read", | |
| 490 | − * but we do so anyways, since the drbd_io_error() | |
| 491 | − * and the potential state change to "Diskless" | |
| 492 | − * needs to be done from process context */ | |
| 493 | 454 | |
| 455 | + /* no point in retrying if there is no good remote data, | |
| 456 | + * or we have no connection. */ | |
| 457 | + if (mdev->state.pdsk != D_UP_TO_DATE) { | |
| 458 | + _req_may_be_done(req, m); | |
| 459 | + break; | |
| 460 | + } | |
| 461 | + | |
| 462 | + /* _req_mod(req,to_be_send); oops, recursion... */ | |
| 463 | + req->rq_state |= RQ_NET_PENDING; | |
| 464 | + inc_ap_pending(mdev); | |
| 494 | 465 | /* fall through: _req_mod(req,queue_for_net_read); */ |
| 495 | 466 | |
| 496 | 467 | case queue_for_net_read: |
| @@ -600,6 +571,9 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what, · 103 unmodified lines | ||
| 600 | 571 | _req_may_be_done(req, m); |
| 601 | 572 | break; |
| 602 | 573 | |
| 574 | + case read_retry_remote_canceled: | |
| 575 | + req->rq_state &= ~RQ_NET_QUEUED; | |
| 576 | + /* fall through, in case we raced with drbd_disconnect */ | |
| 603 | 577 | case connection_lost_while_pending: |
| 604 | 578 | /* transfer log cleanup after connection loss */ |
| 605 | 579 | /* assert something? */ |
| @@ -91,6 +91,7 @@ enum drbd_req_event { · 90 unmodified lines | ||
| 91 | 91 | send_failed, |
| 92 | 92 | handed_over_to_network, |
| 93 | 93 | connection_lost_while_pending, |
| 94 | + read_retry_remote_canceled, | |
| 94 | 95 | recv_acked_by_peer, |
| 95 | 96 | write_acked_by_peer, |
| 96 | 97 | write_acked_by_peer_and_sis, /* and set_in_sync */ |
| @@ -224,9 +224,6 @@ void drbd_endio_pri(struct bio *bio, int error) · 223 unmodified lines | ||
| 224 | 224 | enum drbd_req_event what; |
| 225 | 225 | int uptodate = bio_flagged(bio, BIO_UPTODATE); |
| 226 | 226 | |
| 227 | − if (error) | |
| 228 | − dev_warn(DEV, "p %s: error=%d\n", | |
| 229 | − bio_data_dir(bio) == WRITE ? "write" : "read", error); | |
| 230 | 227 | if (!error && !uptodate) { |
| 231 | 228 | dev_warn(DEV, "p %s: setting error to -EIO\n", |
| 232 | 229 | bio_data_dir(bio) == WRITE ? "write" : "read"); |
| @@ -257,20 +254,6 @@ void drbd_endio_pri(struct bio *bio, int error) · 24 unmodified lines | ||
| 257 | 254 | complete_master_bio(mdev, &m); |
| 258 | 255 | } |
| 259 | 256 | |
| 260 | −int w_io_error(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | |
| 261 | −{ | |
| 262 | − struct drbd_request *req = container_of(w, struct drbd_request, w); | |
| 263 | − | |
| 264 | − /* NOTE: mdev->ldev can be NULL by the time we get here! */ | |
| 265 | − /* D_ASSERT(mdev->ldev->dc.on_io_error != EP_PASS_ON); */ | |
| 266 | − | |
| 267 | − /* the only way this callback is scheduled is from _req_may_be_done, | |
| 268 | − * when it is done and had a local write error, see comments there */ | |
| 269 | − drbd_req_free(req); | |
| 270 | − | |
| 271 | − return TRUE; | |
| 272 | −} | |
| 273 | − | |
| 274 | 257 | int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) |
| 275 | 258 | { |
| 276 | 259 | struct drbd_request *req = container_of(w, struct drbd_request, w); |
| @@ -280,12 +263,9 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) · 3 unmodified lines | ||
| 280 | 263 | * to give the disk the chance to relocate that block */ |
| 281 | 264 | |
| 282 | 265 | spin_lock_irq(&mdev->req_lock); |
| 283 | − if (cancel || | |
| 284 | − mdev->state.conn < C_CONNECTED || | |
| 285 | − mdev->state.pdsk <= D_INCONSISTENT) { | |
| 286 | − _req_mod(req, send_canceled); | |
| 266 | + if (cancel || mdev->state.pdsk != D_UP_TO_DATE) { | |
| 267 | + _req_mod(req, read_retry_remote_canceled); | |
| 287 | 268 | spin_unlock_irq(&mdev->req_lock); |
| 288 | − dev_alert(DEV, "WE ARE LOST. Local IO failure, no peer.\n"); | |
| 289 | 269 | return 1; |
| 290 | 270 | } |
| 291 | 271 | spin_unlock_irq(&mdev->req_lock); |
| @@ -1159,8 +1159,10 @@ static struct of_device_id swim3_match[] = · 1158 unmodified lines | ||
| 1159 | 1159 | |
| 1160 | 1160 | static struct macio_driver swim3_driver = |
| 1161 | 1161 | { |
| 1162 | − .name = "swim3", | |
| 1163 | − .match_table = swim3_match, | |
| 1162 | + .driver = { | |
| 1163 | + .name = "swim3", | |
| 1164 | + .of_match_table = swim3_match, | |
| 1165 | + }, | |
| 1164 | 1166 | .probe = swim3_attach, |
| 1165 | 1167 | #if 0 |
| 1166 | 1168 | .suspend = swim3_suspend, |
| @@ -298,7 +298,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) · 297 unmodified lines | ||
| 298 | 298 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, |
| 299 | 299 | offsetof(struct virtio_blk_config, seg_max), |
| 300 | 300 | &sg_elems); |
| 301 | − if (err) | |
| 301 | + | |
| 302 | + /* We need at least one SG element, whatever they say. */ | |
| 303 | + if (err || !sg_elems) | |
| 302 | 304 | sg_elems = 1; |
| 303 | 305 | |
| 304 | 306 | /* We need an extra sg elements at head and tail. */ |
| @@ -1123,6 +1123,7 @@ source "drivers/s390/char/Kconfig" · 1122 unmodified lines | ||
| 1123 | 1123 | |
| 1124 | 1124 | config RAMOOPS |
| 1125 | 1125 | tristate "Log panic/oops to a RAM buffer" |
| 1126 | + depends on HAS_IOMEM | |
| 1126 | 1127 | default n |
| 1127 | 1128 | help |
| 1128 | 1129 | This enables panic and oops messages to be logged to a circular |
| @@ -1059,7 +1059,7 @@ static void intel_i9xx_setup_flush(void) · 1058 unmodified lines | ||
| 1059 | 1059 | } |
| 1060 | 1060 | } |
| 1061 | 1061 | |
| 1062 | −static int intel_i915_configure(void) | |
| 1062 | +static int intel_i9xx_configure(void) | |
| 1063 | 1063 | { |
| 1064 | 1064 | struct aper_size_info_fixed *current_size; |
| 1065 | 1065 | u32 temp; |
| @@ -1207,6 +1207,38 @@ static int intel_i9xx_fetch_size(void) · 141 unmodified lines | ||
| 1207 | 1207 | return 0; |
| 1208 | 1208 | } |
| 1209 | 1209 | |
| 1210 | +static int intel_i915_get_gtt_size(void) | |
| 1211 | +{ | |
| 1212 | + int size; | |
| 1213 | + | |
| 1214 | + if (IS_G33) { | |
| 1215 | + u16 gmch_ctrl; | |
| 1216 | + | |
| 1217 | + /* G33's GTT size defined in gmch_ctrl */ | |
| 1218 | + pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | |
| 1219 | + switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { | |
| 1220 | + case G33_PGETBL_SIZE_1M: | |
| 1221 | + size = 1024; | |
| 1222 | + break; | |
| 1223 | + case G33_PGETBL_SIZE_2M: | |
| 1224 | + size = 2048; | |
| 1225 | + break; | |
| 1226 | + default: | |
| 1227 | + dev_info(&agp_bridge->dev->dev, | |
| 1228 | + "unknown page table size 0x%x, assuming 512KB\n", | |
| 1229 | + (gmch_ctrl & G33_PGETBL_SIZE_MASK)); | |
| 1230 | + size = 512; | |
| 1231 | + } | |
| 1232 | + } else { | |
| 1233 | + /* On previous hardware, the GTT size was just what was | |
| 1234 | + * required to map the aperture. | |
| 1235 | + */ | |
| 1236 | + size = agp_bridge->driver->fetch_size(); | |
| 1237 | + } | |
| 1238 | + | |
| 1239 | + return KB(size); | |
| 1240 | +} | |
| 1241 | + | |
| 1210 | 1242 | /* The intel i915 automatically initializes the agp aperture during POST. |
| 1211 | 1243 | * Use the memory already set aside for in the GTT. |
| 1212 | 1244 | */ |
| @@ -1216,7 +1248,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) · 3 unmodified lines | ||
| 1216 | 1248 | struct aper_size_info_fixed *size; |
| 1217 | 1249 | int num_entries; |
| 1218 | 1250 | u32 temp, temp2; |
| 1219 | − int gtt_map_size = 256 * 1024; | |
| 1251 | + int gtt_map_size; | |
| 1220 | 1252 | |
| 1221 | 1253 | size = agp_bridge->current_size; |
| 1222 | 1254 | page_order = size->page_order; |
| @@ -1226,8 +1258,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) · 3 unmodified lines | ||
| 1226 | 1258 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); |
| 1227 | 1259 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); |
| 1228 | 1260 | |
| 1229 | − if (IS_G33) | |
| 1230 | − gtt_map_size = 1024 * 1024; /* 1M on G33 */ | |
| 1261 | + gtt_map_size = intel_i915_get_gtt_size(); | |
| 1262 | + | |
| 1231 | 1263 | intel_private.gtt = ioremap(temp2, gtt_map_size); |
| 1232 | 1264 | if (!intel_private.gtt) |
| 1233 | 1265 | return -ENOMEM; |
| @@ -1422,7 +1454,7 @@ static const struct agp_bridge_driver intel_915_driver = { · 188 unmodified lines | ||
| 1422 | 1454 | .size_type = FIXED_APER_SIZE, |
| 1423 | 1455 | .num_aperture_sizes = 4, |
| 1424 | 1456 | .needs_scratch_page = true, |
| 1425 | − .configure = intel_i915_configure, | |
| 1457 | + .configure = intel_i9xx_configure, | |
| 1426 | 1458 | .fetch_size = intel_i9xx_fetch_size, |
| 1427 | 1459 | .cleanup = intel_i915_cleanup, |
| 1428 | 1460 | .mask_memory = intel_i810_mask_memory, |
| @@ -1455,7 +1487,7 @@ static const struct agp_bridge_driver intel_i965_driver = { · 26 unmodified lines | ||
| 1455 | 1487 | .size_type = FIXED_APER_SIZE, |
| 1456 | 1488 | .num_aperture_sizes = 4, |
| 1457 | 1489 | .needs_scratch_page = true, |
| 1458 | − .configure = intel_i915_configure, | |
| 1490 | + .configure = intel_i9xx_configure, | |
| 1459 | 1491 | .fetch_size = intel_i9xx_fetch_size, |
| 1460 | 1492 | .cleanup = intel_i915_cleanup, |
| 1461 | 1493 | .mask_memory = intel_i965_mask_memory, |
| @@ -1488,7 +1520,7 @@ static const struct agp_bridge_driver intel_g33_driver = { · 26 unmodified lines | ||
| 1488 | 1520 | .size_type = FIXED_APER_SIZE, |
| 1489 | 1521 | .num_aperture_sizes = 4, |
| 1490 | 1522 | .needs_scratch_page = true, |
| 1491 | − .configure = intel_i915_configure, | |
| 1523 | + .configure = intel_i9xx_configure, | |
| 1492 | 1524 | .fetch_size = intel_i9xx_fetch_size, |
| 1493 | 1525 | .cleanup = intel_i915_cleanup, |
| 1494 | 1526 | .mask_memory = intel_i965_mask_memory, |
| @@ -415,7 +415,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) · 414 unmodified lines | ||
| 415 | 415 | bridge->gatt_table_real = (u32 *) table; |
| 416 | 416 | /* Need to clear out any dirty data still sitting in caches */ |
| 417 | 417 | flush_dcache_range((unsigned long)table, |
| 418 | − (unsigned long)(table_end + PAGE_SIZE)); | |
| 418 | + (unsigned long)table_end + 1); | |
| 419 | 419 | bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG); |
| 420 | 420 | |
| 421 | 421 | if (bridge->gatt_table == NULL) |
| @@ -904,9 +904,7 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) · 903 unmodified lines | ||
| 904 | 904 | int len; |
| 905 | 905 | /* Priority ordering: We should do priority with RR of the groups */ |
| 906 | 906 | int i = 1; |
| 907 | − unsigned long flags; | |
| 908 | 907 | |
| 909 | − spin_lock_irqsave(&gsm->tx_lock, flags); | |
| 910 | 908 | while (i < NUM_DLCI) { |
| 911 | 909 | struct gsm_dlci *dlci; |
| 912 | 910 | |
| @@ -927,7 +925,6 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) · 14 unmodified lines | ||
| 927 | 925 | if (len == 0) |
| 928 | 926 | i++; |
| 929 | 927 | } |
| 930 | − spin_unlock_irqrestore(&gsm->tx_lock, flags); | |
| 931 | 928 | } |
| 932 | 929 | |
| 933 | 930 | /** |
| @@ -2230,12 +2227,16 @@ static int gsmld_open(struct tty_struct *tty) · 1296 unmodified lines | ||
| 2230 | 2227 | static void gsmld_write_wakeup(struct tty_struct *tty) |
| 2231 | 2228 | { |
| 2232 | 2229 | struct gsm_mux *gsm = tty->disc_data; |
| 2230 | + unsigned long flags; | |
| 2233 | 2231 | |
| 2234 | 2232 | /* Queue poll */ |
| 2235 | 2233 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
| 2236 | 2234 | gsm_data_kick(gsm); |
| 2237 | − if (gsm->tx_bytes < TX_THRESH_LO) | |
| 2235 | + if (gsm->tx_bytes < TX_THRESH_LO) { | |
| 2236 | + spin_lock_irqsave(&gsm->tx_lock, flags); | |
| 2238 | 2237 | gsm_dlci_data_sweep(gsm); |
| 2238 | + spin_unlock_irqrestore(&gsm->tx_lock, flags); | |
| 2239 | + } | |
| 2239 | 2240 | } |
| 2240 | 2241 | |
| 2241 | 2242 | /** |
| @@ -529,6 +529,10 @@ static bool will_write_block(struct port *port) · 528 unmodified lines | ||
| 529 | 529 | { |
| 530 | 530 | bool ret; |
| 531 | 531 | |
| 532 | + if (!port->guest_connected) { | |
| 533 | + /* Port got hot-unplugged. Let's exit. */ | |
| 534 | + return false; | |
| 535 | + } | |
| 532 | 536 | if (!port->host_connected) |
| 533 | 537 | return true; |
| 534 | 538 | |
| @@ -1099,6 +1103,13 @@ static int remove_port(struct port *port) · 564 unmodified lines | ||
| 1099 | 1103 | { |
| 1100 | 1104 | struct port_buffer *buf; |
| 1101 | 1105 | |
| 1106 | + if (port->guest_connected) { | |
| 1107 | + port->guest_connected = false; | |
| 1108 | + port->host_connected = false; | |
| 1109 | + wake_up_interruptible(&port->waitqueue); | |
| 1110 | + send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); | |
| 1111 | + } | |
| 1112 | + | |
| 1102 | 1113 | spin_lock_irq(&port->portdev->ports_lock); |
| 1103 | 1114 | list_del(&port->list); |
| 1104 | 1115 | spin_unlock_irq(&port->portdev->ports_lock); |
| @@ -1120,9 +1131,6 @@ static int remove_port(struct port *port) · 15 unmodified lines | ||
| 1120 | 1131 | hvc_remove(port->cons.hvc); |
| 1121 | 1132 | #endif |
| 1122 | 1133 | } |
| 1123 | − if (port->guest_connected) | |
| 1124 | − send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); | |
| 1125 | − | |
| 1126 | 1134 | sysfs_remove_group(&port->dev->kobj, &port_attribute_group); |
| 1127 | 1135 | device_destroy(pdrvdata.class, port->dev->devt); |
| 1128 | 1136 | cdev_del(&port->cdev); |
| @@ -1303,7 +1303,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, · 1302 unmodified lines | ||
| 1303 | 1303 | if (!perm) |
| 1304 | 1304 | goto eperm; |
| 1305 | 1305 | ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); |
| 1306 | − if (!ret) | |
| 1306 | + if (ret) | |
| 1307 | + ret = -EFAULT; | |
| 1308 | + else | |
| 1307 | 1309 | con_clear_unimap(vc, &ui); |
| 1308 | 1310 | break; |
| 1309 | 1311 | } |
| @@ -412,18 +412,10 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) · 411 unmodified lines | ||
| 412 | 412 | static int sh_cmt_clocksource_enable(struct clocksource *cs) |
| 413 | 413 | { |
| 414 | 414 | struct sh_cmt_priv *p = cs_to_sh_cmt(cs); |
| 415 | − int ret; | |
| 416 | 415 | |
| 417 | 416 | p->total_cycles = 0; |
| 418 | 417 | |
| 419 | − ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); | |
| 420 | − if (ret) | |
| 421 | − return ret; | |
| 422 | − | |
| 423 | − /* TODO: calculate good shift from rate and counter bit width */ | |
| 424 | − cs->shift = 0; | |
| 425 | − cs->mult = clocksource_hz2mult(p->rate, cs->shift); | |
| 426 | − return 0; | |
| 418 | + return sh_cmt_start(p, FLAG_CLOCKSOURCE); | |
| 427 | 419 | } |
| 428 | 420 | |
| 429 | 421 | static void sh_cmt_clocksource_disable(struct clocksource *cs) |
| @@ -450,8 +442,20 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, · 20 unmodified lines | ||
| 450 | 442 | cs->resume = sh_cmt_clocksource_resume; |
| 451 | 443 | cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); |
| 452 | 444 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; |
| 445 | + | |
| 446 | + /* clk_get_rate() needs an enabled clock */ | |
| 447 | + clk_enable(p->clk); | |
| 448 | + p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8; | |
| 449 | + clk_disable(p->clk); | |
| 450 | + | |
| 451 | + /* TODO: calculate good shift from rate and counter bit width */ | |
| 452 | + cs->shift = 10; | |
| 453 | + cs->mult = clocksource_hz2mult(p->rate, cs->shift); | |
| 454 | + | |
| 453 | 455 | dev_info(&p->pdev->dev, "used as clock source\n"); |
| 456 | + | |
| 454 | 457 | clocksource_register(cs); |
| 458 | + | |
| 455 | 459 | return 0; |
| 456 | 460 | } |
| 457 | 461 | |
| @@ -199,16 +199,8 @@ static cycle_t sh_tmu_clocksource_read(struct clocksource *cs) · 198 unmodified lines | ||
| 199 | 199 | static int sh_tmu_clocksource_enable(struct clocksource *cs) |
| 200 | 200 | { |
| 201 | 201 | struct sh_tmu_priv *p = cs_to_sh_tmu(cs); |
| 202 | − int ret; | |
| 203 | − | |
| 204 | − ret = sh_tmu_enable(p); | |
| 205 | − if (ret) | |
| 206 | − return ret; | |
| 207 | 202 | |
| 208 | − /* TODO: calculate good shift from rate and counter bit width */ | |
| 209 | − cs->shift = 10; | |
| 210 | − cs->mult = clocksource_hz2mult(p->rate, cs->shift); | |
| 211 | − return 0; | |
| 203 | + return sh_tmu_enable(p); | |
| 212 | 204 | } |
| 213 | 205 | |
| 214 | 206 | static void sh_tmu_clocksource_disable(struct clocksource *cs) |
| @@ -228,6 +220,16 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, · 13 unmodified lines | ||
| 228 | 220 | cs->disable = sh_tmu_clocksource_disable; |
| 229 | 221 | cs->mask = CLOCKSOURCE_MASK(32); |
| 230 | 222 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; |
| 223 | + | |
| 224 | + /* clk_get_rate() needs an enabled clock */ | |
| 225 | + clk_enable(p->clk); | |
| 226 | + /* channel will be configured at parent clock / 4 */ | |
| 227 | + p->rate = clk_get_rate(p->clk) / 4; | |
| 228 | + clk_disable(p->clk); | |
| 229 | + /* TODO: calculate good shift from rate and counter bit width */ | |
| 230 | + cs->shift = 10; | |
| 231 | + cs->mult = clocksource_hz2mult(p->rate, cs->shift); | |
| 232 | + | |
| 231 | 233 | dev_info(&p->pdev->dev, "used as clock source\n"); |
| 232 | 234 | clocksource_register(cs); |
| 233 | 235 | return 0; |
| @@ -1158,7 +1158,7 @@ static int __init crypto4xx_probe(struct of_device *ofdev, · 1157 unmodified lines | ||
| 1158 | 1158 | struct device *dev = &ofdev->dev; |
| 1159 | 1159 | struct crypto4xx_core_device *core_dev; |
| 1160 | 1160 | |
| 1161 | − rc = of_address_to_resource(ofdev->node, 0, &res); | |
| 1161 | + rc = of_address_to_resource(ofdev->dev.of_node, 0, &res); | |
| 1162 | 1162 | if (rc) |
| 1163 | 1163 | return -ENODEV; |
| 1164 | 1164 | |
| @@ -1215,13 +1215,13 @@ static int __init crypto4xx_probe(struct of_device *ofdev, · 50 unmodified lines | ||
| 1215 | 1215 | (unsigned long) dev); |
| 1216 | 1216 | |
| 1217 | 1217 | /* Register for Crypto isr, Crypto Engine IRQ */ |
| 1218 | − core_dev->irq = irq_of_parse_and_map(ofdev->node, 0); | |
| 1218 | + core_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); | |
| 1219 | 1219 | rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0, |
| 1220 | 1220 | core_dev->dev->name, dev); |
| 1221 | 1221 | if (rc) |
| 1222 | 1222 | goto err_request_irq; |
| 1223 | 1223 | |
| 1224 | − core_dev->dev->ce_base = of_iomap(ofdev->node, 0); | |
| 1224 | + core_dev->dev->ce_base = of_iomap(ofdev->dev.of_node, 0); | |
| 1225 | 1225 | if (!core_dev->dev->ce_base) { |
| 1226 | 1226 | dev_err(dev, "failed to of_iomap\n"); |
| 1227 | 1227 | goto err_iomap; |
| @@ -251,16 +251,10 @@ static void n2_base_ctx_init(struct n2_base_ctx *ctx) · 250 unmodified lines | ||
| 251 | 251 | struct n2_hash_ctx { |
| 252 | 252 | struct n2_base_ctx base; |
| 253 | 253 | |
| 254 | − struct crypto_ahash *fallback; | |
| 254 | + struct crypto_ahash *fallback_tfm; | |
| 255 | +}; | |
| 255 | 256 | |
| 256 | − /* These next three members must match the layout created by | |
| 257 | − * crypto_init_shash_ops_async. This allows us to properly | |
| 258 | − * plumb requests we can't do in hardware down to the fallback | |
| 259 | − * operation, providing all of the data structures and layouts | |
| 260 | − * expected by those paths. | |
| 261 | − */ | |
| 262 | − struct ahash_request fallback_req; | |
| 263 | − struct shash_desc fallback_desc; | |
| 257 | +struct n2_hash_req_ctx { | |
| 264 | 258 | union { |
| 265 | 259 | struct md5_state md5; |
| 266 | 260 | struct sha1_state sha1; |
| @@ -269,56 +263,62 @@ struct n2_hash_ctx { · 2 unmodified lines | ||
| 269 | 263 | |
| 270 | 264 | unsigned char hash_key[64]; |
| 271 | 265 | unsigned char keyed_zero_hash[32]; |
| 266 | + | |
| 267 | + struct ahash_request fallback_req; | |
| 272 | 268 | }; |
| 273 | 269 | |
| 274 | 270 | static int n2_hash_async_init(struct ahash_request *req) |
| 275 | 271 | { |
| 272 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 276 | 273 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 277 | 274 | struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); |
| 278 | 275 | |
| 279 | − ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); | |
| 280 | − ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 276 | + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); | |
| 277 | + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 281 | 278 | |
| 282 | − return crypto_ahash_init(&ctx->fallback_req); | |
| 279 | + return crypto_ahash_init(&rctx->fallback_req); | |
| 283 | 280 | } |
| 284 | 281 | |
| 285 | 282 | static int n2_hash_async_update(struct ahash_request *req) |
| 286 | 283 | { |
| 284 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 287 | 285 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 288 | 286 | struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); |
| 289 | 287 | |
| 290 | − ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); | |
| 291 | − ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 292 | − ctx->fallback_req.nbytes = req->nbytes; | |
| 293 | − ctx->fallback_req.src = req->src; | |
| 288 | + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); | |
| 289 | + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 290 | + rctx->fallback_req.nbytes = req->nbytes; | |
| 291 | + rctx->fallback_req.src = req->src; | |
| 294 | 292 | |
| 295 | − return crypto_ahash_update(&ctx->fallback_req); | |
| 293 | + return crypto_ahash_update(&rctx->fallback_req); | |
| 296 | 294 | } |
| 297 | 295 | |
| 298 | 296 | static int n2_hash_async_final(struct ahash_request *req) |
| 299 | 297 | { |
| 298 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 300 | 299 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 301 | 300 | struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); |
| 302 | 301 | |
| 303 | − ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); | |
| 304 | − ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 305 | − ctx->fallback_req.result = req->result; | |
| 302 | + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); | |
| 303 | + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 304 | + rctx->fallback_req.result = req->result; | |
| 306 | 305 | |
| 307 | − return crypto_ahash_final(&ctx->fallback_req); | |
| 306 | + return crypto_ahash_final(&rctx->fallback_req); | |
| 308 | 307 | } |
| 309 | 308 | |
| 310 | 309 | static int n2_hash_async_finup(struct ahash_request *req) |
| 311 | 310 | { |
| 311 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 312 | 312 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 313 | 313 | struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); |
| 314 | 314 | |
| 315 | − ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); | |
| 316 | − ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 317 | − ctx->fallback_req.nbytes = req->nbytes; | |
| 318 | − ctx->fallback_req.src = req->src; | |
| 319 | − ctx->fallback_req.result = req->result; | |
| 315 | + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); | |
| 316 | + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; | |
| 317 | + rctx->fallback_req.nbytes = req->nbytes; | |
| 318 | + rctx->fallback_req.src = req->src; | |
| 319 | + rctx->fallback_req.result = req->result; | |
| 320 | 320 | |
| 321 | − return crypto_ahash_finup(&ctx->fallback_req); | |
| 321 | + return crypto_ahash_finup(&rctx->fallback_req); | |
| 322 | 322 | } |
| 323 | 323 | |
| 324 | 324 | static int n2_hash_cra_init(struct crypto_tfm *tfm) |
| @@ -338,7 +338,10 @@ static int n2_hash_cra_init(struct crypto_tfm *tfm) · 13 unmodified lines | ||
| 338 | 338 | goto out; |
| 339 | 339 | } |
| 340 | 340 | |
| 341 | − ctx->fallback = fallback_tfm; | |
| 341 | + crypto_ahash_set_reqsize(ahash, (sizeof(struct n2_hash_req_ctx) + | |
| 342 | + crypto_ahash_reqsize(fallback_tfm))); | |
| 343 | + | |
| 344 | + ctx->fallback_tfm = fallback_tfm; | |
| 342 | 345 | return 0; |
| 343 | 346 | |
| 344 | 347 | out: |
| @@ -350,7 +353,7 @@ static void n2_hash_cra_exit(struct crypto_tfm *tfm) · 5 unmodified lines | ||
| 350 | 353 | struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); |
| 351 | 354 | struct n2_hash_ctx *ctx = crypto_ahash_ctx(ahash); |
| 352 | 355 | |
| 353 | − crypto_free_ahash(ctx->fallback); | |
| 356 | + crypto_free_ahash(ctx->fallback_tfm); | |
| 354 | 357 | } |
| 355 | 358 | |
| 356 | 359 | static unsigned long wait_for_tail(struct spu_queue *qp) |
| @@ -399,14 +402,16 @@ static int n2_hash_async_digest(struct ahash_request *req, · 42 unmodified lines | ||
| 399 | 402 | * exceed 2^16. |
| 400 | 403 | */ |
| 401 | 404 | if (unlikely(req->nbytes > (1 << 16))) { |
| 402 | − ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); | |
| 403 | − ctx->fallback_req.base.flags = | |
| 405 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 406 | + | |
| 407 | + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); | |
| 408 | + rctx->fallback_req.base.flags = | |
| 404 | 409 | req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; |
| 405 | − ctx->fallback_req.nbytes = req->nbytes; | |
| 406 | − ctx->fallback_req.src = req->src; | |
| 407 | − ctx->fallback_req.result = req->result; | |
| 410 | + rctx->fallback_req.nbytes = req->nbytes; | |
| 411 | + rctx->fallback_req.src = req->src; | |
| 412 | + rctx->fallback_req.result = req->result; | |
| 408 | 413 | |
| 409 | − return crypto_ahash_digest(&ctx->fallback_req); | |
| 414 | + return crypto_ahash_digest(&rctx->fallback_req); | |
| 410 | 415 | } |
| 411 | 416 | |
| 412 | 417 | n2_base_ctx_init(&ctx->base); |
| @@ -472,9 +477,8 @@ out: · 59 unmodified lines | ||
| 472 | 477 | |
| 473 | 478 | static int n2_md5_async_digest(struct ahash_request *req) |
| 474 | 479 | { |
| 475 | − struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | |
| 476 | − struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); | |
| 477 | − struct md5_state *m = &ctx->u.md5; | |
| 480 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 481 | + struct md5_state *m = &rctx->u.md5; | |
| 478 | 482 | |
| 479 | 483 | if (unlikely(req->nbytes == 0)) { |
| 480 | 484 | static const char md5_zero[MD5_DIGEST_SIZE] = { |
| @@ -497,9 +501,8 @@ static int n2_md5_async_digest(struct ahash_request *req) · 16 unmodified lines | ||
| 497 | 501 | |
| 498 | 502 | static int n2_sha1_async_digest(struct ahash_request *req) |
| 499 | 503 | { |
| 500 | − struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | |
| 501 | − struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); | |
| 502 | − struct sha1_state *s = &ctx->u.sha1; | |
| 504 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 505 | + struct sha1_state *s = &rctx->u.sha1; | |
| 503 | 506 | |
| 504 | 507 | if (unlikely(req->nbytes == 0)) { |
| 505 | 508 | static const char sha1_zero[SHA1_DIGEST_SIZE] = { |
| @@ -524,9 +527,8 @@ static int n2_sha1_async_digest(struct ahash_request *req) · 18 unmodified lines | ||
| 524 | 527 | |
| 525 | 528 | static int n2_sha256_async_digest(struct ahash_request *req) |
| 526 | 529 | { |
| 527 | − struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | |
| 528 | − struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); | |
| 529 | − struct sha256_state *s = &ctx->u.sha256; | |
| 530 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 531 | + struct sha256_state *s = &rctx->u.sha256; | |
| 530 | 532 | |
| 531 | 533 | if (req->nbytes == 0) { |
| 532 | 534 | static const char sha256_zero[SHA256_DIGEST_SIZE] = { |
| @@ -555,9 +557,8 @@ static int n2_sha256_async_digest(struct ahash_request *req) · 22 unmodified lines | ||
| 555 | 557 | |
| 556 | 558 | static int n2_sha224_async_digest(struct ahash_request *req) |
| 557 | 559 | { |
| 558 | − struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | |
| 559 | − struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); | |
| 560 | − struct sha256_state *s = &ctx->u.sha256; | |
| 560 | + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); | |
| 561 | + struct sha256_state *s = &rctx->u.sha256; | |
| 561 | 562 | |
| 562 | 563 | if (req->nbytes == 0) { |
| 563 | 564 | static const char sha224_zero[SHA224_DIGEST_SIZE] = { |
| @@ -1398,7 +1399,7 @@ static int find_devino_index(struct of_device *dev, struct spu_mdesc_info *ip, · 834 unmodified lines | ||
| 1398 | 1399 | |
| 1399 | 1400 | intr = ip->ino_table[i].intr; |
| 1400 | 1401 | |
| 1401 | − dev_intrs = of_get_property(dev->node, "interrupts", NULL); | |
| 1402 | + dev_intrs = of_get_property(dev->dev.of_node, "interrupts", NULL); | |
| 1402 | 1403 | if (!dev_intrs) |
| 1403 | 1404 | return -ENODEV; |
| 1404 | 1405 | |
| @@ -1449,7 +1450,7 @@ static int queue_cache_init(void) · 44 unmodified lines | ||
| 1449 | 1450 | { |
| 1450 | 1451 | if (!queue_cache[HV_NCS_QTYPE_MAU - 1]) |
| 1451 | 1452 | queue_cache[HV_NCS_QTYPE_MAU - 1] = |
| 1452 | − kmem_cache_create("cwq_queue", | |
| 1453 | + kmem_cache_create("mau_queue", | |
| 1453 | 1454 | (MAU_NUM_ENTRIES * |
| 1454 | 1455 | MAU_ENTRY_SIZE), |
| 1455 | 1456 | MAU_ENTRY_SIZE, 0, NULL); |
| @@ -1574,7 +1575,7 @@ static int spu_mdesc_walk_arcs(struct mdesc_handle *mdesc, · 118 unmodified lines | ||
| 1574 | 1575 | id = mdesc_get_property(mdesc, tgt, "id", NULL); |
| 1575 | 1576 | if (table[*id] != NULL) { |
| 1576 | 1577 | dev_err(&dev->dev, "%s: SPU cpu slot already set.\n", |
| 1577 | − dev->node->full_name); | |
| 1578 | + dev->dev.of_node->full_name); | |
| 1578 | 1579 | return -EINVAL; |
| 1579 | 1580 | } |
| 1580 | 1581 | cpu_set(*id, p->sharing); |
| @@ -1595,7 +1596,7 @@ static int handle_exec_unit(struct spu_mdesc_info *ip, struct list_head *list, · 14 unmodified lines | ||
| 1595 | 1596 | p = kzalloc(sizeof(struct spu_queue), GFP_KERNEL); |
| 1596 | 1597 | if (!p) { |
| 1597 | 1598 | dev_err(&dev->dev, "%s: Could not allocate SPU queue.\n", |
| 1598 | − dev->node->full_name); | |
| 1599 | + dev->dev.of_node->full_name); | |
| 1599 | 1600 | return -ENOMEM; |
| 1600 | 1601 | } |
| 1601 | 1602 | |
| @@ -1684,7 +1685,7 @@ static int __devinit grab_mdesc_irq_props(struct mdesc_handle *mdesc, · 82 unmodified lines | ||
| 1684 | 1685 | const unsigned int *reg; |
| 1685 | 1686 | u64 node; |
| 1686 | 1687 | |
| 1687 | − reg = of_get_property(dev->node, "reg", NULL); | |
| 1688 | + reg = of_get_property(dev->dev.of_node, "reg", NULL); | |
| 1688 | 1689 | if (!reg) |
| 1689 | 1690 | return -ENODEV; |
| 1690 | 1691 | |
| @@ -1836,7 +1837,7 @@ static int __devinit n2_crypto_probe(struct of_device *dev, · 145 unmodified lines | ||
| 1836 | 1837 | |
| 1837 | 1838 | n2_spu_driver_version(); |
| 1838 | 1839 | |
| 1839 | − full_name = dev->node->full_name; | |
| 1840 | + full_name = dev->dev.of_node->full_name; | |
| 1840 | 1841 | pr_info("Found N2CP at %s\n", full_name); |
| 1841 | 1842 | |
| 1842 | 1843 | np = alloc_n2cp(); |
| @@ -1948,7 +1949,7 @@ static int __devinit n2_mau_probe(struct of_device *dev, · 105 unmodified lines | ||
| 1948 | 1949 | |
| 1949 | 1950 | n2_spu_driver_version(); |
| 1950 | 1951 | |
| 1951 | − full_name = dev->node->full_name; | |
| 1952 | + full_name = dev->dev.of_node->full_name; | |
| 1952 | 1953 | pr_info("Found NCP at %s\n", full_name); |
| 1953 | 1954 | |
| 1954 | 1955 | mp = alloc_ncp(); |
| @@ -2034,8 +2035,11 @@ static struct of_device_id n2_crypto_match[] = { · 79 unmodified lines | ||
| 2034 | 2035 | MODULE_DEVICE_TABLE(of, n2_crypto_match); |
| 2035 | 2036 | |
| 2036 | 2037 | static struct of_platform_driver n2_crypto_driver = { |
| 2037 | − .name = "n2cp", | |
| 2038 | − .match_table = n2_crypto_match, | |
| 2038 | + .driver = { | |
| 2039 | + .name = "n2cp", | |
| 2040 | + .owner = THIS_MODULE, | |
| 2041 | + .of_match_table = n2_crypto_match, | |
| 2042 | + }, | |
| 2039 | 2043 | .probe = n2_crypto_probe, |
| 2040 | 2044 | .remove = __devexit_p(n2_crypto_remove), |
| 2041 | 2045 | }; |
| @@ -2055,8 +2059,11 @@ static struct of_device_id n2_mau_match[] = { · 13 unmodified lines | ||
| 2055 | 2059 | MODULE_DEVICE_TABLE(of, n2_mau_match); |
| 2056 | 2060 | |
| 2057 | 2061 | static struct of_platform_driver n2_mau_driver = { |
| 2058 | − .name = "ncp", | |
| 2059 | − .match_table = n2_mau_match, | |
| 2062 | + .driver = { | |
| 2063 | + .name = "ncp", | |
| 2064 | + .owner = THIS_MODULE, | |
| 2065 | + .of_match_table = n2_mau_match, | |
| 2066 | + }, | |
| 2060 | 2067 | .probe = n2_mau_probe, |
| 2061 | 2068 | .remove = __devexit_p(n2_mau_remove), |
| 2062 | 2069 | }; |
| @@ -630,7 +630,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, · 629 unmodified lines | ||
| 630 | 630 | static int __devinit mpc_dma_probe(struct of_device *op, |
| 631 | 631 | const struct of_device_id *match) |
| 632 | 632 | { |
| 633 | − struct device_node *dn = op->node; | |
| 633 | + struct device_node *dn = op->dev.of_node; | |
| 634 | 634 | struct device *dev = &op->dev; |
| 635 | 635 | struct dma_device *dma; |
| 636 | 636 | struct mpc_dma *mdma; |
| @@ -771,12 +771,12 @@ static struct of_device_id mpc_dma_match[] = { · 134 unmodified lines | ||
| 771 | 771 | }; |
| 772 | 772 | |
| 773 | 773 | static struct of_platform_driver mpc_dma_driver = { |
| 774 | − .match_table = mpc_dma_match, | |
| 775 | 774 | .probe = mpc_dma_probe, |
| 776 | 775 | .remove = __devexit_p(mpc_dma_remove), |
| 777 | − .driver = { | |
| 778 | − .name = DRV_NAME, | |
| 779 | − .owner = THIS_MODULE, | |
| 776 | + .driver = { | |
| 777 | + .name = DRV_NAME, | |
| 778 | + .owner = THIS_MODULE, | |
| 779 | + .of_match_table = mpc_dma_match, | |
| 780 | 780 | }, |
| 781 | 781 | }; |
| 782 | 782 | |
| @@ -4394,7 +4394,7 @@ static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev, · 4393 unmodified lines | ||
| 4394 | 4394 | static int __devinit ppc440spe_adma_probe(struct of_device *ofdev, |
| 4395 | 4395 | const struct of_device_id *match) |
| 4396 | 4396 | { |
| 4397 | − struct device_node *np = ofdev->node; | |
| 4397 | + struct device_node *np = ofdev->dev.of_node; | |
| 4398 | 4398 | struct resource res; |
| 4399 | 4399 | struct ppc440spe_adma_device *adev; |
| 4400 | 4400 | struct ppc440spe_adma_chan *chan; |
| @@ -4626,7 +4626,7 @@ out: · 225 unmodified lines | ||
| 4626 | 4626 | static int __devexit ppc440spe_adma_remove(struct of_device *ofdev) |
| 4627 | 4627 | { |
| 4628 | 4628 | struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev); |
| 4629 | − struct device_node *np = ofdev->node; | |
| 4629 | + struct device_node *np = ofdev->dev.of_node; | |
| 4630 | 4630 | struct resource res; |
| 4631 | 4631 | struct dma_chan *chan, *_chan; |
| 4632 | 4632 | struct ppc_dma_chan_ref *ref, *_ref; |
| @@ -69,6 +69,9 @@ config EDAC_MM_EDAC · 68 unmodified lines | ||
| 69 | 69 | occurred so that a particular failing memory module can be |
| 70 | 70 | replaced. If unsure, select 'Y'. |
| 71 | 71 | |
| 72 | +config EDAC_MCE | |
| 73 | + bool | |
| 74 | + | |
| 72 | 75 | config EDAC_AMD64 |
| 73 | 76 | tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h" |
| 74 | 77 | depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE |
| @@ -166,6 +169,16 @@ config EDAC_I5400 · 91 unmodified lines | ||
| 166 | 169 | Support for error detection and correction the Intel |
| 167 | 170 | i5400 MCH chipset (Seaburg). |
| 168 | 171 | |
| 172 | +config EDAC_I7CORE | |
| 173 | + tristate "Intel i7 Core (Nehalem) processors" | |
| 174 | + depends on EDAC_MM_EDAC && PCI && X86 | |
| 175 | + select EDAC_MCE | |
| 176 | + help | |
| 177 | + Support for error detection and correction the Intel | |
| 178 | + i7 Core (Nehalem) Integrated Memory Controller that exists on | |
| 179 | + newer processors like i7 Core, i7 Core Extreme, Xeon 35xx | |
| 180 | + and Xeon 55xx processors. | |
| 181 | + | |
| 169 | 182 | config EDAC_I82860 |
| 170 | 183 | tristate "Intel 82860" |
| 171 | 184 | depends on EDAC_MM_EDAC && PCI && X86_32 |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | obj-$(CONFIG_EDAC) := edac_stub.o |
| 10 | 10 | obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o |
| 11 | +obj-$(CONFIG_EDAC_MCE) += edac_mce.o | |
| 11 | 12 | |
| 12 | 13 | edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o |
| 13 | 14 | edac_core-objs += edac_module.o edac_device_sysfs.o |
| @@ -23,6 +24,7 @@ obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o · 9 unmodified lines | ||
| 23 | 24 | obj-$(CONFIG_EDAC_I5000) += i5000_edac.o |
| 24 | 25 | obj-$(CONFIG_EDAC_I5100) += i5100_edac.o |
| 25 | 26 | obj-$(CONFIG_EDAC_I5400) += i5400_edac.o |
| 27 | +obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o | |
| 26 | 28 | obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o |
| 27 | 29 | obj-$(CONFIG_EDAC_E752X) += e752x_edac.o |
| 28 | 30 | obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o |
| @@ -341,12 +341,30 @@ struct csrow_info { · 340 unmodified lines | ||
| 341 | 341 | struct channel_info *channels; |
| 342 | 342 | }; |
| 343 | 343 | |
| 344 | +struct mcidev_sysfs_group { | |
| 345 | + const char *name; /* group name */ | |
| 346 | + struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */ | |
| 347 | +}; | |
| 348 | + | |
| 349 | +struct mcidev_sysfs_group_kobj { | |
| 350 | + struct list_head list; /* list for all instances within a mc */ | |
| 351 | + | |
| 352 | + struct kobject kobj; /* kobj for the group */ | |
| 353 | + | |
| 354 | + struct mcidev_sysfs_group *grp; /* group description table */ | |
| 355 | + struct mem_ctl_info *mci; /* the parent */ | |
| 356 | +}; | |
| 357 | + | |
| 344 | 358 | /* mcidev_sysfs_attribute structure |
| 345 | 359 | * used for driver sysfs attributes and in mem_ctl_info |
| 346 | 360 | * sysfs top level entries |
| 347 | 361 | */ |
| 348 | 362 | struct mcidev_sysfs_attribute { |
| 349 | − struct attribute attr; | |
| 363 | + /* It should use either attr or grp */ | |
| 364 | + struct attribute attr; | |
| 365 | + struct mcidev_sysfs_group *grp; /* Points to a group of attributes */ | |
| 366 | + | |
| 367 | + /* Ops for show/store values at the attribute - not used on group */ | |
| 350 | 368 | ssize_t (*show)(struct mem_ctl_info *,char *); |
| 351 | 369 | ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); |
| 352 | 370 | }; |
| @@ -424,6 +442,9 @@ struct mem_ctl_info { · 71 unmodified lines | ||
| 424 | 442 | /* edac sysfs device control */ |
| 425 | 443 | struct kobject edac_mci_kobj; |
| 426 | 444 | |
| 445 | + /* list for all grp instances within a mc */ | |
| 446 | + struct list_head grp_kobj_list; | |
| 447 | + | |
| 427 | 448 | /* Additional top controller level attributes, but specified |
| 428 | 449 | * by the low level driver. |
| 429 | 450 | * |
| @@ -557,6 +557,8 @@ static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr, · 556 unmodified lines | ||
| 557 | 557 | struct mem_ctl_info *mem_ctl_info = to_mci(kobj); |
| 558 | 558 | struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); |
| 559 | 559 | |
| 560 | + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); | |
| 561 | + | |
| 560 | 562 | if (mcidev_attr->show) |
| 561 | 563 | return mcidev_attr->show(mem_ctl_info, buffer); |
| 562 | 564 | |
| @@ -569,6 +571,8 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr, · 6 unmodified lines | ||
| 569 | 571 | struct mem_ctl_info *mem_ctl_info = to_mci(kobj); |
| 570 | 572 | struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); |
| 571 | 573 | |
| 574 | + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); | |
| 575 | + | |
| 572 | 576 | if (mcidev_attr->store) |
| 573 | 577 | return mcidev_attr->store(mem_ctl_info, buffer, count); |
| 574 | 578 | |
| @@ -726,28 +730,118 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) · 151 unmodified lines | ||
| 726 | 730 | |
| 727 | 731 | #define EDAC_DEVICE_SYMLINK "device" |
| 728 | 732 | |
| 733 | +#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group_kobj, kobj)->mci) | |
| 734 | + | |
| 735 | +/* MCI show/store functions for top most object */ | |
| 736 | +static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr, | |
| 737 | + char *buffer) | |
| 738 | +{ | |
| 739 | + struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj); | |
| 740 | + struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); | |
| 741 | + | |
| 742 | + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); | |
| 743 | + | |
| 744 | + if (mcidev_attr->show) | |
| 745 | + return mcidev_attr->show(mem_ctl_info, buffer); | |
| 746 | + | |
| 747 | + return -EIO; | |
| 748 | +} | |
| 749 | + | |
| 750 | +static ssize_t inst_grp_store(struct kobject *kobj, struct attribute *attr, | |
| 751 | + const char *buffer, size_t count) | |
| 752 | +{ | |
| 753 | + struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj); | |
| 754 | + struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); | |
| 755 | + | |
| 756 | + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); | |
| 757 | + | |
| 758 | + if (mcidev_attr->store) | |
| 759 | + return mcidev_attr->store(mem_ctl_info, buffer, count); | |
| 760 | + | |
| 761 | + return -EIO; | |
| 762 | +} | |
| 763 | + | |
| 764 | +/* No memory to release for this kobj */ | |
| 765 | +static void edac_inst_grp_release(struct kobject *kobj) | |
| 766 | +{ | |
| 767 | + struct mcidev_sysfs_group_kobj *grp; | |
| 768 | + struct mem_ctl_info *mci; | |
| 769 | + | |
| 770 | + debugf1("%s()\n", __func__); | |
| 771 | + | |
| 772 | + grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj); | |
| 773 | + mci = grp->mci; | |
| 774 | + | |
| 775 | + kobject_put(&mci->edac_mci_kobj); | |
| 776 | +} | |
| 777 | + | |
| 778 | +/* Intermediate show/store table */ | |
| 779 | +static struct sysfs_ops inst_grp_ops = { | |
| 780 | + .show = inst_grp_show, | |
| 781 | + .store = inst_grp_store | |
| 782 | +}; | |
| 783 | + | |
| 784 | +/* the kobj_type instance for a instance group */ | |
| 785 | +static struct kobj_type ktype_inst_grp = { | |
| 786 | + .release = edac_inst_grp_release, | |
| 787 | + .sysfs_ops = &inst_grp_ops, | |
| 788 | +}; | |
| 789 | + | |
| 790 | + | |
| 729 | 791 | /* |
| 730 | 792 | * edac_create_mci_instance_attributes |
| 731 | − * create MC driver specific attributes at the topmost level | |
| 732 | − * directory of this mci instance. | |
| 793 | + * create MC driver specific attributes bellow an specified kobj | |
| 794 | + * This routine calls itself recursively, in order to create an entire | |
| 795 | + * object tree. | |
| 733 | 796 | */ |
| 734 | −static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci) | |
| 797 | +static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |
| 798 | + struct mcidev_sysfs_attribute *sysfs_attrib, | |
| 799 | + struct kobject *kobj) | |
| 735 | 800 | { |
| 736 | 801 | int err; |
| 737 | − struct mcidev_sysfs_attribute *sysfs_attrib; | |
| 738 | 802 | |
| 739 | − /* point to the start of the array and iterate over it | |
| 740 | − * adding each attribute listed to this mci instance's kobject | |
| 741 | − */ | |
| 742 | − sysfs_attrib = mci->mc_driver_sysfs_attributes; | |
| 803 | + debugf1("%s()\n", __func__); | |
| 804 | + | |
| 805 | + while (sysfs_attrib) { | |
| 806 | + if (sysfs_attrib->grp) { | |
| 807 | + struct mcidev_sysfs_group_kobj *grp_kobj; | |
| 808 | + | |
| 809 | + grp_kobj = kzalloc(sizeof(*grp_kobj), GFP_KERNEL); | |
| 810 | + if (!grp_kobj) | |
| 811 | + return -ENOMEM; | |
| 812 | + | |
| 813 | + list_add_tail(&grp_kobj->list, &mci->grp_kobj_list); | |
| 814 | + | |
| 815 | + grp_kobj->grp = sysfs_attrib->grp; | |
| 816 | + grp_kobj->mci = mci; | |
| 817 | + | |
| 818 | + debugf0("%s() grp %s, mci %p\n", __func__, | |
| 819 | + sysfs_attrib->grp->name, mci); | |
| 820 | + | |
| 821 | + err = kobject_init_and_add(&grp_kobj->kobj, | |
| 822 | + &ktype_inst_grp, | |
| 823 | + &mci->edac_mci_kobj, | |
| 824 | + sysfs_attrib->grp->name); | |
| 825 | + if (err) | |
| 826 | + return err; | |
| 827 | + | |
| 828 | + err = edac_create_mci_instance_attributes(mci, | |
| 829 | + grp_kobj->grp->mcidev_attr, | |
| 830 | + &grp_kobj->kobj); | |
| 831 | + | |
| 832 | + if (err) | |
| 833 | + return err; | |
| 834 | + } else if (sysfs_attrib->attr.name) { | |
| 835 | + debugf0("%s() file %s\n", __func__, | |
| 836 | + sysfs_attrib->attr.name); | |
| 837 | + | |
| 838 | + err = sysfs_create_file(kobj, &sysfs_attrib->attr); | |
| 839 | + } else | |
| 840 | + break; | |
| 743 | 841 | |
| 744 | − while (sysfs_attrib && sysfs_attrib->attr.name) { | |
| 745 | − err = sysfs_create_file(&mci->edac_mci_kobj, | |
| 746 | − (struct attribute*) sysfs_attrib); | |
| 747 | 842 | if (err) { |
| 748 | 843 | return err; |
| 749 | 844 | } |
| 750 | − | |
| 751 | 845 | sysfs_attrib++; |
| 752 | 846 | } |
| 753 | 847 | |
| @@ -759,21 +853,44 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci) · 5 unmodified lines | ||
| 759 | 853 | * remove MC driver specific attributes at the topmost level |
| 760 | 854 | * directory of this mci instance. |
| 761 | 855 | */ |
| 762 | −static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci) | |
| 856 | +static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, | |
| 857 | + struct mcidev_sysfs_attribute *sysfs_attrib, | |
| 858 | + struct kobject *kobj, int count) | |
| 763 | 859 | { |
| 764 | − struct mcidev_sysfs_attribute *sysfs_attrib; | |
| 860 | + struct mcidev_sysfs_group_kobj *grp_kobj, *tmp; | |
| 765 | 861 | |
| 766 | − /* point to the start of the array and iterate over it | |
| 767 | − * adding each attribute listed to this mci instance's kobject | |
| 768 | − */ | |
| 769 | − sysfs_attrib = mci->mc_driver_sysfs_attributes; | |
| 862 | + debugf1("%s()\n", __func__); | |
| 770 | 863 | |
| 771 | − /* loop if there are attributes and until we hit a NULL entry */ | |
| 772 | − while (sysfs_attrib && sysfs_attrib->attr.name) { | |
| 773 | − sysfs_remove_file(&mci->edac_mci_kobj, | |
| 774 | − (struct attribute *) sysfs_attrib); | |
| 864 | + /* | |
| 865 | + * loop if there are attributes and until we hit a NULL entry | |
| 866 | + * Remove first all the atributes | |
| 867 | + */ | |
| 868 | + while (sysfs_attrib) { | |
| 869 | + if (sysfs_attrib->grp) { | |
| 870 | + list_for_each_entry(grp_kobj, &mci->grp_kobj_list, | |
| 871 | + list) | |
| 872 | + if (grp_kobj->grp == sysfs_attrib->grp) | |
| 873 | + edac_remove_mci_instance_attributes(mci, | |
| 874 | + grp_kobj->grp->mcidev_attr, | |
| 875 | + &grp_kobj->kobj, count + 1); | |
| 876 | + } else if (sysfs_attrib->attr.name) { | |
| 877 | + debugf0("%s() file %s\n", __func__, | |
| 878 | + sysfs_attrib->attr.name); | |
| 879 | + sysfs_remove_file(kobj, &sysfs_attrib->attr); | |
| 880 | + } else | |
| 881 | + break; | |
| 775 | 882 | sysfs_attrib++; |
| 776 | 883 | } |
| 884 | + | |
| 885 | + /* | |
| 886 | + * Now that all attributes got removed, it is save to remove all groups | |
| 887 | + */ | |
| 888 | + if (!count) | |
| 889 | + list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list, | |
| 890 | + list) { | |
| 891 | + debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name); | |
| 892 | + kobject_put(&grp_kobj->kobj); | |
| 893 | + } | |
| 777 | 894 | } |
| 778 | 895 | |
| 779 | 896 | |
| @@ -794,6 +911,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) · 14 unmodified lines | ||
| 794 | 911 | |
| 795 | 912 | debugf0("%s() idx=%d\n", __func__, mci->mc_idx); |
| 796 | 913 | |
| 914 | + INIT_LIST_HEAD(&mci->grp_kobj_list); | |
| 915 | + | |
| 797 | 916 | /* create a symlink for the device */ |
| 798 | 917 | err = sysfs_create_link(kobj_mci, &mci->dev->kobj, |
| 799 | 918 | EDAC_DEVICE_SYMLINK); |
| @@ -806,7 +925,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) · 6 unmodified lines | ||
| 806 | 925 | * then create them now for the driver. |
| 807 | 926 | */ |
| 808 | 927 | if (mci->mc_driver_sysfs_attributes) { |
| 809 | − err = edac_create_mci_instance_attributes(mci); | |
| 928 | + err = edac_create_mci_instance_attributes(mci, | |
| 929 | + mci->mc_driver_sysfs_attributes, | |
| 930 | + &mci->edac_mci_kobj); | |
| 810 | 931 | if (err) { |
| 811 | 932 | debugf1("%s() failure to create mci attributes\n", |
| 812 | 933 | __func__); |
| @@ -841,7 +962,8 @@ fail1: · 28 unmodified lines | ||
| 841 | 962 | } |
| 842 | 963 | |
| 843 | 964 | /* remove the mci instance's attributes, if any */ |
| 844 | − edac_remove_mci_instance_attributes(mci); | |
| 965 | + edac_remove_mci_instance_attributes(mci, | |
| 966 | + mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj, 0); | |
| 845 | 967 | |
| 846 | 968 | /* remove the symlink */ |
| 847 | 969 | sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); |
| @@ -875,8 +997,9 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) · 27 unmodified lines | ||
| 875 | 997 | debugf0("%s() remove_mci_instance\n", __func__); |
| 876 | 998 | |
| 877 | 999 | /* remove this mci instance's attribtes */ |
| 878 | − edac_remove_mci_instance_attributes(mci); | |
| 879 | − | |
| 1000 | + edac_remove_mci_instance_attributes(mci, | |
| 1001 | + mci->mc_driver_sysfs_attributes, | |
| 1002 | + &mci->edac_mci_kobj, 0); | |
| 880 | 1003 | debugf0("%s() unregister this mci kobj\n", __func__); |
| 881 | 1004 | |
| 882 | 1005 | /* unregister this instance's kobject */ |
| @@ -0,0 +1,61 @@ | ||
| 1 | +/* Provides edac interface to mcelog events | |
| 2 | + * | |
| 3 | + * This file may be distributed under the terms of the | |
| 4 | + * GNU General Public License version 2. | |
| 5 | + * | |
| 6 | + * Copyright (c) 2009 by: | |
| 7 | + * Mauro Carvalho Chehab <mchehab@redhat.com> | |
| 8 | + * | |
| 9 | + * Red Hat Inc. http://www.redhat.com | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <linux/module.h> | |
| 13 | +#include <linux/edac_mce.h> | |
| 14 | +#include <asm/mce.h> | |
| 15 | + | |
| 16 | +int edac_mce_enabled; | |
| 17 | +EXPORT_SYMBOL_GPL(edac_mce_enabled); | |
| 18 | + | |
| 19 | + | |
| 20 | +/* | |
| 21 | + * Extension interface | |
| 22 | + */ | |
| 23 | + | |
| 24 | +static LIST_HEAD(edac_mce_list); | |
| 25 | +static DEFINE_MUTEX(edac_mce_lock); | |
| 26 | + | |
| 27 | +int edac_mce_register(struct edac_mce *edac_mce) | |
| 28 | +{ | |
| 29 | + mutex_lock(&edac_mce_lock); | |
| 30 | + list_add_tail(&edac_mce->list, &edac_mce_list); | |
| 31 | + mutex_unlock(&edac_mce_lock); | |
| 32 | + return 0; | |
| 33 | +} | |
| 34 | +EXPORT_SYMBOL(edac_mce_register); | |
| 35 | + | |
| 36 | +void edac_mce_unregister(struct edac_mce *edac_mce) | |
| 37 | +{ | |
| 38 | + mutex_lock(&edac_mce_lock); | |
| 39 | + list_del(&edac_mce->list); | |
| 40 | + mutex_unlock(&edac_mce_lock); | |
| 41 | +} | |
| 42 | +EXPORT_SYMBOL(edac_mce_unregister); | |
| 43 | + | |
| 44 | +int edac_mce_parse(struct mce *mce) | |
| 45 | +{ | |
| 46 | + struct edac_mce *edac_mce; | |
| 47 | + | |
| 48 | + list_for_each_entry(edac_mce, &edac_mce_list, list) { | |
| 49 | + if (edac_mce->check_error(edac_mce->priv, mce)) | |
| 50 | + return 1; | |
| 51 | + } | |
| 52 | + | |
| 53 | + /* Nobody queued the error */ | |
| 54 | + return 0; | |
| 55 | +} | |
| 56 | +EXPORT_SYMBOL_GPL(edac_mce_parse); | |
| 57 | + | |
| 58 | +MODULE_LICENSE("GPL"); | |
| 59 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | |
| 60 | +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); | |
| 61 | +MODULE_DESCRIPTION("EDAC Driver for mcelog captured errors"); | |
| @@ -0,0 +1,2078 @@ | ||
| 1 | +/* Intel i7 core/Nehalem Memory Controller kernel module | |
| 2 | + * | |
| 3 | + * This driver supports yhe memory controllers found on the Intel | |
| 4 | + * processor families i7core, i7core 7xx/8xx, i5core, Xeon 35xx, | |
| 5 | + * Xeon 55xx and Xeon 56xx also known as Nehalem, Nehalem-EP, Lynnfield | |
| 6 | + * and Westmere-EP. | |
| 7 | + * | |
| 8 | + * This file may be distributed under the terms of the | |
| 9 | + * GNU General Public License version 2 only. | |
| 10 | + * | |
| 11 | + * Copyright (c) 2009-2010 by: | |
| 12 | + * Mauro Carvalho Chehab <mchehab@redhat.com> | |
| 13 | + * | |
| 14 | + * Red Hat Inc. http://www.redhat.com | |
| 15 | + * | |
| 16 | + * Forked and adapted from the i5400_edac driver | |
| 17 | + * | |
| 18 | + * Based on the following public Intel datasheets: | |
| 19 | + * Intel Core i7 Processor Extreme Edition and Intel Core i7 Processor | |
| 20 | + * Datasheet, Volume 2: | |
| 21 | + * http://download.intel.com/design/processor/datashts/320835.pdf | |
| 22 | + * Intel Xeon Processor 5500 Series Datasheet Volume 2 | |
| 23 | + * http://www.intel.com/Assets/PDF/datasheet/321322.pdf | |
| 24 | + * also available at: | |
| 25 | + * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf | |
| 26 | + */ | |
| 27 | + | |
| 28 | +#include <linux/module.h> | |
| 29 | +#include <linux/init.h> | |
| 30 | +#include <linux/pci.h> | |
| 31 | +#include <linux/pci_ids.h> | |
| 32 | +#include <linux/slab.h> | |
| 33 | +#include <linux/delay.h> | |
| 34 | +#include <linux/edac.h> | |
| 35 | +#include <linux/mmzone.h> | |
| 36 | +#include <linux/edac_mce.h> | |
| 37 | +#include <linux/smp.h> | |
| 38 | +#include <asm/processor.h> | |
| 39 | + | |
| 40 | +#include "edac_core.h" | |
| 41 | + | |
| 42 | +/* | |
| 43 | + * This is used for Nehalem-EP and Nehalem-EX devices, where the non-core | |
| 44 | + * registers start at bus 255, and are not reported by BIOS. | |
| 45 | + * We currently find devices with only 2 sockets. In order to support more QPI | |
| 46 | + * Quick Path Interconnect, just increment this number. | |
| 47 | + */ | |
| 48 | +#define MAX_SOCKET_BUSES 2 | |
| 49 | + | |
| 50 | + | |
| 51 | +/* | |
| 52 | + * Alter this version for the module when modifications are made | |
| 53 | + */ | |
| 54 | +#define I7CORE_REVISION " Ver: 1.0.0 " __DATE__ | |
| 55 | +#define EDAC_MOD_STR "i7core_edac" | |
| 56 | + | |
| 57 | +/* | |
| 58 | + * Debug macros | |
| 59 | + */ | |
| 60 | +#define i7core_printk(level, fmt, arg...) \ | |
| 61 | + edac_printk(level, "i7core", fmt, ##arg) | |
| 62 | + | |
| 63 | +#define i7core_mc_printk(mci, level, fmt, arg...) \ | |
| 64 | + edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg) | |
| 65 | + | |
| 66 | +/* | |
| 67 | + * i7core Memory Controller Registers | |
| 68 | + */ | |
| 69 | + | |
| 70 | + /* OFFSETS for Device 0 Function 0 */ | |
| 71 | + | |
| 72 | +#define MC_CFG_CONTROL 0x90 | |
| 73 | + | |
| 74 | + /* OFFSETS for Device 3 Function 0 */ | |
| 75 | + | |
| 76 | +#define MC_CONTROL 0x48 | |
| 77 | +#define MC_STATUS 0x4c | |
| 78 | +#define MC_MAX_DOD 0x64 | |
| 79 | + | |
| 80 | +/* | |
| 81 | + * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet: | |
| 82 | + * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf | |
| 83 | + */ | |
| 84 | + | |
| 85 | +#define MC_TEST_ERR_RCV1 0x60 | |
| 86 | + #define DIMM2_COR_ERR(r) ((r) & 0x7fff) | |
| 87 | + | |
| 88 | +#define MC_TEST_ERR_RCV0 0x64 | |
| 89 | + #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff) | |
| 90 | + #define DIMM0_COR_ERR(r) ((r) & 0x7fff) | |
| 91 | + | |
| 92 | +/* OFFSETS for Device 3 Function 2, as inicated on Xeon 5500 datasheet */ | |
| 93 | +#define MC_COR_ECC_CNT_0 0x80 | |
| 94 | +#define MC_COR_ECC_CNT_1 0x84 | |
| 95 | +#define MC_COR_ECC_CNT_2 0x88 | |
| 96 | +#define MC_COR_ECC_CNT_3 0x8c | |
| 97 | +#define MC_COR_ECC_CNT_4 0x90 | |
| 98 | +#define MC_COR_ECC_CNT_5 0x94 | |
| 99 | + | |
| 100 | +#define DIMM_TOP_COR_ERR(r) (((r) >> 16) & 0x7fff) | |
| 101 | +#define DIMM_BOT_COR_ERR(r) ((r) & 0x7fff) | |
| 102 | + | |
| 103 | + | |
| 104 | + /* OFFSETS for Devices 4,5 and 6 Function 0 */ | |
| 105 | + | |
| 106 | +#define MC_CHANNEL_DIMM_INIT_PARAMS 0x58 | |
| 107 | + #define THREE_DIMMS_PRESENT (1 << 24) | |
| 108 | + #define SINGLE_QUAD_RANK_PRESENT (1 << 23) | |
| 109 | + #define QUAD_RANK_PRESENT (1 << 22) | |
| 110 | + #define REGISTERED_DIMM (1 << 15) | |
| 111 | + | |
| 112 | +#define MC_CHANNEL_MAPPER 0x60 | |
| 113 | + #define RDLCH(r, ch) ((((r) >> (3 + (ch * 6))) & 0x07) - 1) | |
| 114 | + #define WRLCH(r, ch) ((((r) >> (ch * 6)) & 0x07) - 1) | |
| 115 | + | |
| 116 | +#define MC_CHANNEL_RANK_PRESENT 0x7c | |
| 117 | + #define RANK_PRESENT_MASK 0xffff | |
| 118 | + | |
| 119 | +#define MC_CHANNEL_ADDR_MATCH 0xf0 | |
| 120 | +#define MC_CHANNEL_ERROR_MASK 0xf8 | |
| 121 | +#define MC_CHANNEL_ERROR_INJECT 0xfc | |
| 122 | + #define INJECT_ADDR_PARITY 0x10 | |
| 123 | + #define INJECT_ECC 0x08 | |
| 124 | + #define MASK_CACHELINE 0x06 | |
| 125 | + #define MASK_FULL_CACHELINE 0x06 | |
| 126 | + #define MASK_MSB32_CACHELINE 0x04 | |
| 127 | + #define MASK_LSB32_CACHELINE 0x02 | |
| 128 | + #define NO_MASK_CACHELINE 0x00 | |
| 129 | + #define REPEAT_EN 0x01 | |
| 130 | + | |
| 131 | + /* OFFSETS for Devices 4,5 and 6 Function 1 */ | |
| 132 | + | |
| 133 | +#define MC_DOD_CH_DIMM0 0x48 | |
| 134 | +#define MC_DOD_CH_DIMM1 0x4c | |
| 135 | +#define MC_DOD_CH_DIMM2 0x50 | |
| 136 | + #define RANKOFFSET_MASK ((1 << 12) | (1 << 11) | (1 << 10)) | |
| 137 | + #define RANKOFFSET(x) ((x & RANKOFFSET_MASK) >> 10) | |
| 138 | + #define DIMM_PRESENT_MASK (1 << 9) | |
| 139 | + #define DIMM_PRESENT(x) (((x) & DIMM_PRESENT_MASK) >> 9) | |
| 140 | + #define MC_DOD_NUMBANK_MASK ((1 << 8) | (1 << 7)) | |
| 141 | + #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7) | |
| 142 | + #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5)) | |
| 143 | + #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5) | |
| 144 | + #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2)) | |
| 145 | + #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2) | |
| 146 | + #define MC_DOD_NUMCOL_MASK 3 | |
| 147 | + #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK) | |
| 148 | + | |
| 149 | +#define MC_RANK_PRESENT 0x7c | |
| 150 | + | |
| 151 | +#define MC_SAG_CH_0 0x80 | |
| 152 | +#define MC_SAG_CH_1 0x84 | |
| 153 | +#define MC_SAG_CH_2 0x88 | |
| 154 | +#define MC_SAG_CH_3 0x8c | |
| 155 | +#define MC_SAG_CH_4 0x90 | |
| 156 | +#define MC_SAG_CH_5 0x94 | |
| 157 | +#define MC_SAG_CH_6 0x98 | |
| 158 | +#define MC_SAG_CH_7 0x9c | |
| 159 | + | |
| 160 | +#define MC_RIR_LIMIT_CH_0 0x40 | |
| 161 | +#define MC_RIR_LIMIT_CH_1 0x44 | |
| 162 | +#define MC_RIR_LIMIT_CH_2 0x48 | |
| 163 | +#define MC_RIR_LIMIT_CH_3 0x4C | |
| 164 | +#define MC_RIR_LIMIT_CH_4 0x50 | |
| 165 | +#define MC_RIR_LIMIT_CH_5 0x54 | |
| 166 | +#define MC_RIR_LIMIT_CH_6 0x58 | |
| 167 | +#define MC_RIR_LIMIT_CH_7 0x5C | |
| 168 | +#define MC_RIR_LIMIT_MASK ((1 << 10) - 1) | |
| 169 | + | |
| 170 | +#define MC_RIR_WAY_CH 0x80 | |
| 171 | + #define MC_RIR_WAY_OFFSET_MASK (((1 << 14) - 1) & ~0x7) | |
| 172 | + #define MC_RIR_WAY_RANK_MASK 0x7 | |
| 173 | + | |
| 174 | +/* | |
| 175 | + * i7core structs | |
| 176 | + */ | |
| 177 | + | |
| 178 | +#define NUM_CHANS 3 | |
| 179 | +#define MAX_DIMMS 3 /* Max DIMMS per channel */ | |
| 180 | +#define MAX_MCR_FUNC 4 | |
| 181 | +#define MAX_CHAN_FUNC 3 | |
| 182 | + | |
| 183 | +struct i7core_info { | |
| 184 | + u32 mc_control; | |
| 185 | + u32 mc_status; | |
| 186 | + u32 max_dod; | |
| 187 | + u32 ch_map; | |
| 188 | +}; | |
| 189 | + | |
| 190 | + | |
| 191 | +struct i7core_inject { | |
| 192 | + int enable; | |
| 193 | + | |
| 194 | + u32 section; | |
| 195 | + u32 type; | |
| 196 | + u32 eccmask; | |
| 197 | + | |
| 198 | + /* Error address mask */ | |
| 199 | + int channel, dimm, rank, bank, page, col; | |
| 200 | +}; | |
| 201 | + | |
| 202 | +struct i7core_channel { | |
| 203 | + u32 ranks; | |
| 204 | + u32 dimms; | |
| 205 | +}; | |
| 206 | + | |
| 207 | +struct pci_id_descr { | |
| 208 | + int dev; | |
| 209 | + int func; | |
| 210 | + int dev_id; | |
| 211 | + int optional; | |
| 212 | +}; | |
| 213 | + | |
| 214 | +struct pci_id_table { | |
| 215 | + struct pci_id_descr *descr; | |
| 216 | + int n_devs; | |
| 217 | +}; | |
| 218 | + | |
| 219 | +struct i7core_dev { | |
| 220 | + struct list_head list; | |
| 221 | + u8 socket; | |
| 222 | + struct pci_dev **pdev; | |
| 223 | + int n_devs; | |
| 224 | + struct mem_ctl_info *mci; | |
| 225 | +}; | |
| 226 | + | |
| 227 | +struct i7core_pvt { | |
| 228 | + struct pci_dev *pci_noncore; | |
| 229 | + struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1]; | |
| 230 | + struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1]; | |
| 231 | + | |
| 232 | + struct i7core_dev *i7core_dev; | |
| 233 | + | |
| 234 | + struct i7core_info info; | |
| 235 | + struct i7core_inject inject; | |
| 236 | + struct i7core_channel channel[NUM_CHANS]; | |
| 237 | + | |
| 238 | + int channels; /* Number of active channels */ | |
| 239 | + | |
| 240 | + int ce_count_available; | |
| 241 | + int csrow_map[NUM_CHANS][MAX_DIMMS]; | |
| 242 | + | |
| 243 | + /* ECC corrected errors counts per udimm */ | |
| 244 | + unsigned long udimm_ce_count[MAX_DIMMS]; | |
| 245 | + int udimm_last_ce_count[MAX_DIMMS]; | |
| 246 | + /* ECC corrected errors counts per rdimm */ | |
| 247 | + unsigned long rdimm_ce_count[NUM_CHANS][MAX_DIMMS]; | |
| 248 | + int rdimm_last_ce_count[NUM_CHANS][MAX_DIMMS]; | |
| 249 | + | |
| 250 | + unsigned int is_registered; | |
| 251 | + | |
| 252 | + /* mcelog glue */ | |
| 253 | + struct edac_mce edac_mce; | |
| 254 | + | |
| 255 | + /* Fifo double buffers */ | |
| 256 | + struct mce mce_entry[MCE_LOG_LEN]; | |
| 257 | + struct mce mce_outentry[MCE_LOG_LEN]; | |
| 258 | + | |
| 259 | + /* Fifo in/out counters */ | |
| 260 | + unsigned mce_in, mce_out; | |
| 261 | + | |
| 262 | + /* Count indicator to show errors not got */ | |
| 263 | + unsigned mce_overrun; | |
| 264 | +}; | |
| 265 | + | |
| 266 | +/* Static vars */ | |
| 267 | +static LIST_HEAD(i7core_edac_list); | |
| 268 | +static DEFINE_MUTEX(i7core_edac_lock); | |
| 269 | + | |
| 270 | +#define PCI_DESCR(device, function, device_id) \ | |
| 271 | + .dev = (device), \ | |
| 272 | + .func = (function), \ | |
| 273 | + .dev_id = (device_id) | |
| 274 | + | |
| 275 | +struct pci_id_descr pci_dev_descr_i7core_nehalem[] = { | |
| 276 | + /* Memory controller */ | |
| 277 | + { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, | |
| 278 | + { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, | |
| 279 | + /* Exists only for RDIMM */ | |
| 280 | + { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS), .optional = 1 }, | |
| 281 | + { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, | |
| 282 | + | |
| 283 | + /* Channel 0 */ | |
| 284 | + { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) }, | |
| 285 | + { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) }, | |
| 286 | + { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK) }, | |
| 287 | + { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC) }, | |
| 288 | + | |
| 289 | + /* Channel 1 */ | |
| 290 | + { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL) }, | |
| 291 | + { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR) }, | |
| 292 | + { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK) }, | |
| 293 | + { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC) }, | |
| 294 | + | |
| 295 | + /* Channel 2 */ | |
| 296 | + { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL) }, | |
| 297 | + { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) }, | |
| 298 | + { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) }, | |
| 299 | + { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) }, | |
| 300 | + | |
| 301 | + /* Generic Non-core registers */ | |
| 302 | + /* | |
| 303 | + * This is the PCI device on i7core and on Xeon 35xx (8086:2c41) | |
| 304 | + * On Xeon 55xx, however, it has a different id (8086:2c40). So, | |
| 305 | + * the probing code needs to test for the other address in case of | |
| 306 | + * failure of this one | |
| 307 | + */ | |
| 308 | + { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE) }, | |
| 309 | + | |
| 310 | +}; | |
| 311 | + | |
| 312 | +struct pci_id_descr pci_dev_descr_lynnfield[] = { | |
| 313 | + { PCI_DESCR( 3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR) }, | |
| 314 | + { PCI_DESCR( 3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD) }, | |
| 315 | + { PCI_DESCR( 3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST) }, | |
| 316 | + | |
| 317 | + { PCI_DESCR( 4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL) }, | |
| 318 | + { PCI_DESCR( 4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR) }, | |
| 319 | + { PCI_DESCR( 4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK) }, | |
| 320 | + { PCI_DESCR( 4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC) }, | |
| 321 | + | |
| 322 | + { PCI_DESCR( 5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL) }, | |
| 323 | + { PCI_DESCR( 5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) }, | |
| 324 | + { PCI_DESCR( 5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) }, | |
| 325 | + { PCI_DESCR( 5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) }, | |
| 326 | + | |
| 327 | + /* | |
| 328 | + * This is the PCI device has an alternate address on some | |
| 329 | + * processors like Core i7 860 | |
| 330 | + */ | |
| 331 | + { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) }, | |
| 332 | +}; | |
| 333 | + | |
| 334 | +struct pci_id_descr pci_dev_descr_i7core_westmere[] = { | |
| 335 | + /* Memory controller */ | |
| 336 | + { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2) }, | |
| 337 | + { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2) }, | |
| 338 | + /* Exists only for RDIMM */ | |
| 339 | + { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2), .optional = 1 }, | |
| 340 | + { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2) }, | |
| 341 | + | |
| 342 | + /* Channel 0 */ | |
| 343 | + { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2) }, | |
| 344 | + { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2) }, | |
| 345 | + { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2) }, | |
| 346 | + { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2) }, | |
| 347 | + | |
| 348 | + /* Channel 1 */ | |
| 349 | + { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2) }, | |
| 350 | + { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2) }, | |
| 351 | + { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2) }, | |
| 352 | + { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2) }, | |
| 353 | + | |
| 354 | + /* Channel 2 */ | |
| 355 | + { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2) }, | |
| 356 | + { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) }, | |
| 357 | + { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) }, | |
| 358 | + { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2) }, | |
| 359 | + | |
| 360 | + /* Generic Non-core registers */ | |
| 361 | + { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2) }, | |
| 362 | + | |
| 363 | +}; | |
| 364 | + | |
| 365 | +#define PCI_ID_TABLE_ENTRY(A) { A, ARRAY_SIZE(A) } | |
| 366 | +struct pci_id_table pci_dev_table[] = { | |
| 367 | + PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem), | |
| 368 | + PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield), | |
| 369 | + PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere), | |
| 370 | +}; | |
| 371 | + | |
| 372 | +/* | |
| 373 | + * pci_device_id table for which devices we are looking for | |
| 374 | + */ | |
| 375 | +static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { | |
| 376 | + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, | |
| 377 | + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0)}, | |
| 378 | + {0,} /* 0 terminated list. */ | |
| 379 | +}; | |
| 380 | + | |
| 381 | +static struct edac_pci_ctl_info *i7core_pci; | |
| 382 | + | |
| 383 | +/**************************************************************************** | |
| 384 | + Anciliary status routines | |
| 385 | + ****************************************************************************/ | |
| 386 | + | |
| 387 | + /* MC_CONTROL bits */ | |
| 388 | +#define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & (1 << (8 + ch))) | |
| 389 | +#define ECCx8(pvt) ((pvt)->info.mc_control & (1 << 1)) | |
| 390 | + | |
| 391 | + /* MC_STATUS bits */ | |
| 392 | +#define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 4)) | |
| 393 | +#define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch)) | |
| 394 | + | |
| 395 | + /* MC_MAX_DOD read functions */ | |
| 396 | +static inline int numdimms(u32 dimms) | |
| 397 | +{ | |
| 398 | + return (dimms & 0x3) + 1; | |
| 399 | +} | |
| 400 | + | |
| 401 | +static inline int numrank(u32 rank) | |
| 402 | +{ | |
| 403 | + static int ranks[4] = { 1, 2, 4, -EINVAL }; | |
| 404 | + | |
| 405 | + return ranks[rank & 0x3]; | |
| 406 | +} | |
| 407 | + | |
| 408 | +static inline int numbank(u32 bank) | |
| 409 | +{ | |
| 410 | + static int banks[4] = { 4, 8, 16, -EINVAL }; | |
| 411 | + | |
| 412 | + return banks[bank & 0x3]; | |
| 413 | +} | |
| 414 | + | |
| 415 | +static inline int numrow(u32 row) | |
| 416 | +{ | |
| 417 | + static int rows[8] = { | |
| 418 | + 1 << 12, 1 << 13, 1 << 14, 1 << 15, | |
| 419 | + 1 << 16, -EINVAL, -EINVAL, -EINVAL, | |
| 420 | + }; | |
| 421 | + | |
| 422 | + return rows[row & 0x7]; | |
| 423 | +} | |
| 424 | + | |
| 425 | +static inline int numcol(u32 col) | |
| 426 | +{ | |
| 427 | + static int cols[8] = { | |
| 428 | + 1 << 10, 1 << 11, 1 << 12, -EINVAL, | |
| 429 | + }; | |
| 430 | + return cols[col & 0x3]; | |
| 431 | +} | |
| 432 | + | |
| 433 | +static struct i7core_dev *get_i7core_dev(u8 socket) | |
| 434 | +{ | |
| 435 | + struct i7core_dev *i7core_dev; | |
| 436 | + | |
| 437 | + list_for_each_entry(i7core_dev, &i7core_edac_list, list) { | |
| 438 | + if (i7core_dev->socket == socket) | |
| 439 | + return i7core_dev; | |
| 440 | + } | |
| 441 | + | |
| 442 | + return NULL; | |
| 443 | +} | |
| 444 | + | |
| 445 | +/**************************************************************************** | |
| 446 | + Memory check routines | |
| 447 | + ****************************************************************************/ | |
| 448 | +static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot, | |
| 449 | + unsigned func) | |
| 450 | +{ | |
| 451 | + struct i7core_dev *i7core_dev = get_i7core_dev(socket); | |
| 452 | + int i; | |
| 453 | + | |
| 454 | + if (!i7core_dev) | |
| 455 | + return NULL; | |
| 456 | + | |
| 457 | + for (i = 0; i < i7core_dev->n_devs; i++) { | |
| 458 | + if (!i7core_dev->pdev[i]) | |
| 459 | + continue; | |
| 460 | + | |
| 461 | + if (PCI_SLOT(i7core_dev->pdev[i]->devfn) == slot && | |
| 462 | + PCI_FUNC(i7core_dev->pdev[i]->devfn) == func) { | |
| 463 | + return i7core_dev->pdev[i]; | |
| 464 | + } | |
| 465 | + } | |
| 466 | + | |
| 467 | + return NULL; | |
| 468 | +} | |
| 469 | + | |
| 470 | +/** | |
| 471 | + * i7core_get_active_channels() - gets the number of channels and csrows | |
| 472 | + * @socket: Quick Path Interconnect socket | |
| 473 | + * @channels: Number of channels that will be returned | |
| 474 | + * @csrows: Number of csrows found | |
| 475 | + * | |
| 476 | + * Since EDAC core needs to know in advance the number of available channels | |
| 477 | + * and csrows, in order to allocate memory for csrows/channels, it is needed | |
| 478 | + * to run two similar steps. At the first step, implemented on this function, | |
| 479 | + * it checks the number of csrows/channels present at one socket. | |
| 480 | + * this is used in order to properly allocate the size of mci components. | |
| 481 | + * | |
| 482 | + * It should be noticed that none of the current available datasheets explain | |
| 483 | + * or even mention how csrows are seen by the memory controller. So, we need | |
| 484 | + * to add a fake description for csrows. | |
| 485 | + * So, this driver is attributing one DIMM memory for one csrow. | |
| 486 | + */ | |
| 487 | +static int i7core_get_active_channels(u8 socket, unsigned *channels, | |
| 488 | + unsigned *csrows) | |
| 489 | +{ | |
| 490 | + struct pci_dev *pdev = NULL; | |
| 491 | + int i, j; | |
| 492 | + u32 status, control; | |
| 493 | + | |
| 494 | + *channels = 0; | |
| 495 | + *csrows = 0; | |
| 496 | + | |
| 497 | + pdev = get_pdev_slot_func(socket, 3, 0); | |
| 498 | + if (!pdev) { | |
| 499 | + i7core_printk(KERN_ERR, "Couldn't find socket %d fn 3.0!!!\n", | |
| 500 | + socket); | |
| 501 | + return -ENODEV; | |
| 502 | + } | |
| 503 | + | |
| 504 | + /* Device 3 function 0 reads */ | |
| 505 | + pci_read_config_dword(pdev, MC_STATUS, &status); | |
| 506 | + pci_read_config_dword(pdev, MC_CONTROL, &control); | |
| 507 | + | |
| 508 | + for (i = 0; i < NUM_CHANS; i++) { | |
| 509 | + u32 dimm_dod[3]; | |
| 510 | + /* Check if the channel is active */ | |
| 511 | + if (!(control & (1 << (8 + i)))) | |
| 512 | + continue; | |
| 513 | + | |
| 514 | + /* Check if the channel is disabled */ | |
| 515 | + if (status & (1 << i)) | |
| 516 | + continue; | |
| 517 | + | |
| 518 | + pdev = get_pdev_slot_func(socket, i + 4, 1); | |
| 519 | + if (!pdev) { | |
| 520 | + i7core_printk(KERN_ERR, "Couldn't find socket %d " | |
| 521 | + "fn %d.%d!!!\n", | |
| 522 | + socket, i + 4, 1); | |
| 523 | + return -ENODEV; | |
| 524 | + } | |
| 525 | + /* Devices 4-6 function 1 */ | |
| 526 | + pci_read_config_dword(pdev, | |
| 527 | + MC_DOD_CH_DIMM0, &dimm_dod[0]); | |
| 528 | + pci_read_config_dword(pdev, | |
| 529 | + MC_DOD_CH_DIMM1, &dimm_dod[1]); | |
| 530 | + pci_read_config_dword(pdev, | |
| 531 | + MC_DOD_CH_DIMM2, &dimm_dod[2]); | |
| 532 | + | |
| 533 | + (*channels)++; | |
| 534 | + | |
| 535 | + for (j = 0; j < 3; j++) { | |
| 536 | + if (!DIMM_PRESENT(dimm_dod[j])) | |
| 537 | + continue; | |
| 538 | + (*csrows)++; | |
| 539 | + } | |
| 540 | + } | |
| 541 | + | |
| 542 | + debugf0("Number of active channels on socket %d: %d\n", | |
| 543 | + socket, *channels); | |
| 544 | + | |
| 545 | + return 0; | |
| 546 | +} | |
| 547 | + | |
| 548 | +static int get_dimm_config(struct mem_ctl_info *mci, int *csrow) | |
| 549 | +{ | |
| 550 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 551 | + struct csrow_info *csr; | |
| 552 | + struct pci_dev *pdev; | |
| 553 | + int i, j; | |
| 554 | + unsigned long last_page = 0; | |
| 555 | + enum edac_type mode; | |
| 556 | + enum mem_type mtype; | |
| 557 | + | |
| 558 | + /* Get data from the MC register, function 0 */ | |
| 559 | + pdev = pvt->pci_mcr[0]; | |
| 560 | + if (!pdev) | |
| 561 | + return -ENODEV; | |
| 562 | + | |
| 563 | + /* Device 3 function 0 reads */ | |
| 564 | + pci_read_config_dword(pdev, MC_CONTROL, &pvt->info.mc_control); | |
| 565 | + pci_read_config_dword(pdev, MC_STATUS, &pvt->info.mc_status); | |
| 566 | + pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod); | |
| 567 | + pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map); | |
| 568 | + | |
| 569 | + debugf0("QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n", | |
| 570 | + pvt->i7core_dev->socket, pvt->info.mc_control, pvt->info.mc_status, | |
| 571 | + pvt->info.max_dod, pvt->info.ch_map); | |
| 572 | + | |
| 573 | + if (ECC_ENABLED(pvt)) { | |
| 574 | + debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4); | |
| 575 | + if (ECCx8(pvt)) | |
| 576 | + mode = EDAC_S8ECD8ED; | |
| 577 | + else | |
| 578 | + mode = EDAC_S4ECD4ED; | |
| 579 | + } else { | |
| 580 | + debugf0("ECC disabled\n"); | |
| 581 | + mode = EDAC_NONE; | |
| 582 | + } | |
| 583 | + | |
| 584 | + /* FIXME: need to handle the error codes */ | |
| 585 | + debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked " | |
| 586 | + "x%x x 0x%x\n", | |
| 587 | + numdimms(pvt->info.max_dod), | |
| 588 | + numrank(pvt->info.max_dod >> 2), | |
| 589 | + numbank(pvt->info.max_dod >> 4), | |
| 590 | + numrow(pvt->info.max_dod >> 6), | |
| 591 | + numcol(pvt->info.max_dod >> 9)); | |
| 592 | + | |
| 593 | + for (i = 0; i < NUM_CHANS; i++) { | |
| 594 | + u32 data, dimm_dod[3], value[8]; | |
| 595 | + | |
| 596 | + if (!pvt->pci_ch[i][0]) | |
| 597 | + continue; | |
| 598 | + | |
| 599 | + if (!CH_ACTIVE(pvt, i)) { | |
| 600 | + debugf0("Channel %i is not active\n", i); | |
| 601 | + continue; | |
| 602 | + } | |
| 603 | + if (CH_DISABLED(pvt, i)) { | |
| 604 | + debugf0("Channel %i is disabled\n", i); | |
| 605 | + continue; | |
| 606 | + } | |
| 607 | + | |
| 608 | + /* Devices 4-6 function 0 */ | |
| 609 | + pci_read_config_dword(pvt->pci_ch[i][0], | |
| 610 | + MC_CHANNEL_DIMM_INIT_PARAMS, &data); | |
| 611 | + | |
| 612 | + pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? | |
| 613 | + 4 : 2; | |
| 614 | + | |
| 615 | + if (data & REGISTERED_DIMM) | |
| 616 | + mtype = MEM_RDDR3; | |
| 617 | + else | |
| 618 | + mtype = MEM_DDR3; | |
| 619 | +#if 0 | |
| 620 | + if (data & THREE_DIMMS_PRESENT) | |
| 621 | + pvt->channel[i].dimms = 3; | |
| 622 | + else if (data & SINGLE_QUAD_RANK_PRESENT) | |
| 623 | + pvt->channel[i].dimms = 1; | |
| 624 | + else | |
| 625 | + pvt->channel[i].dimms = 2; | |
| 626 | +#endif | |
| 627 | + | |
| 628 | + /* Devices 4-6 function 1 */ | |
| 629 | + pci_read_config_dword(pvt->pci_ch[i][1], | |
| 630 | + MC_DOD_CH_DIMM0, &dimm_dod[0]); | |
| 631 | + pci_read_config_dword(pvt->pci_ch[i][1], | |
| 632 | + MC_DOD_CH_DIMM1, &dimm_dod[1]); | |
| 633 | + pci_read_config_dword(pvt->pci_ch[i][1], | |
| 634 | + MC_DOD_CH_DIMM2, &dimm_dod[2]); | |
| 635 | + | |
| 636 | + debugf0("Ch%d phy rd%d, wr%d (0x%08x): " | |
| 637 | + "%d ranks, %cDIMMs\n", | |
| 638 | + i, | |
| 639 | + RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), | |
| 640 | + data, | |
| 641 | + pvt->channel[i].ranks, | |
| 642 | + (data & REGISTERED_DIMM) ? 'R' : 'U'); | |
| 643 | + | |
| 644 | + for (j = 0; j < 3; j++) { | |
| 645 | + u32 banks, ranks, rows, cols; | |
| 646 | + u32 size, npages; | |
| 647 | + | |
| 648 | + if (!DIMM_PRESENT(dimm_dod[j])) | |
| 649 | + continue; | |
| 650 | + | |
| 651 | + banks = numbank(MC_DOD_NUMBANK(dimm_dod[j])); | |
| 652 | + ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j])); | |
| 653 | + rows = numrow(MC_DOD_NUMROW(dimm_dod[j])); | |
| 654 | + cols = numcol(MC_DOD_NUMCOL(dimm_dod[j])); | |
| 655 | + | |
| 656 | + /* DDR3 has 8 I/O banks */ | |
| 657 | + size = (rows * cols * banks * ranks) >> (20 - 3); | |
| 658 | + | |
| 659 | + pvt->channel[i].dimms++; | |
| 660 | + | |
| 661 | + debugf0("\tdimm %d %d Mb offset: %x, " | |
| 662 | + "bank: %d, rank: %d, row: %#x, col: %#x\n", | |
| 663 | + j, size, | |
| 664 | + RANKOFFSET(dimm_dod[j]), | |
| 665 | + banks, ranks, rows, cols); | |
| 666 | + | |
| 667 | +#if PAGE_SHIFT > 20 | |
| 668 | + npages = size >> (PAGE_SHIFT - 20); | |
| 669 | +#else | |
| 670 | + npages = size << (20 - PAGE_SHIFT); | |
| 671 | +#endif | |
| 672 | + | |
| 673 | + csr = &mci->csrows[*csrow]; | |
| 674 | + csr->first_page = last_page + 1; | |
| 675 | + last_page += npages; | |
| 676 | + csr->last_page = last_page; | |
| 677 | + csr->nr_pages = npages; | |
| 678 | + | |
| 679 | + csr->page_mask = 0; | |
| 680 | + csr->grain = 8; | |
| 681 | + csr->csrow_idx = *csrow; | |
| 682 | + csr->nr_channels = 1; | |
| 683 | + | |
| 684 | + csr->channels[0].chan_idx = i; | |
| 685 | + csr->channels[0].ce_count = 0; | |
| 686 | + | |
| 687 | + pvt->csrow_map[i][j] = *csrow; | |
| 688 | + | |
| 689 | + switch (banks) { | |
| 690 | + case 4: | |
| 691 | + csr->dtype = DEV_X4; | |
| 692 | + break; | |
| 693 | + case 8: | |
| 694 | + csr->dtype = DEV_X8; | |
| 695 | + break; | |
| 696 | + case 16: | |
| 697 | + csr->dtype = DEV_X16; | |
| 698 | + break; | |
| 699 | + default: | |
| 700 | + csr->dtype = DEV_UNKNOWN; | |
| 701 | + } | |
| 702 | + | |
| 703 | + csr->edac_mode = mode; | |
| 704 | + csr->mtype = mtype; | |
| 705 | + | |
| 706 | + (*csrow)++; | |
| 707 | + } | |
| 708 | + | |
| 709 | + pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]); | |
| 710 | + pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]); | |
| 711 | + pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]); | |
| 712 | + pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]); | |
| 713 | + pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]); | |
| 714 | + pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); | |
| 715 | + pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); | |
| 716 | + pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); | |
| 717 | + debugf1("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); | |
| 718 | + for (j = 0; j < 8; j++) | |
| 719 | + debugf1("\t\t%#x\t%#x\t%#x\n", | |
| 720 | + (value[j] >> 27) & 0x1, | |
| 721 | + (value[j] >> 24) & 0x7, | |
| 722 | + (value[j] && ((1 << 24) - 1))); | |
| 723 | + } | |
| 724 | + | |
| 725 | + return 0; | |
| 726 | +} | |
| 727 | + | |
| 728 | +/**************************************************************************** | |
| 729 | + Error insertion routines | |
| 730 | + ****************************************************************************/ | |
| 731 | + | |
| 732 | +/* The i7core has independent error injection features per channel. | |
| 733 | + However, to have a simpler code, we don't allow enabling error injection | |
| 734 | + on more than one channel. | |
| 735 | + Also, since a change at an inject parameter will be applied only at enable, | |
| 736 | + we're disabling error injection on all write calls to the sysfs nodes that | |
| 737 | + controls the error code injection. | |
| 738 | + */ | |
| 739 | +static int disable_inject(struct mem_ctl_info *mci) | |
| 740 | +{ | |
| 741 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 742 | + | |
| 743 | + pvt->inject.enable = 0; | |
| 744 | + | |
| 745 | + if (!pvt->pci_ch[pvt->inject.channel][0]) | |
| 746 | + return -ENODEV; | |
| 747 | + | |
| 748 | + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], | |
| 749 | + MC_CHANNEL_ERROR_INJECT, 0); | |
| 750 | + | |
| 751 | + return 0; | |
| 752 | +} | |
| 753 | + | |
| 754 | +/* | |
| 755 | + * i7core inject inject.section | |
| 756 | + * | |
| 757 | + * accept and store error injection inject.section value | |
| 758 | + * bit 0 - refers to the lower 32-byte half cacheline | |
| 759 | + * bit 1 - refers to the upper 32-byte half cacheline | |
| 760 | + */ | |
| 761 | +static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci, | |
| 762 | + const char *data, size_t count) | |
| 763 | +{ | |
| 764 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 765 | + unsigned long value; | |
| 766 | + int rc; | |
| 767 | + | |
| 768 | + if (pvt->inject.enable) | |
| 769 | + disable_inject(mci); | |
| 770 | + | |
| 771 | + rc = strict_strtoul(data, 10, &value); | |
| 772 | + if ((rc < 0) || (value > 3)) | |
| 773 | + return -EIO; | |
| 774 | + | |
| 775 | + pvt->inject.section = (u32) value; | |
| 776 | + return count; | |
| 777 | +} | |
| 778 | + | |
| 779 | +static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci, | |
| 780 | + char *data) | |
| 781 | +{ | |
| 782 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 783 | + return sprintf(data, "0x%08x\n", pvt->inject.section); | |
| 784 | +} | |
| 785 | + | |
| 786 | +/* | |
| 787 | + * i7core inject.type | |
| 788 | + * | |
| 789 | + * accept and store error injection inject.section value | |
| 790 | + * bit 0 - repeat enable - Enable error repetition | |
| 791 | + * bit 1 - inject ECC error | |
| 792 | + * bit 2 - inject parity error | |
| 793 | + */ | |
| 794 | +static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci, | |
| 795 | + const char *data, size_t count) | |
| 796 | +{ | |
| 797 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 798 | + unsigned long value; | |
| 799 | + int rc; | |
| 800 | + | |
| 801 | + if (pvt->inject.enable) | |
| 802 | + disable_inject(mci); | |
| 803 | + | |
| 804 | + rc = strict_strtoul(data, 10, &value); | |
| 805 | + if ((rc < 0) || (value > 7)) | |
| 806 | + return -EIO; | |
| 807 | + | |
| 808 | + pvt->inject.type = (u32) value; | |
| 809 | + return count; | |
| 810 | +} | |
| 811 | + | |
| 812 | +static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci, | |
| 813 | + char *data) | |
| 814 | +{ | |
| 815 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 816 | + return sprintf(data, "0x%08x\n", pvt->inject.type); | |
| 817 | +} | |
| 818 | + | |
| 819 | +/* | |
| 820 | + * i7core_inject_inject.eccmask_store | |
| 821 | + * | |
| 822 | + * The type of error (UE/CE) will depend on the inject.eccmask value: | |
| 823 | + * Any bits set to a 1 will flip the corresponding ECC bit | |
| 824 | + * Correctable errors can be injected by flipping 1 bit or the bits within | |
| 825 | + * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or | |
| 826 | + * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an | |
| 827 | + * uncorrectable error to be injected. | |
| 828 | + */ | |
| 829 | +static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci, | |
| 830 | + const char *data, size_t count) | |
| 831 | +{ | |
| 832 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 833 | + unsigned long value; | |
| 834 | + int rc; | |
| 835 | + | |
| 836 | + if (pvt->inject.enable) | |
| 837 | + disable_inject(mci); | |
| 838 | + | |
| 839 | + rc = strict_strtoul(data, 10, &value); | |
| 840 | + if (rc < 0) | |
| 841 | + return -EIO; | |
| 842 | + | |
| 843 | + pvt->inject.eccmask = (u32) value; | |
| 844 | + return count; | |
| 845 | +} | |
| 846 | + | |
| 847 | +static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci, | |
| 848 | + char *data) | |
| 849 | +{ | |
| 850 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 851 | + return sprintf(data, "0x%08x\n", pvt->inject.eccmask); | |
| 852 | +} | |
| 853 | + | |
| 854 | +/* | |
| 855 | + * i7core_addrmatch | |
| 856 | + * | |
| 857 | + * The type of error (UE/CE) will depend on the inject.eccmask value: | |
| 858 | + * Any bits set to a 1 will flip the corresponding ECC bit | |
| 859 | + * Correctable errors can be injected by flipping 1 bit or the bits within | |
| 860 | + * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or | |
| 861 | + * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an | |
| 862 | + * uncorrectable error to be injected. | |
| 863 | + */ | |
| 864 | + | |
| 865 | +#define DECLARE_ADDR_MATCH(param, limit) \ | |
| 866 | +static ssize_t i7core_inject_store_##param( \ | |
| 867 | + struct mem_ctl_info *mci, \ | |
| 868 | + const char *data, size_t count) \ | |
| 869 | +{ \ | |
| 870 | + struct i7core_pvt *pvt; \ | |
| 871 | + long value; \ | |
| 872 | + int rc; \ | |
| 873 | + \ | |
| 874 | + debugf1("%s()\n", __func__); \ | |
| 875 | + pvt = mci->pvt_info; \ | |
| 876 | + \ | |
| 877 | + if (pvt->inject.enable) \ | |
| 878 | + disable_inject(mci); \ | |
| 879 | + \ | |
| 880 | + if (!strcasecmp(data, "any") || !strcasecmp(data, "any\n"))\ | |
| 881 | + value = -1; \ | |
| 882 | + else { \ | |
| 883 | + rc = strict_strtoul(data, 10, &value); \ | |
| 884 | + if ((rc < 0) || (value >= limit)) \ | |
| 885 | + return -EIO; \ | |
| 886 | + } \ | |
| 887 | + \ | |
| 888 | + pvt->inject.param = value; \ | |
| 889 | + \ | |
| 890 | + return count; \ | |
| 891 | +} \ | |
| 892 | + \ | |
| 893 | +static ssize_t i7core_inject_show_##param( \ | |
| 894 | + struct mem_ctl_info *mci, \ | |
| 895 | + char *data) \ | |
| 896 | +{ \ | |
| 897 | + struct i7core_pvt *pvt; \ | |
| 898 | + \ | |
| 899 | + pvt = mci->pvt_info; \ | |
| 900 | + debugf1("%s() pvt=%p\n", __func__, pvt); \ | |
| 901 | + if (pvt->inject.param < 0) \ | |
| 902 | + return sprintf(data, "any\n"); \ | |
| 903 | + else \ | |
| 904 | + return sprintf(data, "%d\n", pvt->inject.param);\ | |
| 905 | +} | |
| 906 | + | |
| 907 | +#define ATTR_ADDR_MATCH(param) \ | |
| 908 | + { \ | |
| 909 | + .attr = { \ | |
| 910 | + .name = #param, \ | |
| 911 | + .mode = (S_IRUGO | S_IWUSR) \ | |
| 912 | + }, \ | |
| 913 | + .show = i7core_inject_show_##param, \ | |
| 914 | + .store = i7core_inject_store_##param, \ | |
| 915 | + } | |
| 916 | + | |
| 917 | +DECLARE_ADDR_MATCH(channel, 3); | |
| 918 | +DECLARE_ADDR_MATCH(dimm, 3); | |
| 919 | +DECLARE_ADDR_MATCH(rank, 4); | |
| 920 | +DECLARE_ADDR_MATCH(bank, 32); | |
| 921 | +DECLARE_ADDR_MATCH(page, 0x10000); | |
| 922 | +DECLARE_ADDR_MATCH(col, 0x4000); | |
| 923 | + | |
| 924 | +static int write_and_test(struct pci_dev *dev, int where, u32 val) | |
| 925 | +{ | |
| 926 | + u32 read; | |
| 927 | + int count; | |
| 928 | + | |
| 929 | + debugf0("setting pci %02x:%02x.%x reg=%02x value=%08x\n", | |
| 930 | + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), | |
| 931 | + where, val); | |
| 932 | + | |
| 933 | + for (count = 0; count < 10; count++) { | |
| 934 | + if (count) | |
| 935 | + msleep(100); | |
| 936 | + pci_write_config_dword(dev, where, val); | |
| 937 | + pci_read_config_dword(dev, where, &read); | |
| 938 | + | |
| 939 | + if (read == val) | |
| 940 | + return 0; | |
| 941 | + } | |
| 942 | + | |
| 943 | + i7core_printk(KERN_ERR, "Error during set pci %02x:%02x.%x reg=%02x " | |
| 944 | + "write=%08x. Read=%08x\n", | |
| 945 | + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), | |
| 946 | + where, val, read); | |
| 947 | + | |
| 948 | + return -EINVAL; | |
| 949 | +} | |
| 950 | + | |
| 951 | +/* | |
| 952 | + * This routine prepares the Memory Controller for error injection. | |
| 953 | + * The error will be injected when some process tries to write to the | |
| 954 | + * memory that matches the given criteria. | |
| 955 | + * The criteria can be set in terms of a mask where dimm, rank, bank, page | |
| 956 | + * and col can be specified. | |
| 957 | + * A -1 value for any of the mask items will make the MCU to ignore | |
| 958 | + * that matching criteria for error injection. | |
| 959 | + * | |
| 960 | + * It should be noticed that the error will only happen after a write operation | |
| 961 | + * on a memory that matches the condition. if REPEAT_EN is not enabled at | |
| 962 | + * inject mask, then it will produce just one error. Otherwise, it will repeat | |
| 963 | + * until the injectmask would be cleaned. | |
| 964 | + * | |
| 965 | + * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD | |
| 966 | + * is reliable enough to check if the MC is using the | |
| 967 | + * three channels. However, this is not clear at the datasheet. | |
| 968 | + */ | |
| 969 | +static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, | |
| 970 | + const char *data, size_t count) | |
| 971 | +{ | |
| 972 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 973 | + u32 injectmask; | |
| 974 | + u64 mask = 0; | |
| 975 | + int rc; | |
| 976 | + long enable; | |
| 977 | + | |
| 978 | + if (!pvt->pci_ch[pvt->inject.channel][0]) | |
| 979 | + return 0; | |
| 980 | + | |
| 981 | + rc = strict_strtoul(data, 10, &enable); | |
| 982 | + if ((rc < 0)) | |
| 983 | + return 0; | |
| 984 | + | |
| 985 | + if (enable) { | |
| 986 | + pvt->inject.enable = 1; | |
| 987 | + } else { | |
| 988 | + disable_inject(mci); | |
| 989 | + return count; | |
| 990 | + } | |
| 991 | + | |
| 992 | + /* Sets pvt->inject.dimm mask */ | |
| 993 | + if (pvt->inject.dimm < 0) | |
| 994 | + mask |= 1LL << 41; | |
| 995 | + else { | |
| 996 | + if (pvt->channel[pvt->inject.channel].dimms > 2) | |
| 997 | + mask |= (pvt->inject.dimm & 0x3LL) << 35; | |
| 998 | + else | |
| 999 | + mask |= (pvt->inject.dimm & 0x1LL) << 36; | |
| 1000 | + } | |
| 1001 | + | |
| 1002 | + /* Sets pvt->inject.rank mask */ | |
| 1003 | + if (pvt->inject.rank < 0) | |
| 1004 | + mask |= 1LL << 40; | |
| 1005 | + else { | |
| 1006 | + if (pvt->channel[pvt->inject.channel].dimms > 2) | |
| 1007 | + mask |= (pvt->inject.rank & 0x1LL) << 34; | |
| 1008 | + else | |
| 1009 | + mask |= (pvt->inject.rank & 0x3LL) << 34; | |
| 1010 | + } | |
| 1011 | + | |
| 1012 | + /* Sets pvt->inject.bank mask */ | |
| 1013 | + if (pvt->inject.bank < 0) | |
| 1014 | + mask |= 1LL << 39; | |
| 1015 | + else | |
| 1016 | + mask |= (pvt->inject.bank & 0x15LL) << 30; | |
| 1017 | + | |
| 1018 | + /* Sets pvt->inject.page mask */ | |
| 1019 | + if (pvt->inject.page < 0) | |
| 1020 | + mask |= 1LL << 38; | |
| 1021 | + else | |
| 1022 | + mask |= (pvt->inject.page & 0xffff) << 14; | |
| 1023 | + | |
| 1024 | + /* Sets pvt->inject.column mask */ | |
| 1025 | + if (pvt->inject.col < 0) | |
| 1026 | + mask |= 1LL << 37; | |
| 1027 | + else | |
| 1028 | + mask |= (pvt->inject.col & 0x3fff); | |
| 1029 | + | |
| 1030 | + /* | |
| 1031 | + * bit 0: REPEAT_EN | |
| 1032 | + * bits 1-2: MASK_HALF_CACHELINE | |
| 1033 | + * bit 3: INJECT_ECC | |
| 1034 | + * bit 4: INJECT_ADDR_PARITY | |
| 1035 | + */ | |
| 1036 | + | |
| 1037 | + injectmask = (pvt->inject.type & 1) | | |
| 1038 | + (pvt->inject.section & 0x3) << 1 | | |
| 1039 | + (pvt->inject.type & 0x6) << (3 - 1); | |
| 1040 | + | |
| 1041 | + /* Unlock writes to registers - this register is write only */ | |
| 1042 | + pci_write_config_dword(pvt->pci_noncore, | |
| 1043 | + MC_CFG_CONTROL, 0x2); | |
| 1044 | + | |
| 1045 | + write_and_test(pvt->pci_ch[pvt->inject.channel][0], | |
| 1046 | + MC_CHANNEL_ADDR_MATCH, mask); | |
| 1047 | + write_and_test(pvt->pci_ch[pvt->inject.channel][0], | |
| 1048 | + MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L); | |
| 1049 | + | |
| 1050 | + write_and_test(pvt->pci_ch[pvt->inject.channel][0], | |
| 1051 | + MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); | |
| 1052 | + | |
| 1053 | + write_and_test(pvt->pci_ch[pvt->inject.channel][0], | |
| 1054 | + MC_CHANNEL_ERROR_INJECT, injectmask); | |
| 1055 | + | |
| 1056 | + /* | |
| 1057 | + * This is something undocumented, based on my tests | |
| 1058 | + * Without writing 8 to this register, errors aren't injected. Not sure | |
| 1059 | + * why. | |
| 1060 | + */ | |
| 1061 | + pci_write_config_dword(pvt->pci_noncore, | |
| 1062 | + MC_CFG_CONTROL, 8); | |
| 1063 | + | |
| 1064 | + debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," | |
| 1065 | + " inject 0x%08x\n", | |
| 1066 | + mask, pvt->inject.eccmask, injectmask); | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + return count; | |
| 1070 | +} | |
| 1071 | + | |
| 1072 | +static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, | |
| 1073 | + char *data) | |
| 1074 | +{ | |
| 1075 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1076 | + u32 injectmask; | |
| 1077 | + | |
| 1078 | + if (!pvt->pci_ch[pvt->inject.channel][0]) | |
| 1079 | + return 0; | |
| 1080 | + | |
| 1081 | + pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], | |
| 1082 | + MC_CHANNEL_ERROR_INJECT, &injectmask); | |
| 1083 | + | |
| 1084 | + debugf0("Inject error read: 0x%018x\n", injectmask); | |
| 1085 | + | |
| 1086 | + if (injectmask & 0x0c) | |
| 1087 | + pvt->inject.enable = 1; | |
| 1088 | + | |
| 1089 | + return sprintf(data, "%d\n", pvt->inject.enable); | |
| 1090 | +} | |
| 1091 | + | |
| 1092 | +#define DECLARE_COUNTER(param) \ | |
| 1093 | +static ssize_t i7core_show_counter_##param( \ | |
| 1094 | + struct mem_ctl_info *mci, \ | |
| 1095 | + char *data) \ | |
| 1096 | +{ \ | |
| 1097 | + struct i7core_pvt *pvt = mci->pvt_info; \ | |
| 1098 | + \ | |
| 1099 | + debugf1("%s() \n", __func__); \ | |
| 1100 | + if (!pvt->ce_count_available || (pvt->is_registered)) \ | |
| 1101 | + return sprintf(data, "data unavailable\n"); \ | |
| 1102 | + return sprintf(data, "%lu\n", \ | |
| 1103 | + pvt->udimm_ce_count[param]); \ | |
| 1104 | +} | |
| 1105 | + | |
| 1106 | +#define ATTR_COUNTER(param) \ | |
| 1107 | + { \ | |
| 1108 | + .attr = { \ | |
| 1109 | + .name = __stringify(udimm##param), \ | |
| 1110 | + .mode = (S_IRUGO | S_IWUSR) \ | |
| 1111 | + }, \ | |
| 1112 | + .show = i7core_show_counter_##param \ | |
| 1113 | + } | |
| 1114 | + | |
| 1115 | +DECLARE_COUNTER(0); | |
| 1116 | +DECLARE_COUNTER(1); | |
| 1117 | +DECLARE_COUNTER(2); | |
| 1118 | + | |
| 1119 | +/* | |
| 1120 | + * Sysfs struct | |
| 1121 | + */ | |
| 1122 | + | |
| 1123 | + | |
| 1124 | +static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = { | |
| 1125 | + ATTR_ADDR_MATCH(channel), | |
| 1126 | + ATTR_ADDR_MATCH(dimm), | |
| 1127 | + ATTR_ADDR_MATCH(rank), | |
| 1128 | + ATTR_ADDR_MATCH(bank), | |
| 1129 | + ATTR_ADDR_MATCH(page), | |
| 1130 | + ATTR_ADDR_MATCH(col), | |
| 1131 | + { .attr = { .name = NULL } } | |
| 1132 | +}; | |
| 1133 | + | |
| 1134 | +static struct mcidev_sysfs_group i7core_inject_addrmatch = { | |
| 1135 | + .name = "inject_addrmatch", | |
| 1136 | + .mcidev_attr = i7core_addrmatch_attrs, | |
| 1137 | +}; | |
| 1138 | + | |
| 1139 | +static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { | |
| 1140 | + ATTR_COUNTER(0), | |
| 1141 | + ATTR_COUNTER(1), | |
| 1142 | + ATTR_COUNTER(2), | |
| 1143 | +}; | |
| 1144 | + | |
| 1145 | +static struct mcidev_sysfs_group i7core_udimm_counters = { | |
| 1146 | + .name = "all_channel_counts", | |
| 1147 | + .mcidev_attr = i7core_udimm_counters_attrs, | |
| 1148 | +}; | |
| 1149 | + | |
| 1150 | +static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { | |
| 1151 | + { | |
| 1152 | + .attr = { | |
| 1153 | + .name = "inject_section", | |
| 1154 | + .mode = (S_IRUGO | S_IWUSR) | |
| 1155 | + }, | |
| 1156 | + .show = i7core_inject_section_show, | |
| 1157 | + .store = i7core_inject_section_store, | |
| 1158 | + }, { | |
| 1159 | + .attr = { | |
| 1160 | + .name = "inject_type", | |
| 1161 | + .mode = (S_IRUGO | S_IWUSR) | |
| 1162 | + }, | |
| 1163 | + .show = i7core_inject_type_show, | |
| 1164 | + .store = i7core_inject_type_store, | |
| 1165 | + }, { | |
| 1166 | + .attr = { | |
| 1167 | + .name = "inject_eccmask", | |
| 1168 | + .mode = (S_IRUGO | S_IWUSR) | |
| 1169 | + }, | |
| 1170 | + .show = i7core_inject_eccmask_show, | |
| 1171 | + .store = i7core_inject_eccmask_store, | |
| 1172 | + }, { | |
| 1173 | + .grp = &i7core_inject_addrmatch, | |
| 1174 | + }, { | |
| 1175 | + .attr = { | |
| 1176 | + .name = "inject_enable", | |
| 1177 | + .mode = (S_IRUGO | S_IWUSR) | |
| 1178 | + }, | |
| 1179 | + .show = i7core_inject_enable_show, | |
| 1180 | + .store = i7core_inject_enable_store, | |
| 1181 | + }, | |
| 1182 | + { .attr = { .name = NULL } }, /* Reserved for udimm counters */ | |
| 1183 | + { .attr = { .name = NULL } } | |
| 1184 | +}; | |
| 1185 | + | |
| 1186 | +/**************************************************************************** | |
| 1187 | + Device initialization routines: put/get, init/exit | |
| 1188 | + ****************************************************************************/ | |
| 1189 | + | |
| 1190 | +/* | |
| 1191 | + * i7core_put_devices 'put' all the devices that we have | |
| 1192 | + * reserved via 'get' | |
| 1193 | + */ | |
| 1194 | +static void i7core_put_devices(struct i7core_dev *i7core_dev) | |
| 1195 | +{ | |
| 1196 | + int i; | |
| 1197 | + | |
| 1198 | + debugf0(__FILE__ ": %s()\n", __func__); | |
| 1199 | + for (i = 0; i < i7core_dev->n_devs; i++) { | |
| 1200 | + struct pci_dev *pdev = i7core_dev->pdev[i]; | |
| 1201 | + if (!pdev) | |
| 1202 | + continue; | |
| 1203 | + debugf0("Removing dev %02x:%02x.%d\n", | |
| 1204 | + pdev->bus->number, | |
| 1205 | + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); | |
| 1206 | + pci_dev_put(pdev); | |
| 1207 | + } | |
| 1208 | + kfree(i7core_dev->pdev); | |
| 1209 | + list_del(&i7core_dev->list); | |
| 1210 | + kfree(i7core_dev); | |
| 1211 | +} | |
| 1212 | + | |
| 1213 | +static void i7core_put_all_devices(void) | |
| 1214 | +{ | |
| 1215 | + struct i7core_dev *i7core_dev, *tmp; | |
| 1216 | + | |
| 1217 | + list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) | |
| 1218 | + i7core_put_devices(i7core_dev); | |
| 1219 | +} | |
| 1220 | + | |
| 1221 | +static void __init i7core_xeon_pci_fixup(struct pci_id_table *table) | |
| 1222 | +{ | |
| 1223 | + struct pci_dev *pdev = NULL; | |
| 1224 | + int i; | |
| 1225 | + /* | |
| 1226 | + * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses | |
| 1227 | + * aren't announced by acpi. So, we need to use a legacy scan probing | |
| 1228 | + * to detect them | |
| 1229 | + */ | |
| 1230 | + while (table && table->descr) { | |
| 1231 | + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, table->descr[0].dev_id, NULL); | |
| 1232 | + if (unlikely(!pdev)) { | |
| 1233 | + for (i = 0; i < MAX_SOCKET_BUSES; i++) | |
| 1234 | + pcibios_scan_specific_bus(255-i); | |
| 1235 | + } | |
| 1236 | + table++; | |
| 1237 | + } | |
| 1238 | +} | |
| 1239 | + | |
| 1240 | +/* | |
| 1241 | + * i7core_get_devices Find and perform 'get' operation on the MCH's | |
| 1242 | + * device/functions we want to reference for this driver | |
| 1243 | + * | |
| 1244 | + * Need to 'get' device 16 func 1 and func 2 | |
| 1245 | + */ | |
| 1246 | +int i7core_get_onedevice(struct pci_dev **prev, int devno, | |
| 1247 | + struct pci_id_descr *dev_descr, unsigned n_devs) | |
| 1248 | +{ | |
| 1249 | + struct i7core_dev *i7core_dev; | |
| 1250 | + | |
| 1251 | + struct pci_dev *pdev = NULL; | |
| 1252 | + u8 bus = 0; | |
| 1253 | + u8 socket = 0; | |
| 1254 | + | |
| 1255 | + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | |
| 1256 | + dev_descr->dev_id, *prev); | |
| 1257 | + | |
| 1258 | + /* | |
| 1259 | + * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs | |
| 1260 | + * is at addr 8086:2c40, instead of 8086:2c41. So, we need | |
| 1261 | + * to probe for the alternate address in case of failure | |
| 1262 | + */ | |
| 1263 | + if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) | |
| 1264 | + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | |
| 1265 | + PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); | |
| 1266 | + | |
| 1267 | + if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) | |
| 1268 | + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | |
| 1269 | + PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, | |
| 1270 | + *prev); | |
| 1271 | + | |
| 1272 | + if (!pdev) { | |
| 1273 | + if (*prev) { | |
| 1274 | + *prev = pdev; | |
| 1275 | + return 0; | |
| 1276 | + } | |
| 1277 | + | |
| 1278 | + if (dev_descr->optional) | |
| 1279 | + return 0; | |
| 1280 | + | |
| 1281 | + if (devno == 0) | |
| 1282 | + return -ENODEV; | |
| 1283 | + | |
| 1284 | + i7core_printk(KERN_ERR, | |
| 1285 | + "Device not found: dev %02x.%d PCI ID %04x:%04x\n", | |
| 1286 | + dev_descr->dev, dev_descr->func, | |
| 1287 | + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | |
| 1288 | + | |
| 1289 | + /* End of list, leave */ | |
| 1290 | + return -ENODEV; | |
| 1291 | + } | |
| 1292 | + bus = pdev->bus->number; | |
| 1293 | + | |
| 1294 | + if (bus == 0x3f) | |
| 1295 | + socket = 0; | |
| 1296 | + else | |
| 1297 | + socket = 255 - bus; | |
| 1298 | + | |
| 1299 | + i7core_dev = get_i7core_dev(socket); | |
| 1300 | + if (!i7core_dev) { | |
| 1301 | + i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL); | |
| 1302 | + if (!i7core_dev) | |
| 1303 | + return -ENOMEM; | |
| 1304 | + i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * n_devs, | |
| 1305 | + GFP_KERNEL); | |
| 1306 | + if (!i7core_dev->pdev) { | |
| 1307 | + kfree(i7core_dev); | |
| 1308 | + return -ENOMEM; | |
| 1309 | + } | |
| 1310 | + i7core_dev->socket = socket; | |
| 1311 | + i7core_dev->n_devs = n_devs; | |
| 1312 | + list_add_tail(&i7core_dev->list, &i7core_edac_list); | |
| 1313 | + } | |
| 1314 | + | |
| 1315 | + if (i7core_dev->pdev[devno]) { | |
| 1316 | + i7core_printk(KERN_ERR, | |
| 1317 | + "Duplicated device for " | |
| 1318 | + "dev %02x:%02x.%d PCI ID %04x:%04x\n", | |
| 1319 | + bus, dev_descr->dev, dev_descr->func, | |
| 1320 | + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | |
| 1321 | + pci_dev_put(pdev); | |
| 1322 | + return -ENODEV; | |
| 1323 | + } | |
| 1324 | + | |
| 1325 | + i7core_dev->pdev[devno] = pdev; | |
| 1326 | + | |
| 1327 | + /* Sanity check */ | |
| 1328 | + if (unlikely(PCI_SLOT(pdev->devfn) != dev_descr->dev || | |
| 1329 | + PCI_FUNC(pdev->devfn) != dev_descr->func)) { | |
| 1330 | + i7core_printk(KERN_ERR, | |
| 1331 | + "Device PCI ID %04x:%04x " | |
| 1332 | + "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n", | |
| 1333 | + PCI_VENDOR_ID_INTEL, dev_descr->dev_id, | |
| 1334 | + bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | |
| 1335 | + bus, dev_descr->dev, dev_descr->func); | |
| 1336 | + return -ENODEV; | |
| 1337 | + } | |
| 1338 | + | |
| 1339 | + /* Be sure that the device is enabled */ | |
| 1340 | + if (unlikely(pci_enable_device(pdev) < 0)) { | |
| 1341 | + i7core_printk(KERN_ERR, | |
| 1342 | + "Couldn't enable " | |
| 1343 | + "dev %02x:%02x.%d PCI ID %04x:%04x\n", | |
| 1344 | + bus, dev_descr->dev, dev_descr->func, | |
| 1345 | + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | |
| 1346 | + return -ENODEV; | |
| 1347 | + } | |
| 1348 | + | |
| 1349 | + debugf0("Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n", | |
| 1350 | + socket, bus, dev_descr->dev, | |
| 1351 | + dev_descr->func, | |
| 1352 | + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | |
| 1353 | + | |
| 1354 | + *prev = pdev; | |
| 1355 | + | |
| 1356 | + return 0; | |
| 1357 | +} | |
| 1358 | + | |
| 1359 | +static int i7core_get_devices(struct pci_id_table *table) | |
| 1360 | +{ | |
| 1361 | + int i, rc; | |
| 1362 | + struct pci_dev *pdev = NULL; | |
| 1363 | + struct pci_id_descr *dev_descr; | |
| 1364 | + | |
| 1365 | + while (table && table->descr) { | |
| 1366 | + dev_descr = table->descr; | |
| 1367 | + for (i = 0; i < table->n_devs; i++) { | |
| 1368 | + pdev = NULL; | |
| 1369 | + do { | |
| 1370 | + rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], | |
| 1371 | + table->n_devs); | |
| 1372 | + if (rc < 0) { | |
| 1373 | + if (i == 0) { | |
| 1374 | + i = table->n_devs; | |
| 1375 | + break; | |
| 1376 | + } | |
| 1377 | + i7core_put_all_devices(); | |
| 1378 | + return -ENODEV; | |
| 1379 | + } | |
| 1380 | + } while (pdev); | |
| 1381 | + } | |
| 1382 | + table++; | |
| 1383 | + } | |
| 1384 | + | |
| 1385 | + return 0; | |
| 1386 | + return 0; | |
| 1387 | +} | |
| 1388 | + | |
| 1389 | +static int mci_bind_devs(struct mem_ctl_info *mci, | |
| 1390 | + struct i7core_dev *i7core_dev) | |
| 1391 | +{ | |
| 1392 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1393 | + struct pci_dev *pdev; | |
| 1394 | + int i, func, slot; | |
| 1395 | + | |
| 1396 | + /* Associates i7core_dev and mci for future usage */ | |
| 1397 | + pvt->i7core_dev = i7core_dev; | |
| 1398 | + i7core_dev->mci = mci; | |
| 1399 | + | |
| 1400 | + pvt->is_registered = 0; | |
| 1401 | + for (i = 0; i < i7core_dev->n_devs; i++) { | |
| 1402 | + pdev = i7core_dev->pdev[i]; | |
| 1403 | + if (!pdev) | |
| 1404 | + continue; | |
| 1405 | + | |
| 1406 | + func = PCI_FUNC(pdev->devfn); | |
| 1407 | + slot = PCI_SLOT(pdev->devfn); | |
| 1408 | + if (slot == 3) { | |
| 1409 | + if (unlikely(func > MAX_MCR_FUNC)) | |
| 1410 | + goto error; | |
| 1411 | + pvt->pci_mcr[func] = pdev; | |
| 1412 | + } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) { | |
| 1413 | + if (unlikely(func > MAX_CHAN_FUNC)) | |
| 1414 | + goto error; | |
| 1415 | + pvt->pci_ch[slot - 4][func] = pdev; | |
| 1416 | + } else if (!slot && !func) | |
| 1417 | + pvt->pci_noncore = pdev; | |
| 1418 | + else | |
| 1419 | + goto error; | |
| 1420 | + | |
| 1421 | + debugf0("Associated fn %d.%d, dev = %p, socket %d\n", | |
| 1422 | + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | |
| 1423 | + pdev, i7core_dev->socket); | |
| 1424 | + | |
| 1425 | + if (PCI_SLOT(pdev->devfn) == 3 && | |
| 1426 | + PCI_FUNC(pdev->devfn) == 2) | |
| 1427 | + pvt->is_registered = 1; | |
| 1428 | + } | |
| 1429 | + | |
| 1430 | + /* | |
| 1431 | + * Add extra nodes to count errors on udimm | |
| 1432 | + * For registered memory, this is not needed, since the counters | |
| 1433 | + * are already displayed at the standard locations | |
| 1434 | + */ | |
| 1435 | + if (!pvt->is_registered) | |
| 1436 | + i7core_sysfs_attrs[ARRAY_SIZE(i7core_sysfs_attrs)-2].grp = | |
| 1437 | + &i7core_udimm_counters; | |
| 1438 | + | |
| 1439 | + return 0; | |
| 1440 | + | |
| 1441 | +error: | |
| 1442 | + i7core_printk(KERN_ERR, "Device %d, function %d " | |
| 1443 | + "is out of the expected range\n", | |
| 1444 | + slot, func); | |
| 1445 | + return -EINVAL; | |
| 1446 | +} | |
| 1447 | + | |
| 1448 | +/**************************************************************************** | |
| 1449 | + Error check routines | |
| 1450 | + ****************************************************************************/ | |
| 1451 | +static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci, | |
| 1452 | + int chan, int dimm, int add) | |
| 1453 | +{ | |
| 1454 | + char *msg; | |
| 1455 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1456 | + int row = pvt->csrow_map[chan][dimm], i; | |
| 1457 | + | |
| 1458 | + for (i = 0; i < add; i++) { | |
| 1459 | + msg = kasprintf(GFP_KERNEL, "Corrected error " | |
| 1460 | + "(Socket=%d channel=%d dimm=%d)", | |
| 1461 | + pvt->i7core_dev->socket, chan, dimm); | |
| 1462 | + | |
| 1463 | + edac_mc_handle_fbd_ce(mci, row, 0, msg); | |
| 1464 | + kfree (msg); | |
| 1465 | + } | |
| 1466 | +} | |
| 1467 | + | |
| 1468 | +static void i7core_rdimm_update_ce_count(struct mem_ctl_info *mci, | |
| 1469 | + int chan, int new0, int new1, int new2) | |
| 1470 | +{ | |
| 1471 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1472 | + int add0 = 0, add1 = 0, add2 = 0; | |
| 1473 | + /* Updates CE counters if it is not the first time here */ | |
| 1474 | + if (pvt->ce_count_available) { | |
| 1475 | + /* Updates CE counters */ | |
| 1476 | + | |
| 1477 | + add2 = new2 - pvt->rdimm_last_ce_count[chan][2]; | |
| 1478 | + add1 = new1 - pvt->rdimm_last_ce_count[chan][1]; | |
| 1479 | + add0 = new0 - pvt->rdimm_last_ce_count[chan][0]; | |
| 1480 | + | |
| 1481 | + if (add2 < 0) | |
| 1482 | + add2 += 0x7fff; | |
| 1483 | + pvt->rdimm_ce_count[chan][2] += add2; | |
| 1484 | + | |
| 1485 | + if (add1 < 0) | |
| 1486 | + add1 += 0x7fff; | |
| 1487 | + pvt->rdimm_ce_count[chan][1] += add1; | |
| 1488 | + | |
| 1489 | + if (add0 < 0) | |
| 1490 | + add0 += 0x7fff; | |
| 1491 | + pvt->rdimm_ce_count[chan][0] += add0; | |
| 1492 | + } else | |
| 1493 | + pvt->ce_count_available = 1; | |
| 1494 | + | |
| 1495 | + /* Store the new values */ | |
| 1496 | + pvt->rdimm_last_ce_count[chan][2] = new2; | |
| 1497 | + pvt->rdimm_last_ce_count[chan][1] = new1; | |
| 1498 | + pvt->rdimm_last_ce_count[chan][0] = new0; | |
| 1499 | + | |
| 1500 | + /*updated the edac core */ | |
| 1501 | + if (add0 != 0) | |
| 1502 | + i7core_rdimm_update_csrow(mci, chan, 0, add0); | |
| 1503 | + if (add1 != 0) | |
| 1504 | + i7core_rdimm_update_csrow(mci, chan, 1, add1); | |
| 1505 | + if (add2 != 0) | |
| 1506 | + i7core_rdimm_update_csrow(mci, chan, 2, add2); | |
| 1507 | + | |
| 1508 | +} | |
| 1509 | + | |
| 1510 | +static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci) | |
| 1511 | +{ | |
| 1512 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1513 | + u32 rcv[3][2]; | |
| 1514 | + int i, new0, new1, new2; | |
| 1515 | + | |
| 1516 | + /*Read DEV 3: FUN 2: MC_COR_ECC_CNT regs directly*/ | |
| 1517 | + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_0, | |
| 1518 | + &rcv[0][0]); | |
| 1519 | + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_1, | |
| 1520 | + &rcv[0][1]); | |
| 1521 | + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_2, | |
| 1522 | + &rcv[1][0]); | |
| 1523 | + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_3, | |
| 1524 | + &rcv[1][1]); | |
| 1525 | + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_4, | |
| 1526 | + &rcv[2][0]); | |
| 1527 | + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_5, | |
| 1528 | + &rcv[2][1]); | |
| 1529 | + for (i = 0 ; i < 3; i++) { | |
| 1530 | + debugf3("MC_COR_ECC_CNT%d = 0x%x; MC_COR_ECC_CNT%d = 0x%x\n", | |
| 1531 | + (i * 2), rcv[i][0], (i * 2) + 1, rcv[i][1]); | |
| 1532 | + /*if the channel has 3 dimms*/ | |
| 1533 | + if (pvt->channel[i].dimms > 2) { | |
| 1534 | + new0 = DIMM_BOT_COR_ERR(rcv[i][0]); | |
| 1535 | + new1 = DIMM_TOP_COR_ERR(rcv[i][0]); | |
| 1536 | + new2 = DIMM_BOT_COR_ERR(rcv[i][1]); | |
| 1537 | + } else { | |
| 1538 | + new0 = DIMM_TOP_COR_ERR(rcv[i][0]) + | |
| 1539 | + DIMM_BOT_COR_ERR(rcv[i][0]); | |
| 1540 | + new1 = DIMM_TOP_COR_ERR(rcv[i][1]) + | |
| 1541 | + DIMM_BOT_COR_ERR(rcv[i][1]); | |
| 1542 | + new2 = 0; | |
| 1543 | + } | |
| 1544 | + | |
| 1545 | + i7core_rdimm_update_ce_count(mci, i, new0, new1, new2); | |
| 1546 | + } | |
| 1547 | +} | |
| 1548 | + | |
| 1549 | +/* This function is based on the device 3 function 4 registers as described on: | |
| 1550 | + * Intel Xeon Processor 5500 Series Datasheet Volume 2 | |
| 1551 | + * http://www.intel.com/Assets/PDF/datasheet/321322.pdf | |
| 1552 | + * also available at: | |
| 1553 | + * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf | |
| 1554 | + */ | |
| 1555 | +static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info *mci) | |
| 1556 | +{ | |
| 1557 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1558 | + u32 rcv1, rcv0; | |
| 1559 | + int new0, new1, new2; | |
| 1560 | + | |
| 1561 | + if (!pvt->pci_mcr[4]) { | |
| 1562 | + debugf0("%s MCR registers not found\n", __func__); | |
| 1563 | + return; | |
| 1564 | + } | |
| 1565 | + | |
| 1566 | + /* Corrected test errors */ | |
| 1567 | + pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1); | |
| 1568 | + pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0); | |
| 1569 | + | |
| 1570 | + /* Store the new values */ | |
| 1571 | + new2 = DIMM2_COR_ERR(rcv1); | |
| 1572 | + new1 = DIMM1_COR_ERR(rcv0); | |
| 1573 | + new0 = DIMM0_COR_ERR(rcv0); | |
| 1574 | + | |
| 1575 | + /* Updates CE counters if it is not the first time here */ | |
| 1576 | + if (pvt->ce_count_available) { | |
| 1577 | + /* Updates CE counters */ | |
| 1578 | + int add0, add1, add2; | |
| 1579 | + | |
| 1580 | + add2 = new2 - pvt->udimm_last_ce_count[2]; | |
| 1581 | + add1 = new1 - pvt->udimm_last_ce_count[1]; | |
| 1582 | + add0 = new0 - pvt->udimm_last_ce_count[0]; | |
| 1583 | + | |
| 1584 | + if (add2 < 0) | |
| 1585 | + add2 += 0x7fff; | |
| 1586 | + pvt->udimm_ce_count[2] += add2; | |
| 1587 | + | |
| 1588 | + if (add1 < 0) | |
| 1589 | + add1 += 0x7fff; | |
| 1590 | + pvt->udimm_ce_count[1] += add1; | |
| 1591 | + | |
| 1592 | + if (add0 < 0) | |
| 1593 | + add0 += 0x7fff; | |
| 1594 | + pvt->udimm_ce_count[0] += add0; | |
| 1595 | + | |
| 1596 | + if (add0 | add1 | add2) | |
| 1597 | + i7core_printk(KERN_ERR, "New Corrected error(s): " | |
| 1598 | + "dimm0: +%d, dimm1: +%d, dimm2 +%d\n", | |
| 1599 | + add0, add1, add2); | |
| 1600 | + } else | |
| 1601 | + pvt->ce_count_available = 1; | |
| 1602 | + | |
| 1603 | + /* Store the new values */ | |
| 1604 | + pvt->udimm_last_ce_count[2] = new2; | |
| 1605 | + pvt->udimm_last_ce_count[1] = new1; | |
| 1606 | + pvt->udimm_last_ce_count[0] = new0; | |
| 1607 | +} | |
| 1608 | + | |
| 1609 | +/* | |
| 1610 | + * According with tables E-11 and E-12 of chapter E.3.3 of Intel 64 and IA-32 | |
| 1611 | + * Architectures Software Developer’s Manual Volume 3B. | |
| 1612 | + * Nehalem are defined as family 0x06, model 0x1a | |
| 1613 | + * | |
| 1614 | + * The MCA registers used here are the following ones: | |
| 1615 | + * struct mce field MCA Register | |
| 1616 | + * m->status MSR_IA32_MC8_STATUS | |
| 1617 | + * m->addr MSR_IA32_MC8_ADDR | |
| 1618 | + * m->misc MSR_IA32_MC8_MISC | |
| 1619 | + * In the case of Nehalem, the error information is masked at .status and .misc | |
| 1620 | + * fields | |
| 1621 | + */ | |
| 1622 | +static void i7core_mce_output_error(struct mem_ctl_info *mci, | |
| 1623 | + struct mce *m) | |
| 1624 | +{ | |
| 1625 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1626 | + char *type, *optype, *err, *msg; | |
| 1627 | + unsigned long error = m->status & 0x1ff0000l; | |
| 1628 | + u32 optypenum = (m->status >> 4) & 0x07; | |
| 1629 | + u32 core_err_cnt = (m->status >> 38) && 0x7fff; | |
| 1630 | + u32 dimm = (m->misc >> 16) & 0x3; | |
| 1631 | + u32 channel = (m->misc >> 18) & 0x3; | |
| 1632 | + u32 syndrome = m->misc >> 32; | |
| 1633 | + u32 errnum = find_first_bit(&error, 32); | |
| 1634 | + int csrow; | |
| 1635 | + | |
| 1636 | + if (m->mcgstatus & 1) | |
| 1637 | + type = "FATAL"; | |
| 1638 | + else | |
| 1639 | + type = "NON_FATAL"; | |
| 1640 | + | |
| 1641 | + switch (optypenum) { | |
| 1642 | + case 0: | |
| 1643 | + optype = "generic undef request"; | |
| 1644 | + break; | |
| 1645 | + case 1: | |
| 1646 | + optype = "read error"; | |
| 1647 | + break; | |
| 1648 | + case 2: | |
| 1649 | + optype = "write error"; | |
| 1650 | + break; | |
| 1651 | + case 3: | |
| 1652 | + optype = "addr/cmd error"; | |
| 1653 | + break; | |
| 1654 | + case 4: | |
| 1655 | + optype = "scrubbing error"; | |
| 1656 | + break; | |
| 1657 | + default: | |
| 1658 | + optype = "reserved"; | |
| 1659 | + break; | |
| 1660 | + } | |
| 1661 | + | |
| 1662 | + switch (errnum) { | |
| 1663 | + case 16: | |
| 1664 | + err = "read ECC error"; | |
| 1665 | + break; | |
| 1666 | + case 17: | |
| 1667 | + err = "RAS ECC error"; | |
| 1668 | + break; | |
| 1669 | + case 18: | |
| 1670 | + err = "write parity error"; | |
| 1671 | + break; | |
| 1672 | + case 19: | |
| 1673 | + err = "redundacy loss"; | |
| 1674 | + break; | |
| 1675 | + case 20: | |
| 1676 | + err = "reserved"; | |
| 1677 | + break; | |
| 1678 | + case 21: | |
| 1679 | + err = "memory range error"; | |
| 1680 | + break; | |
| 1681 | + case 22: | |
| 1682 | + err = "RTID out of range"; | |
| 1683 | + break; | |
| 1684 | + case 23: | |
| 1685 | + err = "address parity error"; | |
| 1686 | + break; | |
| 1687 | + case 24: | |
| 1688 | + err = "byte enable parity error"; | |
| 1689 | + break; | |
| 1690 | + default: | |
| 1691 | + err = "unknown"; | |
| 1692 | + } | |
| 1693 | + | |
| 1694 | + /* FIXME: should convert addr into bank and rank information */ | |
| 1695 | + msg = kasprintf(GFP_ATOMIC, | |
| 1696 | + "%s (addr = 0x%08llx, cpu=%d, Dimm=%d, Channel=%d, " | |
| 1697 | + "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", | |
| 1698 | + type, (long long) m->addr, m->cpu, dimm, channel, | |
| 1699 | + syndrome, core_err_cnt, (long long)m->status, | |
| 1700 | + (long long)m->misc, optype, err); | |
| 1701 | + | |
| 1702 | + debugf0("%s", msg); | |
| 1703 | + | |
| 1704 | + csrow = pvt->csrow_map[channel][dimm]; | |
| 1705 | + | |
| 1706 | + /* Call the helper to output message */ | |
| 1707 | + if (m->mcgstatus & 1) | |
| 1708 | + edac_mc_handle_fbd_ue(mci, csrow, 0, | |
| 1709 | + 0 /* FIXME: should be channel here */, msg); | |
| 1710 | + else if (!pvt->is_registered) | |
| 1711 | + edac_mc_handle_fbd_ce(mci, csrow, | |
| 1712 | + 0 /* FIXME: should be channel here */, msg); | |
| 1713 | + | |
| 1714 | + kfree(msg); | |
| 1715 | +} | |
| 1716 | + | |
| 1717 | +/* | |
| 1718 | + * i7core_check_error Retrieve and process errors reported by the | |
| 1719 | + * hardware. Called by the Core module. | |
| 1720 | + */ | |
| 1721 | +static void i7core_check_error(struct mem_ctl_info *mci) | |
| 1722 | +{ | |
| 1723 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1724 | + int i; | |
| 1725 | + unsigned count = 0; | |
| 1726 | + struct mce *m; | |
| 1727 | + | |
| 1728 | + /* | |
| 1729 | + * MCE first step: Copy all mce errors into a temporary buffer | |
| 1730 | + * We use a double buffering here, to reduce the risk of | |
| 1731 | + * loosing an error. | |
| 1732 | + */ | |
| 1733 | + smp_rmb(); | |
| 1734 | + count = (pvt->mce_out + MCE_LOG_LEN - pvt->mce_in) | |
| 1735 | + % MCE_LOG_LEN; | |
| 1736 | + if (!count) | |
| 1737 | + goto check_ce_error; | |
| 1738 | + | |
| 1739 | + m = pvt->mce_outentry; | |
| 1740 | + if (pvt->mce_in + count > MCE_LOG_LEN) { | |
| 1741 | + unsigned l = MCE_LOG_LEN - pvt->mce_in; | |
| 1742 | + | |
| 1743 | + memcpy(m, &pvt->mce_entry[pvt->mce_in], sizeof(*m) * l); | |
| 1744 | + smp_wmb(); | |
| 1745 | + pvt->mce_in = 0; | |
| 1746 | + count -= l; | |
| 1747 | + m += l; | |
| 1748 | + } | |
| 1749 | + memcpy(m, &pvt->mce_entry[pvt->mce_in], sizeof(*m) * count); | |
| 1750 | + smp_wmb(); | |
| 1751 | + pvt->mce_in += count; | |
| 1752 | + | |
| 1753 | + smp_rmb(); | |
| 1754 | + if (pvt->mce_overrun) { | |
| 1755 | + i7core_printk(KERN_ERR, "Lost %d memory errors\n", | |
| 1756 | + pvt->mce_overrun); | |
| 1757 | + smp_wmb(); | |
| 1758 | + pvt->mce_overrun = 0; | |
| 1759 | + } | |
| 1760 | + | |
| 1761 | + /* | |
| 1762 | + * MCE second step: parse errors and display | |
| 1763 | + */ | |
| 1764 | + for (i = 0; i < count; i++) | |
| 1765 | + i7core_mce_output_error(mci, &pvt->mce_outentry[i]); | |
| 1766 | + | |
| 1767 | + /* | |
| 1768 | + * Now, let's increment CE error counts | |
| 1769 | + */ | |
| 1770 | +check_ce_error: | |
| 1771 | + if (!pvt->is_registered) | |
| 1772 | + i7core_udimm_check_mc_ecc_err(mci); | |
| 1773 | + else | |
| 1774 | + i7core_rdimm_check_mc_ecc_err(mci); | |
| 1775 | +} | |
| 1776 | + | |
| 1777 | +/* | |
| 1778 | + * i7core_mce_check_error Replicates mcelog routine to get errors | |
| 1779 | + * This routine simply queues mcelog errors, and | |
| 1780 | + * return. The error itself should be handled later | |
| 1781 | + * by i7core_check_error. | |
| 1782 | + * WARNING: As this routine should be called at NMI time, extra care should | |
| 1783 | + * be taken to avoid deadlocks, and to be as fast as possible. | |
| 1784 | + */ | |
| 1785 | +static int i7core_mce_check_error(void *priv, struct mce *mce) | |
| 1786 | +{ | |
| 1787 | + struct mem_ctl_info *mci = priv; | |
| 1788 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 1789 | + | |
| 1790 | + /* | |
| 1791 | + * Just let mcelog handle it if the error is | |
| 1792 | + * outside the memory controller | |
| 1793 | + */ | |
| 1794 | + if (((mce->status & 0xffff) >> 7) != 1) | |
| 1795 | + return 0; | |
| 1796 | + | |
| 1797 | + /* Bank 8 registers are the only ones that we know how to handle */ | |
| 1798 | + if (mce->bank != 8) | |
| 1799 | + return 0; | |
| 1800 | + | |
| 1801 | +#ifdef CONFIG_SMP | |
| 1802 | + /* Only handle if it is the right mc controller */ | |
| 1803 | + if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) | |
| 1804 | + return 0; | |
| 1805 | +#endif | |
| 1806 | + | |
| 1807 | + smp_rmb(); | |
| 1808 | + if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { | |
| 1809 | + smp_wmb(); | |
| 1810 | + pvt->mce_overrun++; | |
| 1811 | + return 0; | |
| 1812 | + } | |
| 1813 | + | |
| 1814 | + /* Copy memory error at the ringbuffer */ | |
| 1815 | + memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce)); | |
| 1816 | + smp_wmb(); | |
| 1817 | + pvt->mce_out = (pvt->mce_out + 1) % MCE_LOG_LEN; | |
| 1818 | + | |
| 1819 | + /* Handle fatal errors immediately */ | |
| 1820 | + if (mce->mcgstatus & 1) | |
| 1821 | + i7core_check_error(mci); | |
| 1822 | + | |
| 1823 | + /* Advice mcelog that the error were handled */ | |
| 1824 | + return 1; | |
| 1825 | +} | |
| 1826 | + | |
| 1827 | +static int i7core_register_mci(struct i7core_dev *i7core_dev, | |
| 1828 | + int num_channels, int num_csrows) | |
| 1829 | +{ | |
| 1830 | + struct mem_ctl_info *mci; | |
| 1831 | + struct i7core_pvt *pvt; | |
| 1832 | + int csrow = 0; | |
| 1833 | + int rc; | |
| 1834 | + | |
| 1835 | + /* allocate a new MC control structure */ | |
| 1836 | + mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, | |
| 1837 | + i7core_dev->socket); | |
| 1838 | + if (unlikely(!mci)) | |
| 1839 | + return -ENOMEM; | |
| 1840 | + | |
| 1841 | + debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); | |
| 1842 | + | |
| 1843 | + /* record ptr to the generic device */ | |
| 1844 | + mci->dev = &i7core_dev->pdev[0]->dev; | |
| 1845 | + | |
| 1846 | + pvt = mci->pvt_info; | |
| 1847 | + memset(pvt, 0, sizeof(*pvt)); | |
| 1848 | + | |
| 1849 | + /* | |
| 1850 | + * FIXME: how to handle RDDR3 at MCI level? It is possible to have | |
| 1851 | + * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different | |
| 1852 | + * memory channels | |
| 1853 | + */ | |
| 1854 | + mci->mtype_cap = MEM_FLAG_DDR3; | |
| 1855 | + mci->edac_ctl_cap = EDAC_FLAG_NONE; | |
| 1856 | + mci->edac_cap = EDAC_FLAG_NONE; | |
| 1857 | + mci->mod_name = "i7core_edac.c"; | |
| 1858 | + mci->mod_ver = I7CORE_REVISION; | |
| 1859 | + mci->ctl_name = kasprintf(GFP_KERNEL, "i7 core #%d", | |
| 1860 | + i7core_dev->socket); | |
| 1861 | + mci->dev_name = pci_name(i7core_dev->pdev[0]); | |
| 1862 | + mci->ctl_page_to_phys = NULL; | |
| 1863 | + mci->mc_driver_sysfs_attributes = i7core_sysfs_attrs; | |
| 1864 | + /* Set the function pointer to an actual operation function */ | |
| 1865 | + mci->edac_check = i7core_check_error; | |
| 1866 | + | |
| 1867 | + /* Store pci devices at mci for faster access */ | |
| 1868 | + rc = mci_bind_devs(mci, i7core_dev); | |
| 1869 | + if (unlikely(rc < 0)) | |
| 1870 | + goto fail; | |
| 1871 | + | |
| 1872 | + /* Get dimm basic config */ | |
| 1873 | + get_dimm_config(mci, &csrow); | |
| 1874 | + | |
| 1875 | + /* add this new MC control structure to EDAC's list of MCs */ | |
| 1876 | + if (unlikely(edac_mc_add_mc(mci))) { | |
| 1877 | + debugf0("MC: " __FILE__ | |
| 1878 | + ": %s(): failed edac_mc_add_mc()\n", __func__); | |
| 1879 | + /* FIXME: perhaps some code should go here that disables error | |
| 1880 | + * reporting if we just enabled it | |
| 1881 | + */ | |
| 1882 | + | |
| 1883 | + rc = -EINVAL; | |
| 1884 | + goto fail; | |
| 1885 | + } | |
| 1886 | + | |
| 1887 | + /* allocating generic PCI control info */ | |
| 1888 | + i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev, | |
| 1889 | + EDAC_MOD_STR); | |
| 1890 | + if (unlikely(!i7core_pci)) { | |
| 1891 | + printk(KERN_WARNING | |
| 1892 | + "%s(): Unable to create PCI control\n", | |
| 1893 | + __func__); | |
| 1894 | + printk(KERN_WARNING | |
| 1895 | + "%s(): PCI error report via EDAC not setup\n", | |
| 1896 | + __func__); | |
| 1897 | + } | |
| 1898 | + | |
| 1899 | + /* Default error mask is any memory */ | |
| 1900 | + pvt->inject.channel = 0; | |
| 1901 | + pvt->inject.dimm = -1; | |
| 1902 | + pvt->inject.rank = -1; | |
| 1903 | + pvt->inject.bank = -1; | |
| 1904 | + pvt->inject.page = -1; | |
| 1905 | + pvt->inject.col = -1; | |
| 1906 | + | |
| 1907 | + /* Registers on edac_mce in order to receive memory errors */ | |
| 1908 | + pvt->edac_mce.priv = mci; | |
| 1909 | + pvt->edac_mce.check_error = i7core_mce_check_error; | |
| 1910 | + | |
| 1911 | + rc = edac_mce_register(&pvt->edac_mce); | |
| 1912 | + if (unlikely(rc < 0)) { | |
| 1913 | + debugf0("MC: " __FILE__ | |
| 1914 | + ": %s(): failed edac_mce_register()\n", __func__); | |
| 1915 | + } | |
| 1916 | + | |
| 1917 | +fail: | |
| 1918 | + if (rc < 0) | |
| 1919 | + edac_mc_free(mci); | |
| 1920 | + return rc; | |
| 1921 | +} | |
| 1922 | + | |
| 1923 | +/* | |
| 1924 | + * i7core_probe Probe for ONE instance of device to see if it is | |
| 1925 | + * present. | |
| 1926 | + * return: | |
| 1927 | + * 0 for FOUND a device | |
| 1928 | + * < 0 for error code | |
| 1929 | + */ | |
| 1930 | +static int __devinit i7core_probe(struct pci_dev *pdev, | |
| 1931 | + const struct pci_device_id *id) | |
| 1932 | +{ | |
| 1933 | + int dev_idx = id->driver_data; | |
| 1934 | + int rc; | |
| 1935 | + struct i7core_dev *i7core_dev; | |
| 1936 | + | |
| 1937 | + /* | |
| 1938 | + * All memory controllers are allocated at the first pass. | |
| 1939 | + */ | |
| 1940 | + if (unlikely(dev_idx >= 1)) | |
| 1941 | + return -EINVAL; | |
| 1942 | + | |
| 1943 | + /* get the pci devices we want to reserve for our use */ | |
| 1944 | + mutex_lock(&i7core_edac_lock); | |
| 1945 | + | |
| 1946 | + rc = i7core_get_devices(pci_dev_table); | |
| 1947 | + if (unlikely(rc < 0)) | |
| 1948 | + goto fail0; | |
| 1949 | + | |
| 1950 | + list_for_each_entry(i7core_dev, &i7core_edac_list, list) { | |
| 1951 | + int channels; | |
| 1952 | + int csrows; | |
| 1953 | + | |
| 1954 | + /* Check the number of active and not disabled channels */ | |
| 1955 | + rc = i7core_get_active_channels(i7core_dev->socket, | |
| 1956 | + &channels, &csrows); | |
| 1957 | + if (unlikely(rc < 0)) | |
| 1958 | + goto fail1; | |
| 1959 | + | |
| 1960 | + rc = i7core_register_mci(i7core_dev, channels, csrows); | |
| 1961 | + if (unlikely(rc < 0)) | |
| 1962 | + goto fail1; | |
| 1963 | + } | |
| 1964 | + | |
| 1965 | + i7core_printk(KERN_INFO, "Driver loaded.\n"); | |
| 1966 | + | |
| 1967 | + mutex_unlock(&i7core_edac_lock); | |
| 1968 | + return 0; | |
| 1969 | + | |
| 1970 | +fail1: | |
| 1971 | + i7core_put_all_devices(); | |
| 1972 | +fail0: | |
| 1973 | + mutex_unlock(&i7core_edac_lock); | |
| 1974 | + return rc; | |
| 1975 | +} | |
| 1976 | + | |
| 1977 | +/* | |
| 1978 | + * i7core_remove destructor for one instance of device | |
| 1979 | + * | |
| 1980 | + */ | |
| 1981 | +static void __devexit i7core_remove(struct pci_dev *pdev) | |
| 1982 | +{ | |
| 1983 | + struct mem_ctl_info *mci; | |
| 1984 | + struct i7core_dev *i7core_dev, *tmp; | |
| 1985 | + | |
| 1986 | + debugf0(__FILE__ ": %s()\n", __func__); | |
| 1987 | + | |
| 1988 | + if (i7core_pci) | |
| 1989 | + edac_pci_release_generic_ctl(i7core_pci); | |
| 1990 | + | |
| 1991 | + /* | |
| 1992 | + * we have a trouble here: pdev value for removal will be wrong, since | |
| 1993 | + * it will point to the X58 register used to detect that the machine | |
| 1994 | + * is a Nehalem or upper design. However, due to the way several PCI | |
| 1995 | + * devices are grouped together to provide MC functionality, we need | |
| 1996 | + * to use a different method for releasing the devices | |
| 1997 | + */ | |
| 1998 | + | |
| 1999 | + mutex_lock(&i7core_edac_lock); | |
| 2000 | + list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) { | |
| 2001 | + mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev); | |
| 2002 | + if (mci) { | |
| 2003 | + struct i7core_pvt *pvt = mci->pvt_info; | |
| 2004 | + | |
| 2005 | + i7core_dev = pvt->i7core_dev; | |
| 2006 | + edac_mce_unregister(&pvt->edac_mce); | |
| 2007 | + kfree(mci->ctl_name); | |
| 2008 | + edac_mc_free(mci); | |
| 2009 | + i7core_put_devices(i7core_dev); | |
| 2010 | + } else { | |
| 2011 | + i7core_printk(KERN_ERR, | |
| 2012 | + "Couldn't find mci for socket %d\n", | |
| 2013 | + i7core_dev->socket); | |
| 2014 | + } | |
| 2015 | + } | |
| 2016 | + mutex_unlock(&i7core_edac_lock); | |
| 2017 | +} | |
| 2018 | + | |
| 2019 | +MODULE_DEVICE_TABLE(pci, i7core_pci_tbl); | |
| 2020 | + | |
| 2021 | +/* | |
| 2022 | + * i7core_driver pci_driver structure for this module | |
| 2023 | + * | |
| 2024 | + */ | |
| 2025 | +static struct pci_driver i7core_driver = { | |
| 2026 | + .name = "i7core_edac", | |
| 2027 | + .probe = i7core_probe, | |
| 2028 | + .remove = __devexit_p(i7core_remove), | |
| 2029 | + .id_table = i7core_pci_tbl, | |
| 2030 | +}; | |
| 2031 | + | |
| 2032 | +/* | |
| 2033 | + * i7core_init Module entry function | |
| 2034 | + * Try to initialize this module for its devices | |
| 2035 | + */ | |
| 2036 | +static int __init i7core_init(void) | |
| 2037 | +{ | |
| 2038 | + int pci_rc; | |
| 2039 | + | |
| 2040 | + debugf2("MC: " __FILE__ ": %s()\n", __func__); | |
| 2041 | + | |
| 2042 | + /* Ensure that the OPSTATE is set correctly for POLL or NMI */ | |
| 2043 | + opstate_init(); | |
| 2044 | + | |
| 2045 | + i7core_xeon_pci_fixup(pci_dev_table); | |
| 2046 | + | |
| 2047 | + pci_rc = pci_register_driver(&i7core_driver); | |
| 2048 | + | |
| 2049 | + if (pci_rc >= 0) | |
| 2050 | + return 0; | |
| 2051 | + | |
| 2052 | + i7core_printk(KERN_ERR, "Failed to register device with error %d.\n", | |
| 2053 | + pci_rc); | |
| 2054 | + | |
| 2055 | + return pci_rc; | |
| 2056 | +} | |
| 2057 | + | |
| 2058 | +/* | |
| 2059 | + * i7core_exit() Module exit function | |
| 2060 | + * Unregister the driver | |
| 2061 | + */ | |
| 2062 | +static void __exit i7core_exit(void) | |
| 2063 | +{ | |
| 2064 | + debugf2("MC: " __FILE__ ": %s()\n", __func__); | |
| 2065 | + pci_unregister_driver(&i7core_driver); | |
| 2066 | +} | |
| 2067 | + | |
| 2068 | +module_init(i7core_init); | |
| 2069 | +module_exit(i7core_exit); | |
| 2070 | + | |
| 2071 | +MODULE_LICENSE("GPL"); | |
| 2072 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | |
| 2073 | +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); | |
| 2074 | +MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - " | |
| 2075 | + I7CORE_REVISION); | |
| 2076 | + | |
| 2077 | +module_param(edac_op_state, int, 0444); | |
| 2078 | +MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); | |
| @@ -229,7 +229,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op, · 228 unmodified lines | ||
| 229 | 229 | |
| 230 | 230 | pdata->edac_idx = edac_pci_idx++; |
| 231 | 231 | |
| 232 | − res = of_address_to_resource(op->node, 0, &r); | |
| 232 | + res = of_address_to_resource(op->dev.of_node, 0, &r); | |
| 233 | 233 | if (res) { |
| 234 | 234 | printk(KERN_ERR "%s: Unable to get resource for " |
| 235 | 235 | "PCI err regs\n", __func__); |
| @@ -274,7 +274,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op, · 38 unmodified lines | ||
| 274 | 274 | } |
| 275 | 275 | |
| 276 | 276 | if (edac_op_state == EDAC_OPSTATE_INT) { |
| 277 | − pdata->irq = irq_of_parse_and_map(op->node, 0); | |
| 277 | + pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0); | |
| 278 | 278 | res = devm_request_irq(&op->dev, pdata->irq, |
| 279 | 279 | mpc85xx_pci_isr, IRQF_DISABLED, |
| 280 | 280 | "[EDAC] PCI err", pci); |
| @@ -529,7 +529,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op, · 248 unmodified lines | ||
| 529 | 529 | edac_dev->ctl_name = pdata->name; |
| 530 | 530 | edac_dev->dev_name = pdata->name; |
| 531 | 531 | |
| 532 | − res = of_address_to_resource(op->node, 0, &r); | |
| 532 | + res = of_address_to_resource(op->dev.of_node, 0, &r); | |
| 533 | 533 | if (res) { |
| 534 | 534 | printk(KERN_ERR "%s: Unable to get resource for " |
| 535 | 535 | "L2 err regs\n", __func__); |
| @@ -576,7 +576,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op, · 40 unmodified lines | ||
| 576 | 576 | } |
| 577 | 577 | |
| 578 | 578 | if (edac_op_state == EDAC_OPSTATE_INT) { |
| 579 | − pdata->irq = irq_of_parse_and_map(op->node, 0); | |
| 579 | + pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0); | |
| 580 | 580 | res = devm_request_irq(&op->dev, pdata->irq, |
| 581 | 581 | mpc85xx_l2_isr, IRQF_DISABLED, |
| 582 | 582 | "[EDAC] L2 err", edac_dev); |
| @@ -978,7 +978,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op, · 395 unmodified lines | ||
| 978 | 978 | mci->ctl_name = pdata->name; |
| 979 | 979 | mci->dev_name = pdata->name; |
| 980 | 980 | |
| 981 | − res = of_address_to_resource(op->node, 0, &r); | |
| 981 | + res = of_address_to_resource(op->dev.of_node, 0, &r); | |
| 982 | 982 | if (res) { |
| 983 | 983 | printk(KERN_ERR "%s: Unable to get resource for MC err regs\n", |
| 984 | 984 | __func__); |
| @@ -1052,7 +1052,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op, · 67 unmodified lines | ||
| 1052 | 1052 | out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000); |
| 1053 | 1053 | |
| 1054 | 1054 | /* register interrupts */ |
| 1055 | − pdata->irq = irq_of_parse_and_map(op->node, 0); | |
| 1055 | + pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0); | |
| 1056 | 1056 | res = devm_request_irq(&op->dev, pdata->irq, |
| 1057 | 1057 | mpc85xx_mc_isr, |
| 1058 | 1058 | IRQF_DISABLED | IRQF_SHARED, |
| @@ -1022,7 +1022,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci, · 1021 unmodified lines | ||
| 1022 | 1022 | int status = 0; |
| 1023 | 1023 | const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK); |
| 1024 | 1024 | struct ppc4xx_edac_pdata *pdata = NULL; |
| 1025 | − const struct device_node *np = op->node; | |
| 1025 | + const struct device_node *np = op->dev.of_node; | |
| 1026 | 1026 | |
| 1027 | 1027 | if (match == NULL) |
| 1028 | 1028 | return -EINVAL; |
| @@ -1113,7 +1113,7 @@ ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci) · 84 unmodified lines | ||
| 1113 | 1113 | int status = 0; |
| 1114 | 1114 | int ded_irq, sec_irq; |
| 1115 | 1115 | struct ppc4xx_edac_pdata *pdata = mci->pvt_info; |
| 1116 | − struct device_node *np = op->node; | |
| 1116 | + struct device_node *np = op->dev.of_node; | |
| 1117 | 1117 | |
| 1118 | 1118 | ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX); |
| 1119 | 1119 | sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX); |
| @@ -1243,7 +1243,7 @@ ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match) · 123 unmodified lines | ||
| 1243 | 1243 | int status = 0; |
| 1244 | 1244 | u32 mcopt1, memcheck; |
| 1245 | 1245 | dcr_host_t dcr_host; |
| 1246 | − const struct device_node *np = op->node; | |
| 1246 | + const struct device_node *np = op->dev.of_node; | |
| 1247 | 1247 | struct mem_ctl_info *mci = NULL; |
| 1248 | 1248 | static int ppc4xx_edac_instance; |
| 1249 | 1249 | |
| @@ -231,7 +231,7 @@ void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) · 230 unmodified lines | ||
| 231 | 231 | static void fw_card_bm_work(struct work_struct *work) |
| 232 | 232 | { |
| 233 | 233 | struct fw_card *card = container_of(work, struct fw_card, work.work); |
| 234 | − struct fw_device *root_device; | |
| 234 | + struct fw_device *root_device, *irm_device; | |
| 235 | 235 | struct fw_node *root_node; |
| 236 | 236 | unsigned long flags; |
| 237 | 237 | int root_id, new_root_id, irm_id, local_id; |
| @@ -239,6 +239,7 @@ static void fw_card_bm_work(struct work_struct *work) · 1 unmodified line | ||
| 239 | 239 | bool do_reset = false; |
| 240 | 240 | bool root_device_is_running; |
| 241 | 241 | bool root_device_is_cmc; |
| 242 | + bool irm_is_1394_1995_only; | |
| 242 | 243 | |
| 243 | 244 | spin_lock_irqsave(&card->lock, flags); |
| 244 | 245 | |
| @@ -248,12 +249,18 @@ static void fw_card_bm_work(struct work_struct *work) · 3 unmodified lines | ||
| 248 | 249 | } |
| 249 | 250 | |
| 250 | 251 | generation = card->generation; |
| 252 | + | |
| 251 | 253 | root_node = card->root_node; |
| 252 | 254 | fw_node_get(root_node); |
| 253 | 255 | root_device = root_node->data; |
| 254 | 256 | root_device_is_running = root_device && |
| 255 | 257 | atomic_read(&root_device->state) == FW_DEVICE_RUNNING; |
| 256 | 258 | root_device_is_cmc = root_device && root_device->cmc; |
| 259 | + | |
| 260 | + irm_device = card->irm_node->data; | |
| 261 | + irm_is_1394_1995_only = irm_device && irm_device->config_rom && | |
| 262 | + (irm_device->config_rom[2] & 0x000000f0) == 0; | |
| 263 | + | |
| 257 | 264 | root_id = root_node->node_id; |
| 258 | 265 | irm_id = card->irm_node->node_id; |
| 259 | 266 | local_id = card->local_node->node_id; |
| @@ -276,8 +283,15 @@ static void fw_card_bm_work(struct work_struct *work) · 16 unmodified lines | ||
| 276 | 283 | |
| 277 | 284 | if (!card->irm_node->link_on) { |
| 278 | 285 | new_root_id = local_id; |
| 279 | − fw_notify("IRM has link off, making local node (%02x) root.\n", | |
| 280 | − new_root_id); | |
| 286 | + fw_notify("%s, making local node (%02x) root.\n", | |
| 287 | + "IRM has link off", new_root_id); | |
| 288 | + goto pick_me; | |
| 289 | + } | |
| 290 | + | |
| 291 | + if (irm_is_1394_1995_only) { | |
| 292 | + new_root_id = local_id; | |
| 293 | + fw_notify("%s, making local node (%02x) root.\n", | |
| 294 | + "IRM is not 1394a compliant", new_root_id); | |
| 281 | 295 | goto pick_me; |
| 282 | 296 | } |
| 283 | 297 | |
| @@ -316,8 +330,8 @@ static void fw_card_bm_work(struct work_struct *work) · 32 unmodified lines | ||
| 316 | 330 | * root, and thus, IRM. |
| 317 | 331 | */ |
| 318 | 332 | new_root_id = local_id; |
| 319 | − fw_notify("BM lock failed, making local node (%02x) root.\n", | |
| 320 | − new_root_id); | |
| 333 | + fw_notify("%s, making local node (%02x) root.\n", | |
| 334 | + "BM lock failed", new_root_id); | |
| 321 | 335 | goto pick_me; |
| 322 | 336 | } |
| 323 | 337 | } else if (card->bm_generation != generation) { |
| @@ -1840,8 +1840,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, · 1839 unmodified lines | ||
| 1840 | 1840 | |
| 1841 | 1841 | ret = copy_from_user(clips, clips_ptr, |
| 1842 | 1842 | num_clips * sizeof(*clips)); |
| 1843 | − if (ret) | |
| 1843 | + if (ret) { | |
| 1844 | + ret = -EFAULT; | |
| 1844 | 1845 | goto out_err2; |
| 1846 | + } | |
| 1845 | 1847 | } |
| 1846 | 1848 | |
| 1847 | 1849 | if (fb->funcs->dirty) { |
| @@ -860,19 +860,24 @@ static void output_poll_execute(struct slow_work *work) · 859 unmodified lines | ||
| 860 | 860 | } |
| 861 | 861 | } |
| 862 | 862 | |
| 863 | −void drm_kms_helper_poll_init(struct drm_device *dev) | |
| 863 | +void drm_kms_helper_poll_disable(struct drm_device *dev) | |
| 864 | +{ | |
| 865 | + if (!dev->mode_config.poll_enabled) | |
| 866 | + return; | |
| 867 | + delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); | |
| 868 | +} | |
| 869 | +EXPORT_SYMBOL(drm_kms_helper_poll_disable); | |
| 870 | + | |
| 871 | +void drm_kms_helper_poll_enable(struct drm_device *dev) | |
| 864 | 872 | { |
| 865 | − struct drm_connector *connector; | |
| 866 | 873 | bool poll = false; |
| 874 | + struct drm_connector *connector; | |
| 867 | 875 | int ret; |
| 868 | 876 | |
| 869 | 877 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 870 | 878 | if (connector->polled) |
| 871 | 879 | poll = true; |
| 872 | 880 | } |
| 873 | − slow_work_register_user(THIS_MODULE); | |
| 874 | − delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, | |
| 875 | − &output_poll_ops); | |
| 876 | 881 | |
| 877 | 882 | if (poll) { |
| 878 | 883 | ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD); |
| @@ -880,11 +885,22 @@ void drm_kms_helper_poll_init(struct drm_device *dev) · 1 unmodified line | ||
| 880 | 885 | DRM_ERROR("delayed enqueue failed %d\n", ret); |
| 881 | 886 | } |
| 882 | 887 | } |
| 888 | +EXPORT_SYMBOL(drm_kms_helper_poll_enable); | |
| 889 | + | |
| 890 | +void drm_kms_helper_poll_init(struct drm_device *dev) | |
| 891 | +{ | |
| 892 | + slow_work_register_user(THIS_MODULE); | |
| 893 | + delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, | |
| 894 | + &output_poll_ops); | |
| 895 | + dev->mode_config.poll_enabled = true; | |
| 896 | + | |
| 897 | + drm_kms_helper_poll_enable(dev); | |
| 898 | +} | |
| 883 | 899 | EXPORT_SYMBOL(drm_kms_helper_poll_init); |
| 884 | 900 | |
| 885 | 901 | void drm_kms_helper_poll_fini(struct drm_device *dev) |
| 886 | 902 | { |
| 887 | − delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); | |
| 903 | + drm_kms_helper_poll_disable(dev); | |
| 888 | 904 | slow_work_unregister_user(THIS_MODULE); |
| 889 | 905 | } |
| 890 | 906 | EXPORT_SYMBOL(drm_kms_helper_poll_fini); |
| @@ -264,7 +264,7 @@ bool drm_fb_helper_force_kernel_mode(void) · 263 unmodified lines | ||
| 264 | 264 | int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed, |
| 265 | 265 | void *panic_str) |
| 266 | 266 | { |
| 267 | − DRM_ERROR("panic occurred, switching back to text console\n"); | |
| 267 | + printk(KERN_ERR "panic occurred, switching back to text console\n"); | |
| 268 | 268 | return drm_fb_helper_force_kernel_mode(); |
| 269 | 269 | return 0; |
| 270 | 270 | } |
| @@ -22,6 +22,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ · 21 unmodified lines | ||
| 22 | 22 | intel_fb.o \ |
| 23 | 23 | intel_tv.o \ |
| 24 | 24 | intel_dvo.o \ |
| 25 | + intel_ringbuffer.o \ | |
| 25 | 26 | intel_overlay.o \ |
| 26 | 27 | dvo_ch7xxx.o \ |
| 27 | 28 | dvo_ch7017.o \ |
| @@ -77,7 +77,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) · 76 unmodified lines | ||
| 77 | 77 | case ACTIVE_LIST: |
| 78 | 78 | seq_printf(m, "Active:\n"); |
| 79 | 79 | lock = &dev_priv->mm.active_list_lock; |
| 80 | − head = &dev_priv->mm.active_list; | |
| 80 | + head = &dev_priv->render_ring.active_list; | |
| 81 | 81 | break; |
| 82 | 82 | case INACTIVE_LIST: |
| 83 | 83 | seq_printf(m, "Inactive:\n"); |
| @@ -129,7 +129,8 @@ static int i915_gem_request_info(struct seq_file *m, void *data) · 45 unmodified lines | ||
| 129 | 129 | struct drm_i915_gem_request *gem_request; |
| 130 | 130 | |
| 131 | 131 | seq_printf(m, "Request:\n"); |
| 132 | − list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { | |
| 132 | + list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, | |
| 133 | + list) { | |
| 133 | 134 | seq_printf(m, " %d @ %d\n", |
| 134 | 135 | gem_request->seqno, |
| 135 | 136 | (int) (jiffies - gem_request->emitted_jiffies)); |
| @@ -143,9 +144,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) · 7 unmodified lines | ||
| 143 | 144 | struct drm_device *dev = node->minor->dev; |
| 144 | 145 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 145 | 146 | |
| 146 | − if (dev_priv->hw_status_page != NULL) { | |
| 147 | + if (dev_priv->render_ring.status_page.page_addr != NULL) { | |
| 147 | 148 | seq_printf(m, "Current sequence: %d\n", |
| 148 | − i915_get_gem_seqno(dev)); | |
| 149 | + i915_get_gem_seqno(dev, &dev_priv->render_ring)); | |
| 149 | 150 | } else { |
| 150 | 151 | seq_printf(m, "Current sequence: hws uninitialized\n"); |
| 151 | 152 | } |
| @@ -195,9 +196,9 @@ static int i915_interrupt_info(struct seq_file *m, void *data) · 43 unmodified lines | ||
| 195 | 196 | } |
| 196 | 197 | seq_printf(m, "Interrupts received: %d\n", |
| 197 | 198 | atomic_read(&dev_priv->irq_received)); |
| 198 | − if (dev_priv->hw_status_page != NULL) { | |
| 199 | + if (dev_priv->render_ring.status_page.page_addr != NULL) { | |
| 199 | 200 | seq_printf(m, "Current sequence: %d\n", |
| 200 | − i915_get_gem_seqno(dev)); | |
| 201 | + i915_get_gem_seqno(dev, &dev_priv->render_ring)); | |
| 201 | 202 | } else { |
| 202 | 203 | seq_printf(m, "Current sequence: hws uninitialized\n"); |
| 203 | 204 | } |
| @@ -251,7 +252,7 @@ static int i915_hws_info(struct seq_file *m, void *data) · 47 unmodified lines | ||
| 251 | 252 | int i; |
| 252 | 253 | volatile u32 *hws; |
| 253 | 254 | |
| 254 | − hws = (volatile u32 *)dev_priv->hw_status_page; | |
| 255 | + hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr; | |
| 255 | 256 | if (hws == NULL) |
| 256 | 257 | return 0; |
| 257 | 258 | |
| @@ -287,7 +288,8 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) · 29 unmodified lines | ||
| 287 | 288 | |
| 288 | 289 | spin_lock(&dev_priv->mm.active_list_lock); |
| 289 | 290 | |
| 290 | − list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | |
| 291 | + list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list, | |
| 292 | + list) { | |
| 291 | 293 | obj = &obj_priv->base; |
| 292 | 294 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { |
| 293 | 295 | ret = i915_gem_object_get_pages(obj, 0); |
| @@ -317,14 +319,14 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) · 23 unmodified lines | ||
| 317 | 319 | u8 *virt; |
| 318 | 320 | uint32_t *ptr, off; |
| 319 | 321 | |
| 320 | − if (!dev_priv->ring.ring_obj) { | |
| 322 | + if (!dev_priv->render_ring.gem_object) { | |
| 321 | 323 | seq_printf(m, "No ringbuffer setup\n"); |
| 322 | 324 | return 0; |
| 323 | 325 | } |
| 324 | 326 | |
| 325 | − virt = dev_priv->ring.virtual_start; | |
| 327 | + virt = dev_priv->render_ring.virtual_start; | |
| 326 | 328 | |
| 327 | − for (off = 0; off < dev_priv->ring.Size; off += 4) { | |
| 329 | + for (off = 0; off < dev_priv->render_ring.size; off += 4) { | |
| 328 | 330 | ptr = (uint32_t *)(virt + off); |
| 329 | 331 | seq_printf(m, "%08x : %08x\n", off, *ptr); |
| 330 | 332 | } |
| @@ -344,7 +346,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) · 13 unmodified lines | ||
| 344 | 346 | |
| 345 | 347 | seq_printf(m, "RingHead : %08x\n", head); |
| 346 | 348 | seq_printf(m, "RingTail : %08x\n", tail); |
| 347 | − seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); | |
| 349 | + seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.size); | |
| 348 | 350 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); |
| 349 | 351 | |
| 350 | 352 | return 0; |
| @@ -489,11 +491,14 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) · 138 unmodified lines | ||
| 489 | 491 | struct drm_device *dev = node->minor->dev; |
| 490 | 492 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 491 | 493 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
| 494 | + u16 rgvstat = I915_READ16(MEMSTAT_ILK); | |
| 492 | 495 | |
| 493 | − seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3); | |
| 494 | − seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1); | |
| 495 | − seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf, | |
| 496 | − rgvswctl & 0x3f); | |
| 496 | + seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); | |
| 497 | + seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); | |
| 498 | + seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> | |
| 499 | + MEMSTAT_VID_SHIFT); | |
| 500 | + seq_printf(m, "Current P-state: %d\n", | |
| 501 | + (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); | |
| 497 | 502 | |
| 498 | 503 | return 0; |
| 499 | 504 | } |
| @@ -508,7 +513,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) · 8 unmodified lines | ||
| 508 | 513 | |
| 509 | 514 | for (i = 0; i < 16; i++) { |
| 510 | 515 | delayfreq = I915_READ(PXVFREQ_BASE + i * 4); |
| 511 | − seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq); | |
| 516 | + seq_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq, | |
| 517 | + (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); | |
| 512 | 518 | } |
| 513 | 519 | |
| 514 | 520 | return 0; |
| @@ -541,6 +547,8 @@ static int i915_drpc_info(struct seq_file *m, void *unused) · 26 unmodified lines | ||
| 541 | 547 | struct drm_device *dev = node->minor->dev; |
| 542 | 548 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 543 | 549 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
| 550 | + u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY); | |
| 551 | + u16 crstandvid = I915_READ16(CRSTANDVID); | |
| 544 | 552 | |
| 545 | 553 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? |
| 546 | 554 | "yes" : "no"); |
| @@ -555,9 +563,13 @@ static int i915_drpc_info(struct seq_file *m, void *unused) · 8 unmodified lines | ||
| 555 | 563 | rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); |
| 556 | 564 | seq_printf(m, "Starting frequency: P%d\n", |
| 557 | 565 | (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); |
| 558 | − seq_printf(m, "Max frequency: P%d\n", | |
| 566 | + seq_printf(m, "Max P-state: P%d\n", | |
| 559 | 567 | (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); |
| 560 | − seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); | |
| 568 | + seq_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); | |
| 569 | + seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f)); | |
| 570 | + seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); | |
| 571 | + seq_printf(m, "Render standby enabled: %s\n", | |
| 572 | + (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); | |
| 561 | 573 | |
| 562 | 574 | return 0; |
| 563 | 575 | } |
| @@ -621,6 +633,36 @@ static int i915_sr_status(struct seq_file *m, void *unused) · 57 unmodified lines | ||
| 621 | 633 | return 0; |
| 622 | 634 | } |
| 623 | 635 | |
| 636 | +static int i915_emon_status(struct seq_file *m, void *unused) | |
| 637 | +{ | |
| 638 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
| 639 | + struct drm_device *dev = node->minor->dev; | |
| 640 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 641 | + unsigned long temp, chipset, gfx; | |
| 642 | + | |
| 643 | + temp = i915_mch_val(dev_priv); | |
| 644 | + chipset = i915_chipset_val(dev_priv); | |
| 645 | + gfx = i915_gfx_val(dev_priv); | |
| 646 | + | |
| 647 | + seq_printf(m, "GMCH temp: %ld\n", temp); | |
| 648 | + seq_printf(m, "Chipset power: %ld\n", chipset); | |
| 649 | + seq_printf(m, "GFX power: %ld\n", gfx); | |
| 650 | + seq_printf(m, "Total power: %ld\n", chipset + gfx); | |
| 651 | + | |
| 652 | + return 0; | |
| 653 | +} | |
| 654 | + | |
| 655 | +static int i915_gfxec(struct seq_file *m, void *unused) | |
| 656 | +{ | |
| 657 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
| 658 | + struct drm_device *dev = node->minor->dev; | |
| 659 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 660 | + | |
| 661 | + seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); | |
| 662 | + | |
| 663 | + return 0; | |
| 664 | +} | |
| 665 | + | |
| 624 | 666 | static int |
| 625 | 667 | i915_wedged_open(struct inode *inode, |
| 626 | 668 | struct file *filp) |
| @@ -743,6 +785,8 @@ static struct drm_info_list i915_debugfs_list[] = { · 116 unmodified lines | ||
| 743 | 785 | {"i915_delayfreq_table", i915_delayfreq_table, 0}, |
| 744 | 786 | {"i915_inttoext_table", i915_inttoext_table, 0}, |
| 745 | 787 | {"i915_drpc_info", i915_drpc_info, 0}, |
| 788 | + {"i915_emon_status", i915_emon_status, 0}, | |
| 789 | + {"i915_gfxec", i915_gfxec, 0}, | |
| 746 | 790 | {"i915_fbc_status", i915_fbc_status, 0}, |
| 747 | 791 | {"i915_sr_status", i915_sr_status, 0}, |
| 748 | 792 | }; |
| @@ -40,84 +40,6 @@ · 39 unmodified lines | ||
| 40 | 40 | #include <linux/vga_switcheroo.h> |
| 41 | 41 | #include <linux/slab.h> |
| 42 | 42 | |
| 43 | −/* Really want an OS-independent resettable timer. Would like to have | |
| 44 | − * this loop run for (eg) 3 sec, but have the timer reset every time | |
| 45 | − * the head pointer changes, so that EBUSY only happens if the ring | |
| 46 | − * actually stalls for (eg) 3 seconds. | |
| 47 | − */ | |
| 48 | −int i915_wait_ring(struct drm_device * dev, int n, const char *caller) | |
| 49 | −{ | |
| 50 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 51 | − drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | |
| 52 | − u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; | |
| 53 | − u32 last_acthd = I915_READ(acthd_reg); | |
| 54 | − u32 acthd; | |
| 55 | − u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | |
| 56 | − int i; | |
| 57 | − | |
| 58 | − trace_i915_ring_wait_begin (dev); | |
| 59 | − | |
| 60 | − for (i = 0; i < 100000; i++) { | |
| 61 | − ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | |
| 62 | − acthd = I915_READ(acthd_reg); | |
| 63 | − ring->space = ring->head - (ring->tail + 8); | |
| 64 | − if (ring->space < 0) | |
| 65 | − ring->space += ring->Size; | |
| 66 | − if (ring->space >= n) { | |
| 67 | − trace_i915_ring_wait_end (dev); | |
| 68 | − return 0; | |
| 69 | − } | |
| 70 | − | |
| 71 | − if (dev->primary->master) { | |
| 72 | − struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | |
| 73 | − if (master_priv->sarea_priv) | |
| 74 | − master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | |
| 75 | − } | |
| 76 | − | |
| 77 | − | |
| 78 | − if (ring->head != last_head) | |
| 79 | − i = 0; | |
| 80 | − if (acthd != last_acthd) | |
| 81 | − i = 0; | |
| 82 | − | |
| 83 | − last_head = ring->head; | |
| 84 | − last_acthd = acthd; | |
| 85 | − msleep_interruptible(10); | |
| 86 | − | |
| 87 | − } | |
| 88 | − | |
| 89 | − trace_i915_ring_wait_end (dev); | |
| 90 | − return -EBUSY; | |
| 91 | −} | |
| 92 | − | |
| 93 | −/* As a ringbuffer is only allowed to wrap between instructions, fill | |
| 94 | − * the tail with NOOPs. | |
| 95 | − */ | |
| 96 | −int i915_wrap_ring(struct drm_device *dev) | |
| 97 | −{ | |
| 98 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 99 | − volatile unsigned int *virt; | |
| 100 | − int rem; | |
| 101 | − | |
| 102 | − rem = dev_priv->ring.Size - dev_priv->ring.tail; | |
| 103 | − if (dev_priv->ring.space < rem) { | |
| 104 | − int ret = i915_wait_ring(dev, rem, __func__); | |
| 105 | − if (ret) | |
| 106 | − return ret; | |
| 107 | − } | |
| 108 | − dev_priv->ring.space -= rem; | |
| 109 | − | |
| 110 | − virt = (unsigned int *) | |
| 111 | − (dev_priv->ring.virtual_start + dev_priv->ring.tail); | |
| 112 | − rem /= 4; | |
| 113 | − while (rem--) | |
| 114 | − *virt++ = MI_NOOP; | |
| 115 | − | |
| 116 | − dev_priv->ring.tail = 0; | |
| 117 | − | |
| 118 | − return 0; | |
| 119 | −} | |
| 120 | − | |
| 121 | 43 | /** |
| 122 | 44 | * Sets up the hardware status page for devices that need a physical address |
| 123 | 45 | * in the register. |
| @@ -133,10 +55,11 @@ static int i915_init_phys_hws(struct drm_device *dev) · 9 unmodified lines | ||
| 133 | 55 | DRM_ERROR("Can not allocate hardware status page\n"); |
| 134 | 56 | return -ENOMEM; |
| 135 | 57 | } |
| 136 | − dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | |
| 58 | + dev_priv->render_ring.status_page.page_addr | |
| 59 | + = dev_priv->status_page_dmah->vaddr; | |
| 137 | 60 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; |
| 138 | 61 | |
| 139 | − memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | |
| 62 | + memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); | |
| 140 | 63 | |
| 141 | 64 | if (IS_I965G(dev)) |
| 142 | 65 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & |
| @@ -159,8 +82,8 @@ static void i915_free_hws(struct drm_device *dev) · 16 unmodified lines | ||
| 159 | 82 | dev_priv->status_page_dmah = NULL; |
| 160 | 83 | } |
| 161 | 84 | |
| 162 | − if (dev_priv->status_gfx_addr) { | |
| 163 | − dev_priv->status_gfx_addr = 0; | |
| 85 | + if (dev_priv->render_ring.status_page.gfx_addr) { | |
| 86 | + dev_priv->render_ring.status_page.gfx_addr = 0; | |
| 164 | 87 | drm_core_ioremapfree(&dev_priv->hws_map, dev); |
| 165 | 88 | } |
| 166 | 89 | |
| @@ -172,7 +95,7 @@ void i915_kernel_lost_context(struct drm_device * dev) · 5 unmodified lines | ||
| 172 | 95 | { |
| 173 | 96 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 174 | 97 | struct drm_i915_master_private *master_priv; |
| 175 | − drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | |
| 98 | + struct intel_ring_buffer *ring = &dev_priv->render_ring; | |
| 176 | 99 | |
| 177 | 100 | /* |
| 178 | 101 | * We should never lose context on the ring with modesetting |
| @@ -185,7 +108,7 @@ void i915_kernel_lost_context(struct drm_device * dev) · 6 unmodified lines | ||
| 185 | 108 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; |
| 186 | 109 | ring->space = ring->head - (ring->tail + 8); |
| 187 | 110 | if (ring->space < 0) |
| 188 | − ring->space += ring->Size; | |
| 111 | + ring->space += ring->size; | |
| 189 | 112 | |
| 190 | 113 | if (!dev->primary->master) |
| 191 | 114 | return; |
| @@ -205,12 +128,9 @@ static int i915_dma_cleanup(struct drm_device * dev) · 13 unmodified lines | ||
| 205 | 128 | if (dev->irq_enabled) |
| 206 | 129 | drm_irq_uninstall(dev); |
| 207 | 130 | |
| 208 | − if (dev_priv->ring.virtual_start) { | |
| 209 | − drm_core_ioremapfree(&dev_priv->ring.map, dev); | |
| 210 | − dev_priv->ring.virtual_start = NULL; | |
| 211 | − dev_priv->ring.map.handle = NULL; | |
| 212 | − dev_priv->ring.map.size = 0; | |
| 213 | − } | |
| 131 | + intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | |
| 132 | + if (HAS_BSD(dev)) | |
| 133 | + intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | |
| 214 | 134 | |
| 215 | 135 | /* Clear the HWS virtual address at teardown */ |
| 216 | 136 | if (I915_NEED_GFX_HWS(dev)) |
| @@ -233,24 +153,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) · 16 unmodified lines | ||
| 233 | 153 | } |
| 234 | 154 | |
| 235 | 155 | if (init->ring_size != 0) { |
| 236 | − if (dev_priv->ring.ring_obj != NULL) { | |
| 156 | + if (dev_priv->render_ring.gem_object != NULL) { | |
| 237 | 157 | i915_dma_cleanup(dev); |
| 238 | 158 | DRM_ERROR("Client tried to initialize ringbuffer in " |
| 239 | 159 | "GEM mode\n"); |
| 240 | 160 | return -EINVAL; |
| 241 | 161 | } |
| 242 | 162 | |
| 243 | − dev_priv->ring.Size = init->ring_size; | |
| 163 | + dev_priv->render_ring.size = init->ring_size; | |
| 244 | 164 | |
| 245 | − dev_priv->ring.map.offset = init->ring_start; | |
| 246 | − dev_priv->ring.map.size = init->ring_size; | |
| 247 | − dev_priv->ring.map.type = 0; | |
| 248 | − dev_priv->ring.map.flags = 0; | |
| 249 | − dev_priv->ring.map.mtrr = 0; | |
| 165 | + dev_priv->render_ring.map.offset = init->ring_start; | |
| 166 | + dev_priv->render_ring.map.size = init->ring_size; | |
| 167 | + dev_priv->render_ring.map.type = 0; | |
| 168 | + dev_priv->render_ring.map.flags = 0; | |
| 169 | + dev_priv->render_ring.map.mtrr = 0; | |
| 250 | 170 | |
| 251 | − drm_core_ioremap_wc(&dev_priv->ring.map, dev); | |
| 171 | + drm_core_ioremap_wc(&dev_priv->render_ring.map, dev); | |
| 252 | 172 | |
| 253 | − if (dev_priv->ring.map.handle == NULL) { | |
| 173 | + if (dev_priv->render_ring.map.handle == NULL) { | |
| 254 | 174 | i915_dma_cleanup(dev); |
| 255 | 175 | DRM_ERROR("can not ioremap virtual address for" |
| 256 | 176 | " ring buffer\n"); |
| @@ -258,7 +178,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) · 1 unmodified line | ||
| 258 | 178 | } |
| 259 | 179 | } |
| 260 | 180 | |
| 261 | − dev_priv->ring.virtual_start = dev_priv->ring.map.handle; | |
| 181 | + dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle; | |
| 262 | 182 | |
| 263 | 183 | dev_priv->cpp = init->cpp; |
| 264 | 184 | dev_priv->back_offset = init->back_offset; |
| @@ -278,26 +198,29 @@ static int i915_dma_resume(struct drm_device * dev) · 13 unmodified lines | ||
| 278 | 198 | { |
| 279 | 199 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 280 | 200 | |
| 201 | + struct intel_ring_buffer *ring; | |
| 281 | 202 | DRM_DEBUG_DRIVER("%s\n", __func__); |
| 282 | 203 | |
| 283 | − if (dev_priv->ring.map.handle == NULL) { | |
| 204 | + ring = &dev_priv->render_ring; | |
| 205 | + | |
| 206 | + if (ring->map.handle == NULL) { | |
| 284 | 207 | DRM_ERROR("can not ioremap virtual address for" |
| 285 | 208 | " ring buffer\n"); |
| 286 | 209 | return -ENOMEM; |
| 287 | 210 | } |
| 288 | 211 | |
| 289 | 212 | /* Program Hardware Status Page */ |
| 290 | − if (!dev_priv->hw_status_page) { | |
| 213 | + if (!ring->status_page.page_addr) { | |
| 291 | 214 | DRM_ERROR("Can not find hardware status page\n"); |
| 292 | 215 | return -EINVAL; |
| 293 | 216 | } |
| 294 | 217 | DRM_DEBUG_DRIVER("hw status page @ %p\n", |
| 295 | − dev_priv->hw_status_page); | |
| 296 | − | |
| 297 | − if (dev_priv->status_gfx_addr != 0) | |
| 298 | − I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); | |
| 218 | + ring->status_page.page_addr); | |
| 219 | + if (ring->status_page.gfx_addr != 0) | |
| 220 | + ring->setup_status_page(dev, ring); | |
| 299 | 221 | else |
| 300 | 222 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); |
| 223 | + | |
| 301 | 224 | DRM_DEBUG_DRIVER("Enabled hardware status page\n"); |
| 302 | 225 | |
| 303 | 226 | return 0; |
| @@ -407,9 +330,8 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) · 103 unmodified lines | ||
| 407 | 330 | { |
| 408 | 331 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 409 | 332 | int i; |
| 410 | − RING_LOCALS; | |
| 411 | 333 | |
| 412 | − if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) | |
| 334 | + if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8) | |
| 413 | 335 | return -EINVAL; |
| 414 | 336 | |
| 415 | 337 | BEGIN_LP_RING((dwords+1)&~1); |
| @@ -442,9 +364,7 @@ i915_emit_box(struct drm_device *dev, · 26 unmodified lines | ||
| 442 | 364 | struct drm_clip_rect *boxes, |
| 443 | 365 | int i, int DR1, int DR4) |
| 444 | 366 | { |
| 445 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 446 | 367 | struct drm_clip_rect box = boxes[i]; |
| 447 | − RING_LOCALS; | |
| 448 | 368 | |
| 449 | 369 | if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { |
| 450 | 370 | DRM_ERROR("Bad box %d,%d..%d,%d\n", |
| @@ -481,7 +401,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev) · 30 unmodified lines | ||
| 481 | 401 | { |
| 482 | 402 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 483 | 403 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
| 484 | − RING_LOCALS; | |
| 485 | 404 | |
| 486 | 405 | dev_priv->counter++; |
| 487 | 406 | if (dev_priv->counter > 0x7FFFFFFFUL) |
| @@ -535,10 +454,8 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, · 47 unmodified lines | ||
| 535 | 454 | drm_i915_batchbuffer_t * batch, |
| 536 | 455 | struct drm_clip_rect *cliprects) |
| 537 | 456 | { |
| 538 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 539 | 457 | int nbox = batch->num_cliprects; |
| 540 | 458 | int i = 0, count; |
| 541 | − RING_LOCALS; | |
| 542 | 459 | |
| 543 | 460 | if ((batch->start | batch->used) & 0x7) { |
| 544 | 461 | DRM_ERROR("alignment"); |
| @@ -587,7 +504,6 @@ static int i915_dispatch_flip(struct drm_device * dev) · 42 unmodified lines | ||
| 587 | 504 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 588 | 505 | struct drm_i915_master_private *master_priv = |
| 589 | 506 | dev->primary->master->driver_priv; |
| 590 | − RING_LOCALS; | |
| 591 | 507 | |
| 592 | 508 | if (!master_priv->sarea_priv) |
| 593 | 509 | return -EINVAL; |
| @@ -640,7 +556,8 @@ static int i915_quiescent(struct drm_device * dev) · 46 unmodified lines | ||
| 640 | 556 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 641 | 557 | |
| 642 | 558 | i915_kernel_lost_context(dev); |
| 643 | − return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); | |
| 559 | + return intel_wait_ring_buffer(dev, &dev_priv->render_ring, | |
| 560 | + dev_priv->render_ring.size - 8); | |
| 644 | 561 | } |
| 645 | 562 | |
| 646 | 563 | static int i915_flush_ioctl(struct drm_device *dev, void *data, |
| @@ -827,6 +744,9 @@ static int i915_getparam(struct drm_device *dev, void *data, · 180 unmodified lines | ||
| 827 | 744 | /* depends on GEM */ |
| 828 | 745 | value = dev_priv->has_gem; |
| 829 | 746 | break; |
| 747 | + case I915_PARAM_HAS_BSD: | |
| 748 | + value = HAS_BSD(dev); | |
| 749 | + break; | |
| 830 | 750 | default: |
| 831 | 751 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
| 832 | 752 | param->param); |
| @@ -882,6 +802,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, · 49 unmodified lines | ||
| 882 | 802 | { |
| 883 | 803 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 884 | 804 | drm_i915_hws_addr_t *hws = data; |
| 805 | + struct intel_ring_buffer *ring = &dev_priv->render_ring; | |
| 885 | 806 | |
| 886 | 807 | if (!I915_NEED_GFX_HWS(dev)) |
| 887 | 808 | return -EINVAL; |
| @@ -898,7 +819,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, · 10 unmodified lines | ||
| 898 | 819 | |
| 899 | 820 | DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); |
| 900 | 821 | |
| 901 | − dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); | |
| 822 | + ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); | |
| 902 | 823 | |
| 903 | 824 | dev_priv->hws_map.offset = dev->agp->base + hws->addr; |
| 904 | 825 | dev_priv->hws_map.size = 4*1024; |
| @@ -909,19 +830,19 @@ static int i915_set_status_page(struct drm_device *dev, void *data, · 4 unmodified lines | ||
| 909 | 830 | drm_core_ioremap_wc(&dev_priv->hws_map, dev); |
| 910 | 831 | if (dev_priv->hws_map.handle == NULL) { |
| 911 | 832 | i915_dma_cleanup(dev); |
| 912 | − dev_priv->status_gfx_addr = 0; | |
| 833 | + ring->status_page.gfx_addr = 0; | |
| 913 | 834 | DRM_ERROR("can not ioremap virtual address for" |
| 914 | 835 | " G33 hw status page\n"); |
| 915 | 836 | return -ENOMEM; |
| 916 | 837 | } |
| 917 | − dev_priv->hw_status_page = dev_priv->hws_map.handle; | |
| 838 | + ring->status_page.page_addr = dev_priv->hws_map.handle; | |
| 839 | + memset(ring->status_page.page_addr, 0, PAGE_SIZE); | |
| 840 | + I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); | |
| 918 | 841 | |
| 919 | − memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | |
| 920 | − I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); | |
| 921 | 842 | DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", |
| 922 | − dev_priv->status_gfx_addr); | |
| 843 | + ring->status_page.gfx_addr); | |
| 923 | 844 | DRM_DEBUG_DRIVER("load hws at %p\n", |
| 924 | − dev_priv->hw_status_page); | |
| 845 | + ring->status_page.page_addr); | |
| 925 | 846 | return 0; |
| 926 | 847 | } |
| 927 | 848 | |
| @@ -1399,12 +1320,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ · 471 unmodified lines | ||
| 1399 | 1320 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1400 | 1321 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
| 1401 | 1322 | if (state == VGA_SWITCHEROO_ON) { |
| 1402 | − printk(KERN_INFO "i915: switched off\n"); | |
| 1323 | + printk(KERN_INFO "i915: switched on\n"); | |
| 1403 | 1324 | /* i915 resume handler doesn't set to D0 */ |
| 1404 | 1325 | pci_set_power_state(dev->pdev, PCI_D0); |
| 1405 | 1326 | i915_resume(dev); |
| 1327 | + drm_kms_helper_poll_enable(dev); | |
| 1406 | 1328 | } else { |
| 1407 | 1329 | printk(KERN_ERR "i915: switched off\n"); |
| 1330 | + drm_kms_helper_poll_disable(dev); | |
| 1408 | 1331 | i915_suspend(dev, pmm); |
| 1409 | 1332 | } |
| 1410 | 1333 | } |
| @@ -1479,19 +1402,19 @@ static int i915_load_modeset_init(struct drm_device *dev, · 68 unmodified lines | ||
| 1479 | 1402 | /* if we have > 1 VGA cards, then disable the radeon VGA resources */ |
| 1480 | 1403 | ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); |
| 1481 | 1404 | if (ret) |
| 1482 | − goto destroy_ringbuffer; | |
| 1405 | + goto cleanup_ringbuffer; | |
| 1483 | 1406 | |
| 1484 | 1407 | ret = vga_switcheroo_register_client(dev->pdev, |
| 1485 | 1408 | i915_switcheroo_set_state, |
| 1486 | 1409 | i915_switcheroo_can_switch); |
| 1487 | 1410 | if (ret) |
| 1488 | − goto destroy_ringbuffer; | |
| 1411 | + goto cleanup_vga_client; | |
| 1489 | 1412 | |
| 1490 | 1413 | intel_modeset_init(dev); |
| 1491 | 1414 | |
| 1492 | 1415 | ret = drm_irq_install(dev); |
| 1493 | 1416 | if (ret) |
| 1494 | − goto destroy_ringbuffer; | |
| 1417 | + goto cleanup_vga_switcheroo; | |
| 1495 | 1418 | |
| 1496 | 1419 | /* Always safe in the mode setting case. */ |
| 1497 | 1420 | /* FIXME: do pre/post-mode set stuff in core KMS code */ |
| @@ -1503,11 +1426,20 @@ static int i915_load_modeset_init(struct drm_device *dev, · 5 unmodified lines | ||
| 1503 | 1426 | |
| 1504 | 1427 | I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); |
| 1505 | 1428 | |
| 1506 | − intel_fbdev_init(dev); | |
| 1429 | + ret = intel_fbdev_init(dev); | |
| 1430 | + if (ret) | |
| 1431 | + goto cleanup_irq; | |
| 1432 | + | |
| 1507 | 1433 | drm_kms_helper_poll_init(dev); |
| 1508 | 1434 | return 0; |
| 1509 | 1435 | |
| 1510 | −destroy_ringbuffer: | |
| 1436 | +cleanup_irq: | |
| 1437 | + drm_irq_uninstall(dev); | |
| 1438 | +cleanup_vga_switcheroo: | |
| 1439 | + vga_switcheroo_unregister_client(dev->pdev); | |
| 1440 | +cleanup_vga_client: | |
| 1441 | + vga_client_register(dev->pdev, NULL, NULL, NULL); | |
| 1442 | +cleanup_ringbuffer: | |
| 1511 | 1443 | mutex_lock(&dev->struct_mutex); |
| 1512 | 1444 | i915_gem_cleanup_ringbuffer(dev); |
| 1513 | 1445 | mutex_unlock(&dev->struct_mutex); |
| @@ -1539,14 +1471,11 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) · 25 unmodified lines | ||
| 1539 | 1471 | master->driver_priv = NULL; |
| 1540 | 1472 | } |
| 1541 | 1473 | |
| 1542 | −static void i915_get_mem_freq(struct drm_device *dev) | |
| 1474 | +static void i915_pineview_get_mem_freq(struct drm_device *dev) | |
| 1543 | 1475 | { |
| 1544 | 1476 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1545 | 1477 | u32 tmp; |
| 1546 | 1478 | |
| 1547 | − if (!IS_PINEVIEW(dev)) | |
| 1548 | − return; | |
| 1549 | − | |
| 1550 | 1479 | tmp = I915_READ(CLKCFG); |
| 1551 | 1480 | |
| 1552 | 1481 | switch (tmp & CLKCFG_FSB_MASK) { |
| @@ -1575,7 +1504,524 @@ static void i915_get_mem_freq(struct drm_device *dev) · 22 unmodified lines | ||
| 1575 | 1504 | dev_priv->mem_freq = 800; |
| 1576 | 1505 | break; |
| 1577 | 1506 | } |
| 1507 | + | |
| 1508 | + /* detect pineview DDR3 setting */ | |
| 1509 | + tmp = I915_READ(CSHRDDR3CTL); | |
| 1510 | + dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; | |
| 1511 | +} | |
| 1512 | + | |
| 1513 | +static void i915_ironlake_get_mem_freq(struct drm_device *dev) | |
| 1514 | +{ | |
| 1515 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 1516 | + u16 ddrpll, csipll; | |
| 1517 | + | |
| 1518 | + ddrpll = I915_READ16(DDRMPLL1); | |
| 1519 | + csipll = I915_READ16(CSIPLL0); | |
| 1520 | + | |
| 1521 | + switch (ddrpll & 0xff) { | |
| 1522 | + case 0xc: | |
| 1523 | + dev_priv->mem_freq = 800; | |
| 1524 | + break; | |
| 1525 | + case 0x10: | |
| 1526 | + dev_priv->mem_freq = 1066; | |
| 1527 | + break; | |
| 1528 | + case 0x14: | |
| 1529 | + dev_priv->mem_freq = 1333; | |
| 1530 | + break; | |
| 1531 | + case 0x18: | |
| 1532 | + dev_priv->mem_freq = 1600; | |
| 1533 | + break; | |
| 1534 | + default: | |
| 1535 | + DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n", | |
| 1536 | + ddrpll & 0xff); | |
| 1537 | + dev_priv->mem_freq = 0; | |
| 1538 | + break; | |
| 1539 | + } | |
| 1540 | + | |
| 1541 | + dev_priv->r_t = dev_priv->mem_freq; | |
| 1542 | + | |
| 1543 | + switch (csipll & 0x3ff) { | |
| 1544 | + case 0x00c: | |
| 1545 | + dev_priv->fsb_freq = 3200; | |
| 1546 | + break; | |
| 1547 | + case 0x00e: | |
| 1548 | + dev_priv->fsb_freq = 3733; | |
| 1549 | + break; | |
| 1550 | + case 0x010: | |
| 1551 | + dev_priv->fsb_freq = 4266; | |
| 1552 | + break; | |
| 1553 | + case 0x012: | |
| 1554 | + dev_priv->fsb_freq = 4800; | |
| 1555 | + break; | |
| 1556 | + case 0x014: | |
| 1557 | + dev_priv->fsb_freq = 5333; | |
| 1558 | + break; | |
| 1559 | + case 0x016: | |
| 1560 | + dev_priv->fsb_freq = 5866; | |
| 1561 | + break; | |
| 1562 | + case 0x018: | |
| 1563 | + dev_priv->fsb_freq = 6400; | |
| 1564 | + break; | |
| 1565 | + default: | |
| 1566 | + DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n", | |
| 1567 | + csipll & 0x3ff); | |
| 1568 | + dev_priv->fsb_freq = 0; | |
| 1569 | + break; | |
| 1570 | + } | |
| 1571 | + | |
| 1572 | + if (dev_priv->fsb_freq == 3200) { | |
| 1573 | + dev_priv->c_m = 0; | |
| 1574 | + } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) { | |
| 1575 | + dev_priv->c_m = 1; | |
| 1576 | + } else { | |
| 1577 | + dev_priv->c_m = 2; | |
| 1578 | + } | |
| 1579 | +} | |
| 1580 | + | |
| 1581 | +struct v_table { | |
| 1582 | + u8 vid; | |
| 1583 | + unsigned long vd; /* in .1 mil */ | |
| 1584 | + unsigned long vm; /* in .1 mil */ | |
| 1585 | + u8 pvid; | |
| 1586 | +}; | |
| 1587 | + | |
| 1588 | +static struct v_table v_table[] = { | |
| 1589 | + { 0, 16125, 15000, 0x7f, }, | |
| 1590 | + { 1, 16000, 14875, 0x7e, }, | |
| 1591 | + { 2, 15875, 14750, 0x7d, }, | |
| 1592 | + { 3, 15750, 14625, 0x7c, }, | |
| 1593 | + { 4, 15625, 14500, 0x7b, }, | |
| 1594 | + { 5, 15500, 14375, 0x7a, }, | |
| 1595 | + { 6, 15375, 14250, 0x79, }, | |
| 1596 | + { 7, 15250, 14125, 0x78, }, | |
| 1597 | + { 8, 15125, 14000, 0x77, }, | |
| 1598 | + { 9, 15000, 13875, 0x76, }, | |
| 1599 | + { 10, 14875, 13750, 0x75, }, | |
| 1600 | + { 11, 14750, 13625, 0x74, }, | |
| 1601 | + { 12, 14625, 13500, 0x73, }, | |
| 1602 | + { 13, 14500, 13375, 0x72, }, | |
| 1603 | + { 14, 14375, 13250, 0x71, }, | |
| 1604 | + { 15, 14250, 13125, 0x70, }, | |
| 1605 | + { 16, 14125, 13000, 0x6f, }, | |
| 1606 | + { 17, 14000, 12875, 0x6e, }, | |
| 1607 | + { 18, 13875, 12750, 0x6d, }, | |
| 1608 | + { 19, 13750, 12625, 0x6c, }, | |
| 1609 | + { 20, 13625, 12500, 0x6b, }, | |
| 1610 | + { 21, 13500, 12375, 0x6a, }, | |
| 1611 | + { 22, 13375, 12250, 0x69, }, | |
| 1612 | + { 23, 13250, 12125, 0x68, }, | |
| 1613 | + { 24, 13125, 12000, 0x67, }, | |
| 1614 | + { 25, 13000, 11875, 0x66, }, | |
| 1615 | + { 26, 12875, 11750, 0x65, }, | |
| 1616 | + { 27, 12750, 11625, 0x64, }, | |
| 1617 | + { 28, 12625, 11500, 0x63, }, | |
| 1618 | + { 29, 12500, 11375, 0x62, }, | |
| 1619 | + { 30, 12375, 11250, 0x61, }, | |
| 1620 | + { 31, 12250, 11125, 0x60, }, | |
| 1621 | + { 32, 12125, 11000, 0x5f, }, | |
| 1622 | + { 33, 12000, 10875, 0x5e, }, | |
| 1623 | + { 34, 11875, 10750, 0x5d, }, | |
| 1624 | + { 35, 11750, 10625, 0x5c, }, | |
| 1625 | + { 36, 11625, 10500, 0x5b, }, | |
| 1626 | + { 37, 11500, 10375, 0x5a, }, | |
| 1627 | + { 38, 11375, 10250, 0x59, }, | |
| 1628 | + { 39, 11250, 10125, 0x58, }, | |
| 1629 | + { 40, 11125, 10000, 0x57, }, | |
| 1630 | + { 41, 11000, 9875, 0x56, }, | |
| 1631 | + { 42, 10875, 9750, 0x55, }, | |
| 1632 | + { 43, 10750, 9625, 0x54, }, | |
| 1633 | + { 44, 10625, 9500, 0x53, }, | |
| 1634 | + { 45, 10500, 9375, 0x52, }, | |
| 1635 | + { 46, 10375, 9250, 0x51, }, | |
| 1636 | + { 47, 10250, 9125, 0x50, }, | |
| 1637 | + { 48, 10125, 9000, 0x4f, }, | |
| 1638 | + { 49, 10000, 8875, 0x4e, }, | |
| 1639 | + { 50, 9875, 8750, 0x4d, }, | |
| 1640 | + { 51, 9750, 8625, 0x4c, }, | |
| 1641 | + { 52, 9625, 8500, 0x4b, }, | |
| 1642 | + { 53, 9500, 8375, 0x4a, }, | |
| 1643 | + { 54, 9375, 8250, 0x49, }, | |
| 1644 | + { 55, 9250, 8125, 0x48, }, | |
| 1645 | + { 56, 9125, 8000, 0x47, }, | |
| 1646 | + { 57, 9000, 7875, 0x46, }, | |
| 1647 | + { 58, 8875, 7750, 0x45, }, | |
| 1648 | + { 59, 8750, 7625, 0x44, }, | |
| 1649 | + { 60, 8625, 7500, 0x43, }, | |
| 1650 | + { 61, 8500, 7375, 0x42, }, | |
| 1651 | + { 62, 8375, 7250, 0x41, }, | |
| 1652 | + { 63, 8250, 7125, 0x40, }, | |
| 1653 | + { 64, 8125, 7000, 0x3f, }, | |
| 1654 | + { 65, 8000, 6875, 0x3e, }, | |
| 1655 | + { 66, 7875, 6750, 0x3d, }, | |
| 1656 | + { 67, 7750, 6625, 0x3c, }, | |
| 1657 | + { 68, 7625, 6500, 0x3b, }, | |
| 1658 | + { 69, 7500, 6375, 0x3a, }, | |
| 1659 | + { 70, 7375, 6250, 0x39, }, | |
| 1660 | + { 71, 7250, 6125, 0x38, }, | |
| 1661 | + { 72, 7125, 6000, 0x37, }, | |
| 1662 | + { 73, 7000, 5875, 0x36, }, | |
| 1663 | + { 74, 6875, 5750, 0x35, }, | |
| 1664 | + { 75, 6750, 5625, 0x34, }, | |
| 1665 | + { 76, 6625, 5500, 0x33, }, | |
| 1666 | + { 77, 6500, 5375, 0x32, }, | |
| 1667 | + { 78, 6375, 5250, 0x31, }, | |
| 1668 | + { 79, 6250, 5125, 0x30, }, | |
| 1669 | + { 80, 6125, 5000, 0x2f, }, | |
| 1670 | + { 81, 6000, 4875, 0x2e, }, | |
| 1671 | + { 82, 5875, 4750, 0x2d, }, | |
| 1672 | + { 83, 5750, 4625, 0x2c, }, | |
| 1673 | + { 84, 5625, 4500, 0x2b, }, | |
| 1674 | + { 85, 5500, 4375, 0x2a, }, | |
| 1675 | + { 86, 5375, 4250, 0x29, }, | |
| 1676 | + { 87, 5250, 4125, 0x28, }, | |
| 1677 | + { 88, 5125, 4000, 0x27, }, | |
| 1678 | + { 89, 5000, 3875, 0x26, }, | |
| 1679 | + { 90, 4875, 3750, 0x25, }, | |
| 1680 | + { 91, 4750, 3625, 0x24, }, | |
| 1681 | + { 92, 4625, 3500, 0x23, }, | |
| 1682 | + { 93, 4500, 3375, 0x22, }, | |
| 1683 | + { 94, 4375, 3250, 0x21, }, | |
| 1684 | + { 95, 4250, 3125, 0x20, }, | |
| 1685 | + { 96, 4125, 3000, 0x1f, }, | |
| 1686 | + { 97, 4125, 3000, 0x1e, }, | |
| 1687 | + { 98, 4125, 3000, 0x1d, }, | |
| 1688 | + { 99, 4125, 3000, 0x1c, }, | |
| 1689 | + { 100, 4125, 3000, 0x1b, }, | |
| 1690 | + { 101, 4125, 3000, 0x1a, }, | |
| 1691 | + { 102, 4125, 3000, 0x19, }, | |
| 1692 | + { 103, 4125, 3000, 0x18, }, | |
| 1693 | + { 104, 4125, 3000, 0x17, }, | |
| 1694 | + { 105, 4125, 3000, 0x16, }, | |
| 1695 | + { 106, 4125, 3000, 0x15, }, | |
| 1696 | + { 107, 4125, 3000, 0x14, }, | |
| 1697 | + { 108, 4125, 3000, 0x13, }, | |
| 1698 | + { 109, 4125, 3000, 0x12, }, | |
| 1699 | + { 110, 4125, 3000, 0x11, }, | |
| 1700 | + { 111, 4125, 3000, 0x10, }, | |
| 1701 | + { 112, 4125, 3000, 0x0f, }, | |
| 1702 | + { 113, 4125, 3000, 0x0e, }, | |
| 1703 | + { 114, 4125, 3000, 0x0d, }, | |
| 1704 | + { 115, 4125, 3000, 0x0c, }, | |
| 1705 | + { 116, 4125, 3000, 0x0b, }, | |
| 1706 | + { 117, 4125, 3000, 0x0a, }, | |
| 1707 | + { 118, 4125, 3000, 0x09, }, | |
| 1708 | + { 119, 4125, 3000, 0x08, }, | |
| 1709 | + { 120, 1125, 0, 0x07, }, | |
| 1710 | + { 121, 1000, 0, 0x06, }, | |
| 1711 | + { 122, 875, 0, 0x05, }, | |
| 1712 | + { 123, 750, 0, 0x04, }, | |
| 1713 | + { 124, 625, 0, 0x03, }, | |
| 1714 | + { 125, 500, 0, 0x02, }, | |
| 1715 | + { 126, 375, 0, 0x01, }, | |
| 1716 | + { 127, 0, 0, 0x00, }, | |
| 1717 | +}; | |
| 1718 | + | |
| 1719 | +struct cparams { | |
| 1720 | + int i; | |
| 1721 | + int t; | |
| 1722 | + int m; | |
| 1723 | + int c; | |
| 1724 | +}; | |
| 1725 | + | |
| 1726 | +static struct cparams cparams[] = { | |
| 1727 | + { 1, 1333, 301, 28664 }, | |
| 1728 | + { 1, 1066, 294, 24460 }, | |
| 1729 | + { 1, 800, 294, 25192 }, | |
| 1730 | + { 0, 1333, 276, 27605 }, | |
| 1731 | + { 0, 1066, 276, 27605 }, | |
| 1732 | + { 0, 800, 231, 23784 }, | |
| 1733 | +}; | |
| 1734 | + | |
| 1735 | +unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | |
| 1736 | +{ | |
| 1737 | + u64 total_count, diff, ret; | |
| 1738 | + u32 count1, count2, count3, m = 0, c = 0; | |
| 1739 | + unsigned long now = jiffies_to_msecs(jiffies), diff1; | |
| 1740 | + int i; | |
| 1741 | + | |
| 1742 | + diff1 = now - dev_priv->last_time1; | |
| 1743 | + | |
| 1744 | + count1 = I915_READ(DMIEC); | |
| 1745 | + count2 = I915_READ(DDREC); | |
| 1746 | + count3 = I915_READ(CSIEC); | |
| 1747 | + | |
| 1748 | + total_count = count1 + count2 + count3; | |
| 1749 | + | |
| 1750 | + /* FIXME: handle per-counter overflow */ | |
| 1751 | + if (total_count < dev_priv->last_count1) { | |
| 1752 | + diff = ~0UL - dev_priv->last_count1; | |
| 1753 | + diff += total_count; | |
| 1754 | + } else { | |
| 1755 | + diff = total_count - dev_priv->last_count1; | |
| 1756 | + } | |
| 1757 | + | |
| 1758 | + for (i = 0; i < ARRAY_SIZE(cparams); i++) { | |
| 1759 | + if (cparams[i].i == dev_priv->c_m && | |
| 1760 | + cparams[i].t == dev_priv->r_t) { | |
| 1761 | + m = cparams[i].m; | |
| 1762 | + c = cparams[i].c; | |
| 1763 | + break; | |
| 1764 | + } | |
| 1765 | + } | |
| 1766 | + | |
| 1767 | + div_u64(diff, diff1); | |
| 1768 | + ret = ((m * diff) + c); | |
| 1769 | + div_u64(ret, 10); | |
| 1770 | + | |
| 1771 | + dev_priv->last_count1 = total_count; | |
| 1772 | + dev_priv->last_time1 = now; | |
| 1773 | + | |
| 1774 | + return ret; | |
| 1775 | +} | |
| 1776 | + | |
| 1777 | +unsigned long i915_mch_val(struct drm_i915_private *dev_priv) | |
| 1778 | +{ | |
| 1779 | + unsigned long m, x, b; | |
| 1780 | + u32 tsfs; | |
| 1781 | + | |
| 1782 | + tsfs = I915_READ(TSFS); | |
| 1783 | + | |
| 1784 | + m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT); | |
| 1785 | + x = I915_READ8(TR1); | |
| 1786 | + | |
| 1787 | + b = tsfs & TSFS_INTR_MASK; | |
| 1788 | + | |
| 1789 | + return ((m * x) / 127) - b; | |
| 1790 | +} | |
| 1791 | + | |
| 1792 | +static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) | |
| 1793 | +{ | |
| 1794 | + unsigned long val = 0; | |
| 1795 | + int i; | |
| 1796 | + | |
| 1797 | + for (i = 0; i < ARRAY_SIZE(v_table); i++) { | |
| 1798 | + if (v_table[i].pvid == pxvid) { | |
| 1799 | + if (IS_MOBILE(dev_priv->dev)) | |
| 1800 | + val = v_table[i].vm; | |
| 1801 | + else | |
| 1802 | + val = v_table[i].vd; | |
| 1803 | + } | |
| 1804 | + } | |
| 1805 | + | |
| 1806 | + return val; | |
| 1807 | +} | |
| 1808 | + | |
| 1809 | +void i915_update_gfx_val(struct drm_i915_private *dev_priv) | |
| 1810 | +{ | |
| 1811 | + struct timespec now, diff1; | |
| 1812 | + u64 diff; | |
| 1813 | + unsigned long diffms; | |
| 1814 | + u32 count; | |
| 1815 | + | |
| 1816 | + getrawmonotonic(&now); | |
| 1817 | + diff1 = timespec_sub(now, dev_priv->last_time2); | |
| 1818 | + | |
| 1819 | + /* Don't divide by 0 */ | |
| 1820 | + diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000; | |
| 1821 | + if (!diffms) | |
| 1822 | + return; | |
| 1823 | + | |
| 1824 | + count = I915_READ(GFXEC); | |
| 1825 | + | |
| 1826 | + if (count < dev_priv->last_count2) { | |
| 1827 | + diff = ~0UL - dev_priv->last_count2; | |
| 1828 | + diff += count; | |
| 1829 | + } else { | |
| 1830 | + diff = count - dev_priv->last_count2; | |
| 1831 | + } | |
| 1832 | + | |
| 1833 | + dev_priv->last_count2 = count; | |
| 1834 | + dev_priv->last_time2 = now; | |
| 1835 | + | |
| 1836 | + /* More magic constants... */ | |
| 1837 | + diff = diff * 1181; | |
| 1838 | + div_u64(diff, diffms * 10); | |
| 1839 | + dev_priv->gfx_power = diff; | |
| 1840 | +} | |
| 1841 | + | |
| 1842 | +unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) | |
| 1843 | +{ | |
| 1844 | + unsigned long t, corr, state1, corr2, state2; | |
| 1845 | + u32 pxvid, ext_v; | |
| 1846 | + | |
| 1847 | + pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4)); | |
| 1848 | + pxvid = (pxvid >> 24) & 0x7f; | |
| 1849 | + ext_v = pvid_to_extvid(dev_priv, pxvid); | |
| 1850 | + | |
| 1851 | + state1 = ext_v; | |
| 1852 | + | |
| 1853 | + t = i915_mch_val(dev_priv); | |
| 1854 | + | |
| 1855 | + /* Revel in the empirically derived constants */ | |
| 1856 | + | |
| 1857 | + /* Correction factor in 1/100000 units */ | |
| 1858 | + if (t > 80) | |
| 1859 | + corr = ((t * 2349) + 135940); | |
| 1860 | + else if (t >= 50) | |
| 1861 | + corr = ((t * 964) + 29317); | |
| 1862 | + else /* < 50 */ | |
| 1863 | + corr = ((t * 301) + 1004); | |
| 1864 | + | |
| 1865 | + corr = corr * ((150142 * state1) / 10000 - 78642); | |
| 1866 | + corr /= 100000; | |
| 1867 | + corr2 = (corr * dev_priv->corr); | |
| 1868 | + | |
| 1869 | + state2 = (corr2 * state1) / 10000; | |
| 1870 | + state2 /= 100; /* convert to mW */ | |
| 1871 | + | |
| 1872 | + i915_update_gfx_val(dev_priv); | |
| 1873 | + | |
| 1874 | + return dev_priv->gfx_power + state2; | |
| 1875 | +} | |
| 1876 | + | |
| 1877 | +/* Global for IPS driver to get at the current i915 device */ | |
| 1878 | +static struct drm_i915_private *i915_mch_dev; | |
| 1879 | +/* | |
| 1880 | + * Lock protecting IPS related data structures | |
| 1881 | + * - i915_mch_dev | |
| 1882 | + * - dev_priv->max_delay | |
| 1883 | + * - dev_priv->min_delay | |
| 1884 | + * - dev_priv->fmax | |
| 1885 | + * - dev_priv->gpu_busy | |
| 1886 | + */ | |
| 1887 | +DEFINE_SPINLOCK(mchdev_lock); | |
| 1888 | + | |
| 1889 | +/** | |
| 1890 | + * i915_read_mch_val - return value for IPS use | |
| 1891 | + * | |
| 1892 | + * Calculate and return a value for the IPS driver to use when deciding whether | |
| 1893 | + * we have thermal and power headroom to increase CPU or GPU power budget. | |
| 1894 | + */ | |
| 1895 | +unsigned long i915_read_mch_val(void) | |
| 1896 | +{ | |
| 1897 | + struct drm_i915_private *dev_priv; | |
| 1898 | + unsigned long chipset_val, graphics_val, ret = 0; | |
| 1899 | + | |
| 1900 | + spin_lock(&mchdev_lock); | |
| 1901 | + if (!i915_mch_dev) | |
| 1902 | + goto out_unlock; | |
| 1903 | + dev_priv = i915_mch_dev; | |
| 1904 | + | |
| 1905 | + chipset_val = i915_chipset_val(dev_priv); | |
| 1906 | + graphics_val = i915_gfx_val(dev_priv); | |
| 1907 | + | |
| 1908 | + ret = chipset_val + graphics_val; | |
| 1909 | + | |
| 1910 | +out_unlock: | |
| 1911 | + spin_unlock(&mchdev_lock); | |
| 1912 | + | |
| 1913 | + return ret; | |
| 1914 | +} | |
| 1915 | +EXPORT_SYMBOL_GPL(i915_read_mch_val); | |
| 1916 | + | |
| 1917 | +/** | |
| 1918 | + * i915_gpu_raise - raise GPU frequency limit | |
| 1919 | + * | |
| 1920 | + * Raise the limit; IPS indicates we have thermal headroom. | |
| 1921 | + */ | |
| 1922 | +bool i915_gpu_raise(void) | |
| 1923 | +{ | |
| 1924 | + struct drm_i915_private *dev_priv; | |
| 1925 | + bool ret = true; | |
| 1926 | + | |
| 1927 | + spin_lock(&mchdev_lock); | |
| 1928 | + if (!i915_mch_dev) { | |
| 1929 | + ret = false; | |
| 1930 | + goto out_unlock; | |
| 1931 | + } | |
| 1932 | + dev_priv = i915_mch_dev; | |
| 1933 | + | |
| 1934 | + if (dev_priv->max_delay > dev_priv->fmax) | |
| 1935 | + dev_priv->max_delay--; | |
| 1936 | + | |
| 1937 | +out_unlock: | |
| 1938 | + spin_unlock(&mchdev_lock); | |
| 1939 | + | |
| 1940 | + return ret; | |
| 1941 | +} | |
| 1942 | +EXPORT_SYMBOL_GPL(i915_gpu_raise); | |
| 1943 | + | |
| 1944 | +/** | |
| 1945 | + * i915_gpu_lower - lower GPU frequency limit | |
| 1946 | + * | |
| 1947 | + * IPS indicates we're close to a thermal limit, so throttle back the GPU | |
| 1948 | + * frequency maximum. | |
| 1949 | + */ | |
| 1950 | +bool i915_gpu_lower(void) | |
| 1951 | +{ | |
| 1952 | + struct drm_i915_private *dev_priv; | |
| 1953 | + bool ret = true; | |
| 1954 | + | |
| 1955 | + spin_lock(&mchdev_lock); | |
| 1956 | + if (!i915_mch_dev) { | |
| 1957 | + ret = false; | |
| 1958 | + goto out_unlock; | |
| 1959 | + } | |
| 1960 | + dev_priv = i915_mch_dev; | |
| 1961 | + | |
| 1962 | + if (dev_priv->max_delay < dev_priv->min_delay) | |
| 1963 | + dev_priv->max_delay++; | |
| 1964 | + | |
| 1965 | +out_unlock: | |
| 1966 | + spin_unlock(&mchdev_lock); | |
| 1967 | + | |
| 1968 | + return ret; | |
| 1578 | 1969 | } |
| 1970 | +EXPORT_SYMBOL_GPL(i915_gpu_lower); | |
| 1971 | + | |
| 1972 | +/** | |
| 1973 | + * i915_gpu_busy - indicate GPU business to IPS | |
| 1974 | + * | |
| 1975 | + * Tell the IPS driver whether or not the GPU is busy. | |
| 1976 | + */ | |
| 1977 | +bool i915_gpu_busy(void) | |
| 1978 | +{ | |
| 1979 | + struct drm_i915_private *dev_priv; | |
| 1980 | + bool ret = false; | |
| 1981 | + | |
| 1982 | + spin_lock(&mchdev_lock); | |
| 1983 | + if (!i915_mch_dev) | |
| 1984 | + goto out_unlock; | |
| 1985 | + dev_priv = i915_mch_dev; | |
| 1986 | + | |
| 1987 | + ret = dev_priv->busy; | |
| 1988 | + | |
| 1989 | +out_unlock: | |
| 1990 | + spin_unlock(&mchdev_lock); | |
| 1991 | + | |
| 1992 | + return ret; | |
| 1993 | +} | |
| 1994 | +EXPORT_SYMBOL_GPL(i915_gpu_busy); | |
| 1995 | + | |
| 1996 | +/** | |
| 1997 | + * i915_gpu_turbo_disable - disable graphics turbo | |
| 1998 | + * | |
| 1999 | + * Disable graphics turbo by resetting the max frequency and setting the | |
| 2000 | + * current frequency to the default. | |
| 2001 | + */ | |
| 2002 | +bool i915_gpu_turbo_disable(void) | |
| 2003 | +{ | |
| 2004 | + struct drm_i915_private *dev_priv; | |
| 2005 | + bool ret = true; | |
| 2006 | + | |
| 2007 | + spin_lock(&mchdev_lock); | |
| 2008 | + if (!i915_mch_dev) { | |
| 2009 | + ret = false; | |
| 2010 | + goto out_unlock; | |
| 2011 | + } | |
| 2012 | + dev_priv = i915_mch_dev; | |
| 2013 | + | |
| 2014 | + dev_priv->max_delay = dev_priv->fstart; | |
| 2015 | + | |
| 2016 | + if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart)) | |
| 2017 | + ret = false; | |
| 2018 | + | |
| 2019 | +out_unlock: | |
| 2020 | + spin_unlock(&mchdev_lock); | |
| 2021 | + | |
| 2022 | + return ret; | |
| 2023 | +} | |
| 2024 | +EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); | |
| 1579 | 2025 | |
| 1580 | 2026 | /** |
| 1581 | 2027 | * i915_driver_load - setup chip and create an initial config |
| @@ -1594,7 +2040,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) · 12 unmodified lines | ||
| 1594 | 2040 | resource_size_t base, size; |
| 1595 | 2041 | int ret = 0, mmio_bar; |
| 1596 | 2042 | uint32_t agp_size, prealloc_size, prealloc_start; |
| 1597 | − | |
| 1598 | 2043 | /* i915 has 4 more counters */ |
| 1599 | 2044 | dev->counters += 4; |
| 1600 | 2045 | dev->types[6] = _DRM_STAT_IRQ; |
| @@ -1672,6 +2117,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) · 71 unmodified lines | ||
| 1672 | 2117 | dev_priv->has_gem = 0; |
| 1673 | 2118 | } |
| 1674 | 2119 | |
| 2120 | + if (dev_priv->has_gem == 0 && | |
| 2121 | + drm_core_check_feature(dev, DRIVER_MODESET)) { | |
| 2122 | + DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); | |
| 2123 | + ret = -ENODEV; | |
| 2124 | + goto out_iomapfree; | |
| 2125 | + } | |
| 2126 | + | |
| 1675 | 2127 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
| 1676 | 2128 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
| 1677 | 2129 | if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) { |
| @@ -1691,7 +2143,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) · 13 unmodified lines | ||
| 1691 | 2143 | goto out_workqueue_free; |
| 1692 | 2144 | } |
| 1693 | 2145 | |
| 1694 | − i915_get_mem_freq(dev); | |
| 2146 | + if (IS_PINEVIEW(dev)) | |
| 2147 | + i915_pineview_get_mem_freq(dev); | |
| 2148 | + else if (IS_IRONLAKE(dev)) | |
| 2149 | + i915_ironlake_get_mem_freq(dev); | |
| 1695 | 2150 | |
| 1696 | 2151 | /* On the 945G/GM, the chipset reports the MSI capability on the |
| 1697 | 2152 | * integrated graphics even though the support isn't actually there |
| @@ -1709,7 +2164,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) · 11 unmodified lines | ||
| 1709 | 2164 | |
| 1710 | 2165 | spin_lock_init(&dev_priv->user_irq_lock); |
| 1711 | 2166 | spin_lock_init(&dev_priv->error_lock); |
| 1712 | − dev_priv->user_irq_refcount = 0; | |
| 1713 | 2167 | dev_priv->trace_irq_seqno = 0; |
| 1714 | 2168 | |
| 1715 | 2169 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
| @@ -1738,6 +2192,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) · 22 unmodified lines | ||
| 1738 | 2192 | |
| 1739 | 2193 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, |
| 1740 | 2194 | (unsigned long) dev); |
| 2195 | + | |
| 2196 | + spin_lock(&mchdev_lock); | |
| 2197 | + i915_mch_dev = dev_priv; | |
| 2198 | + dev_priv->mchdev_lock = &mchdev_lock; | |
| 2199 | + spin_unlock(&mchdev_lock); | |
| 2200 | + | |
| 1741 | 2201 | return 0; |
| 1742 | 2202 | |
| 1743 | 2203 | out_workqueue_free: |
| @@ -1759,6 +2219,10 @@ int i915_driver_unload(struct drm_device *dev) · 15 unmodified lines | ||
| 1759 | 2219 | |
| 1760 | 2220 | i915_destroy_error_state(dev); |
| 1761 | 2221 | |
| 2222 | + spin_lock(&mchdev_lock); | |
| 2223 | + i915_mch_dev = NULL; | |
| 2224 | + spin_unlock(&mchdev_lock); | |
| 2225 | + | |
| 1762 | 2226 | destroy_workqueue(dev_priv->wq); |
| 1763 | 2227 | del_timer_sync(&dev_priv->hangcheck_timer); |
| 1764 | 2228 | |
| @@ -60,95 +60,95 @@ extern int intel_agp_enabled; · 59 unmodified lines | ||
| 60 | 60 | .subdevice = PCI_ANY_ID, \ |
| 61 | 61 | .driver_data = (unsigned long) info } |
| 62 | 62 | |
| 63 | −const static struct intel_device_info intel_i830_info = { | |
| 63 | +static const struct intel_device_info intel_i830_info = { | |
| 64 | 64 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, |
| 65 | 65 | }; |
| 66 | 66 | |
| 67 | −const static struct intel_device_info intel_845g_info = { | |
| 67 | +static const struct intel_device_info intel_845g_info = { | |
| 68 | 68 | .is_i8xx = 1, |
| 69 | 69 | }; |
| 70 | 70 | |
| 71 | −const static struct intel_device_info intel_i85x_info = { | |
| 71 | +static const struct intel_device_info intel_i85x_info = { | |
| 72 | 72 | .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, |
| 73 | 73 | .cursor_needs_physical = 1, |
| 74 | 74 | }; |
| 75 | 75 | |
| 76 | −const static struct intel_device_info intel_i865g_info = { | |
| 76 | +static const struct intel_device_info intel_i865g_info = { | |
| 77 | 77 | .is_i8xx = 1, |
| 78 | 78 | }; |
| 79 | 79 | |
| 80 | −const static struct intel_device_info intel_i915g_info = { | |
| 80 | +static const struct intel_device_info intel_i915g_info = { | |
| 81 | 81 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, |
| 82 | 82 | }; |
| 83 | −const static struct intel_device_info intel_i915gm_info = { | |
| 83 | +static const struct intel_device_info intel_i915gm_info = { | |
| 84 | 84 | .is_i9xx = 1, .is_mobile = 1, |
| 85 | 85 | .cursor_needs_physical = 1, |
| 86 | 86 | }; |
| 87 | −const static struct intel_device_info intel_i945g_info = { | |
| 87 | +static const struct intel_device_info intel_i945g_info = { | |
| 88 | 88 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, |
| 89 | 89 | }; |
| 90 | −const static struct intel_device_info intel_i945gm_info = { | |
| 90 | +static const struct intel_device_info intel_i945gm_info = { | |
| 91 | 91 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, |
| 92 | 92 | .has_hotplug = 1, .cursor_needs_physical = 1, |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | −const static struct intel_device_info intel_i965g_info = { | |
| 95 | +static const struct intel_device_info intel_i965g_info = { | |
| 96 | 96 | .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, |
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | −const static struct intel_device_info intel_i965gm_info = { | |
| 99 | +static const struct intel_device_info intel_i965gm_info = { | |
| 100 | 100 | .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, |
| 101 | 101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, |
| 102 | 102 | .has_hotplug = 1, |
| 103 | 103 | }; |
| 104 | 104 | |
| 105 | −const static struct intel_device_info intel_g33_info = { | |
| 105 | +static const struct intel_device_info intel_g33_info = { | |
| 106 | 106 | .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
| 107 | 107 | .has_hotplug = 1, |
| 108 | 108 | }; |
| 109 | 109 | |
| 110 | −const static struct intel_device_info intel_g45_info = { | |
| 110 | +static const struct intel_device_info intel_g45_info = { | |
| 111 | 111 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
| 112 | 112 | .has_pipe_cxsr = 1, |
| 113 | 113 | .has_hotplug = 1, |
| 114 | 114 | }; |
| 115 | 115 | |
| 116 | −const static struct intel_device_info intel_gm45_info = { | |
| 116 | +static const struct intel_device_info intel_gm45_info = { | |
| 117 | 117 | .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, |
| 118 | 118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, |
| 119 | 119 | .has_pipe_cxsr = 1, |
| 120 | 120 | .has_hotplug = 1, |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | −const static struct intel_device_info intel_pineview_info = { | |
| 123 | +static const struct intel_device_info intel_pineview_info = { | |
| 124 | 124 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, |
| 125 | 125 | .need_gfx_hws = 1, |
| 126 | 126 | .has_hotplug = 1, |
| 127 | 127 | }; |
| 128 | 128 | |
| 129 | −const static struct intel_device_info intel_ironlake_d_info = { | |
| 129 | +static const struct intel_device_info intel_ironlake_d_info = { | |
| 130 | 130 | .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
| 131 | 131 | .has_pipe_cxsr = 1, |
| 132 | 132 | .has_hotplug = 1, |
| 133 | 133 | }; |
| 134 | 134 | |
| 135 | −const static struct intel_device_info intel_ironlake_m_info = { | |
| 135 | +static const struct intel_device_info intel_ironlake_m_info = { | |
| 136 | 136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, |
| 137 | 137 | .need_gfx_hws = 1, .has_rc6 = 1, |
| 138 | 138 | .has_hotplug = 1, |
| 139 | 139 | }; |
| 140 | 140 | |
| 141 | −const static struct intel_device_info intel_sandybridge_d_info = { | |
| 141 | +static const struct intel_device_info intel_sandybridge_d_info = { | |
| 142 | 142 | .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
| 143 | 143 | .has_hotplug = 1, .is_gen6 = 1, |
| 144 | 144 | }; |
| 145 | 145 | |
| 146 | −const static struct intel_device_info intel_sandybridge_m_info = { | |
| 146 | +static const struct intel_device_info intel_sandybridge_m_info = { | |
| 147 | 147 | .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
| 148 | 148 | .has_hotplug = 1, .is_gen6 = 1, |
| 149 | 149 | }; |
| 150 | 150 | |
| 151 | −const static struct pci_device_id pciidlist[] = { | |
| 151 | +static const struct pci_device_id pciidlist[] = { | |
| 152 | 152 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), |
| 153 | 153 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), |
| 154 | 154 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), |
| @@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags) · 185 unmodified lines | ||
| 340 | 340 | /* |
| 341 | 341 | * Clear request list |
| 342 | 342 | */ |
| 343 | − i915_gem_retire_requests(dev); | |
| 343 | + i915_gem_retire_requests(dev, &dev_priv->render_ring); | |
| 344 | 344 | |
| 345 | 345 | if (need_display) |
| 346 | 346 | i915_save_display(dev); |
| @@ -370,6 +370,7 @@ int i965_reset(struct drm_device *dev, u8 flags) · 23 unmodified lines | ||
| 370 | 370 | } |
| 371 | 371 | } else { |
| 372 | 372 | DRM_ERROR("Error occurred. Don't know how to reset this chip.\n"); |
| 373 | + mutex_unlock(&dev->struct_mutex); | |
| 373 | 374 | return -ENODEV; |
| 374 | 375 | } |
| 375 | 376 | |
| @@ -388,33 +389,10 @@ int i965_reset(struct drm_device *dev, u8 flags) · 12 unmodified lines | ||
| 388 | 389 | * switched away). |
| 389 | 390 | */ |
| 390 | 391 | if (drm_core_check_feature(dev, DRIVER_MODESET) || |
| 391 | − !dev_priv->mm.suspended) { | |
| 392 | − drm_i915_ring_buffer_t *ring = &dev_priv->ring; | |
| 393 | − struct drm_gem_object *obj = ring->ring_obj; | |
| 394 | − struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | |
| 392 | + !dev_priv->mm.suspended) { | |
| 393 | + struct intel_ring_buffer *ring = &dev_priv->render_ring; | |
| 395 | 394 | dev_priv->mm.suspended = 0; |
| 396 | − | |
| 397 | − /* Stop the ring if it's running. */ | |
| 398 | − I915_WRITE(PRB0_CTL, 0); | |
| 399 | − I915_WRITE(PRB0_TAIL, 0); | |
| 400 | − I915_WRITE(PRB0_HEAD, 0); | |
| 401 | − | |
| 402 | − /* Initialize the ring. */ | |
| 403 | − I915_WRITE(PRB0_START, obj_priv->gtt_offset); | |
| 404 | − I915_WRITE(PRB0_CTL, | |
| 405 | − ((obj->size - 4096) & RING_NR_PAGES) | | |
| 406 | − RING_NO_REPORT | | |
| 407 | − RING_VALID); | |
| 408 | − if (!drm_core_check_feature(dev, DRIVER_MODESET)) | |
| 409 | − i915_kernel_lost_context(dev); | |
| 410 | − else { | |
| 411 | − ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | |
| 412 | − ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | |
| 413 | − ring->space = ring->head - (ring->tail + 8); | |
| 414 | − if (ring->space < 0) | |
| 415 | − ring->space += ring->Size; | |
| 416 | − } | |
| 417 | − | |
| 395 | + ring->init(dev, ring); | |
| 418 | 396 | mutex_unlock(&dev->struct_mutex); |
| 419 | 397 | drm_irq_uninstall(dev); |
| 420 | 398 | drm_irq_install(dev); |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #include "i915_reg.h" |
| 34 | 34 | #include "intel_bios.h" |
| 35 | +#include "intel_ringbuffer.h" | |
| 35 | 36 | #include <linux/io-mapping.h> |
| 36 | 37 | |
| 37 | 38 | /* General customization: |
| @@ -55,6 +56,8 @@ enum plane { · 17 unmodified lines | ||
| 55 | 56 | |
| 56 | 57 | #define I915_NUM_PIPE 2 |
| 57 | 58 | |
| 59 | +#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) | |
| 60 | + | |
| 58 | 61 | /* Interface history: |
| 59 | 62 | * |
| 60 | 63 | * 1.1: Original. |
| @@ -89,16 +92,6 @@ struct drm_i915_gem_phys_object { · 28 unmodified lines | ||
| 89 | 92 | struct drm_gem_object *cur_obj; |
| 90 | 93 | }; |
| 91 | 94 | |
| 92 | −typedef struct _drm_i915_ring_buffer { | |
| 93 | − unsigned long Size; | |
| 94 | − u8 *virtual_start; | |
| 95 | − int head; | |
| 96 | − int tail; | |
| 97 | − int space; | |
| 98 | − drm_local_map_t map; | |
| 99 | − struct drm_gem_object *ring_obj; | |
| 100 | −} drm_i915_ring_buffer_t; | |
| 101 | − | |
| 102 | 95 | struct mem_block { |
| 103 | 96 | struct mem_block *next; |
| 104 | 97 | struct mem_block *prev; |
| @@ -241,17 +234,15 @@ typedef struct drm_i915_private { · 136 unmodified lines | ||
| 241 | 234 | void __iomem *regs; |
| 242 | 235 | |
| 243 | 236 | struct pci_dev *bridge_dev; |
| 244 | − drm_i915_ring_buffer_t ring; | |
| 237 | + struct intel_ring_buffer render_ring; | |
| 238 | + struct intel_ring_buffer bsd_ring; | |
| 245 | 239 | |
| 246 | 240 | drm_dma_handle_t *status_page_dmah; |
| 247 | − void *hw_status_page; | |
| 248 | 241 | void *seqno_page; |
| 249 | 242 | dma_addr_t dma_status_page; |
| 250 | 243 | uint32_t counter; |
| 251 | − unsigned int status_gfx_addr; | |
| 252 | 244 | unsigned int seqno_gfx_addr; |
| 253 | 245 | drm_local_map_t hws_map; |
| 254 | − struct drm_gem_object *hws_obj; | |
| 255 | 246 | struct drm_gem_object *seqno_obj; |
| 256 | 247 | struct drm_gem_object *pwrctx; |
| 257 | 248 | |
| @@ -267,8 +258,6 @@ typedef struct drm_i915_private { · 9 unmodified lines | ||
| 267 | 258 | atomic_t irq_received; |
| 268 | 259 | /** Protects user_irq_refcount and irq_mask_reg */ |
| 269 | 260 | spinlock_t user_irq_lock; |
| 270 | − /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ | |
| 271 | − int user_irq_refcount; | |
| 272 | 261 | u32 trace_irq_seqno; |
| 273 | 262 | /** Cached value of IMR to avoid reads in updating the bitfield */ |
| 274 | 263 | u32 irq_mask_reg; |
| @@ -289,6 +278,7 @@ typedef struct drm_i915_private { · 14 unmodified lines | ||
| 289 | 278 | struct mem_block *agp_heap; |
| 290 | 279 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
| 291 | 280 | int vblank_pipe; |
| 281 | + int num_pipe; | |
| 292 | 282 | |
| 293 | 283 | /* For hangcheck timer */ |
| 294 | 284 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ |
| @@ -334,7 +324,7 @@ typedef struct drm_i915_private { · 39 unmodified lines | ||
| 334 | 324 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
| 335 | 325 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
| 336 | 326 | |
| 337 | − unsigned int fsb_freq, mem_freq; | |
| 327 | + unsigned int fsb_freq, mem_freq, is_ddr3; | |
| 338 | 328 | |
| 339 | 329 | spinlock_t error_lock; |
| 340 | 330 | struct drm_i915_error_state *first_error; |
| @@ -514,18 +504,7 @@ typedef struct drm_i915_private { · 173 unmodified lines | ||
| 514 | 504 | */ |
| 515 | 505 | struct list_head shrink_list; |
| 516 | 506 | |
| 517 | − /** | |
| 518 | − * List of objects currently involved in rendering from the | |
| 519 | − * ringbuffer. | |
| 520 | − * | |
| 521 | − * Includes buffers having the contents of their GPU caches | |
| 522 | − * flushed, not necessarily primitives. last_rendering_seqno | |
| 523 | − * represents when the rendering involved will be completed. | |
| 524 | − * | |
| 525 | − * A reference is held on the buffer while on this list. | |
| 526 | − */ | |
| 527 | 507 | spinlock_t active_list_lock; |
| 528 | − struct list_head active_list; | |
| 529 | 508 | |
| 530 | 509 | /** |
| 531 | 510 | * List of objects which are not in the ringbuffer but which |
| @@ -562,12 +541,6 @@ typedef struct drm_i915_private { · 30 unmodified lines | ||
| 562 | 541 | /** LRU list of objects with fence regs on them. */ |
| 563 | 542 | struct list_head fence_list; |
| 564 | 543 | |
| 565 | − /** | |
| 566 | − * List of breadcrumbs associated with GPU requests currently | |
| 567 | − * outstanding. | |
| 568 | − */ | |
| 569 | − struct list_head request_list; | |
| 570 | − | |
| 571 | 544 | /** |
| 572 | 545 | * We leave the user IRQ off as much as possible, |
| 573 | 546 | * but this means that requests will finish and never |
| @@ -644,6 +617,18 @@ typedef struct drm_i915_private { · 70 unmodified lines | ||
| 644 | 617 | u8 cur_delay; |
| 645 | 618 | u8 min_delay; |
| 646 | 619 | u8 max_delay; |
| 620 | + u8 fmax; | |
| 621 | + u8 fstart; | |
| 622 | + | |
| 623 | + u64 last_count1; | |
| 624 | + unsigned long last_time1; | |
| 625 | + u64 last_count2; | |
| 626 | + struct timespec last_time2; | |
| 627 | + unsigned long gfx_power; | |
| 628 | + int c_m; | |
| 629 | + int r_t; | |
| 630 | + u8 corr; | |
| 631 | + spinlock_t *mchdev_lock; | |
| 647 | 632 | |
| 648 | 633 | enum no_fbc_reason no_fbc_reason; |
| 649 | 634 | |
| @@ -671,19 +656,64 @@ struct drm_i915_gem_object { · 21 unmodified lines | ||
| 671 | 656 | * (has pending rendering), and is not set if it's on inactive (ready |
| 672 | 657 | * to be unbound). |
| 673 | 658 | */ |
| 674 | − int active; | |
| 659 | + unsigned int active : 1; | |
| 675 | 660 | |
| 676 | 661 | /** |
| 677 | 662 | * This is set if the object has been written to since last bound |
| 678 | 663 | * to the GTT |
| 679 | 664 | */ |
| 680 | − int dirty; | |
| 665 | + unsigned int dirty : 1; | |
| 666 | + | |
| 667 | + /** | |
| 668 | + * Fence register bits (if any) for this object. Will be set | |
| 669 | + * as needed when mapped into the GTT. | |
| 670 | + * Protected by dev->struct_mutex. | |
| 671 | + * | |
| 672 | + * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) | |
| 673 | + */ | |
| 674 | + int fence_reg : 5; | |
| 675 | + | |
| 676 | + /** | |
| 677 | + * Used for checking the object doesn't appear more than once | |
| 678 | + * in an execbuffer object list. | |
| 679 | + */ | |
| 680 | + unsigned int in_execbuffer : 1; | |
| 681 | + | |
| 682 | + /** | |
| 683 | + * Advice: are the backing pages purgeable? | |
| 684 | + */ | |
| 685 | + unsigned int madv : 2; | |
| 686 | + | |
| 687 | + /** | |
| 688 | + * Refcount for the pages array. With the current locking scheme, there | |
| 689 | + * are at most two concurrent users: Binding a bo to the gtt and | |
| 690 | + * pwrite/pread using physical addresses. So two bits for a maximum | |
| 691 | + * of two users are enough. | |
| 692 | + */ | |
| 693 | + unsigned int pages_refcount : 2; | |
| 694 | +#define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3 | |
| 695 | + | |
| 696 | + /** | |
| 697 | + * Current tiling mode for the object. | |
| 698 | + */ | |
| 699 | + unsigned int tiling_mode : 2; | |
| 700 | + | |
| 701 | + /** How many users have pinned this object in GTT space. The following | |
| 702 | + * users can each hold at most one reference: pwrite/pread, pin_ioctl | |
| 703 | + * (via user_pin_count), execbuffer (objects are not allowed multiple | |
| 704 | + * times for the same batchbuffer), and the framebuffer code. When | |
| 705 | + * switching/pageflipping, the framebuffer code has at most two buffers | |
| 706 | + * pinned per crtc. | |
| 707 | + * | |
| 708 | + * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 | |
| 709 | + * bits with absolutely no headroom. So use 4 bits. */ | |
| 710 | + int pin_count : 4; | |
| 711 | +#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf | |
| 681 | 712 | |
| 682 | 713 | /** AGP memory structure for our GTT binding. */ |
| 683 | 714 | DRM_AGP_MEM *agp_mem; |
| 684 | 715 | |
| 685 | 716 | struct page **pages; |
| 686 | − int pages_refcount; | |
| 687 | 717 | |
| 688 | 718 | /** |
| 689 | 719 | * Current offset of the object in GTT space. |
| @@ -692,26 +722,18 @@ struct drm_i915_gem_object { · 2 unmodified lines | ||
| 692 | 722 | */ |
| 693 | 723 | uint32_t gtt_offset; |
| 694 | 724 | |
| 725 | + /* Which ring is refering to is this object */ | |
| 726 | + struct intel_ring_buffer *ring; | |
| 727 | + | |
| 695 | 728 | /** |
| 696 | 729 | * Fake offset for use by mmap(2) |
| 697 | 730 | */ |
| 698 | 731 | uint64_t mmap_offset; |
| 699 | 732 | |
| 700 | − /** | |
| 701 | − * Fence register bits (if any) for this object. Will be set | |
| 702 | − * as needed when mapped into the GTT. | |
| 703 | − * Protected by dev->struct_mutex. | |
| 704 | − */ | |
| 705 | − int fence_reg; | |
| 706 | − | |
| 707 | − /** How many users have pinned this object in GTT space */ | |
| 708 | − int pin_count; | |
| 709 | − | |
| 710 | 733 | /** Breadcrumb of last rendering to the buffer. */ |
| 711 | 734 | uint32_t last_rendering_seqno; |
| 712 | 735 | |
| 713 | − /** Current tiling mode for the object. */ | |
| 714 | − uint32_t tiling_mode; | |
| 736 | + /** Current tiling stride for the object, if it's tiled. */ | |
| 715 | 737 | uint32_t stride; |
| 716 | 738 | |
| 717 | 739 | /** Record of address bit 17 of each page at last unbind. */ |
| @@ -733,17 +755,6 @@ struct drm_i915_gem_object { · 15 unmodified lines | ||
| 733 | 755 | /** for phy allocated objects */ |
| 734 | 756 | struct drm_i915_gem_phys_object *phys_obj; |
| 735 | 757 | |
| 736 | − /** | |
| 737 | − * Used for checking the object doesn't appear more than once | |
| 738 | − * in an execbuffer object list. | |
| 739 | − */ | |
| 740 | − int in_execbuffer; | |
| 741 | − | |
| 742 | − /** | |
| 743 | − * Advice: are the backing pages purgeable? | |
| 744 | − */ | |
| 745 | − int madv; | |
| 746 | − | |
| 747 | 758 | /** |
| 748 | 759 | * Number of crtcs where this object is currently the fb, but |
| 749 | 760 | * will be page flipped away on the next vblank. When it |
| @@ -765,6 +776,9 @@ struct drm_i915_gem_object { · 15 unmodified lines | ||
| 765 | 776 | * an emission time with seqnos for tracking how far ahead of the GPU we are. |
| 766 | 777 | */ |
| 767 | 778 | struct drm_i915_gem_request { |
| 779 | + /** On Which ring this request was generated */ | |
| 780 | + struct intel_ring_buffer *ring; | |
| 781 | + | |
| 768 | 782 | /** GEM sequence number associated with this request. */ |
| 769 | 783 | uint32_t seqno; |
| 770 | 784 | |
| @@ -821,6 +835,11 @@ extern int i915_emit_box(struct drm_device *dev, · 50 unmodified lines | ||
| 821 | 835 | struct drm_clip_rect *boxes, |
| 822 | 836 | int i, int DR1, int DR4); |
| 823 | 837 | extern int i965_reset(struct drm_device *dev, u8 flags); |
| 838 | +extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); | |
| 839 | +extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); | |
| 840 | +extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); | |
| 841 | +extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); | |
| 842 | + | |
| 824 | 843 | |
| 825 | 844 | /* i915_irq.c */ |
| 826 | 845 | void i915_hangcheck_elapsed(unsigned long data); |
| @@ -829,9 +848,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data, · 2 unmodified lines | ||
| 829 | 848 | struct drm_file *file_priv); |
| 830 | 849 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
| 831 | 850 | struct drm_file *file_priv); |
| 832 | −void i915_user_irq_get(struct drm_device *dev); | |
| 833 | 851 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno); |
| 834 | −void i915_user_irq_put(struct drm_device *dev); | |
| 835 | 852 | extern void i915_enable_interrupt (struct drm_device *dev); |
| 836 | 853 | |
| 837 | 854 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
| @@ -849,6 +866,11 @@ extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); · 11 unmodified lines | ||
| 849 | 866 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
| 850 | 867 | struct drm_file *file_priv); |
| 851 | 868 | extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); |
| 869 | +extern void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask); | |
| 870 | +extern void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, | |
| 871 | + u32 mask); | |
| 872 | +extern void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, | |
| 873 | + u32 mask); | |
| 852 | 874 | |
| 853 | 875 | void |
| 854 | 876 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); |
| @@ -922,11 +944,13 @@ void i915_gem_object_unpin(struct drm_gem_object *obj); · 67 unmodified lines | ||
| 922 | 944 | int i915_gem_object_unbind(struct drm_gem_object *obj); |
| 923 | 945 | void i915_gem_release_mmap(struct drm_gem_object *obj); |
| 924 | 946 | void i915_gem_lastclose(struct drm_device *dev); |
| 925 | −uint32_t i915_get_gem_seqno(struct drm_device *dev); | |
| 947 | +uint32_t i915_get_gem_seqno(struct drm_device *dev, | |
| 948 | + struct intel_ring_buffer *ring); | |
| 926 | 949 | bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); |
| 927 | 950 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); |
| 928 | 951 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); |
| 929 | −void i915_gem_retire_requests(struct drm_device *dev); | |
| 952 | +void i915_gem_retire_requests(struct drm_device *dev, | |
| 953 | + struct intel_ring_buffer *ring); | |
| 930 | 954 | void i915_gem_retire_work_handler(struct work_struct *work); |
| 931 | 955 | void i915_gem_clflush_object(struct drm_gem_object *obj); |
| 932 | 956 | int i915_gem_object_set_domain(struct drm_gem_object *obj, |
| @@ -937,9 +961,13 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev); · 4 unmodified lines | ||
| 937 | 961 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
| 938 | 962 | unsigned long end); |
| 939 | 963 | int i915_gem_idle(struct drm_device *dev); |
| 940 | −uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |
| 941 | − uint32_t flush_domains); | |
| 942 | −int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible); | |
| 964 | +uint32_t i915_add_request(struct drm_device *dev, | |
| 965 | + struct drm_file *file_priv, | |
| 966 | + uint32_t flush_domains, | |
| 967 | + struct intel_ring_buffer *ring); | |
| 968 | +int i915_do_wait_request(struct drm_device *dev, | |
| 969 | + uint32_t seqno, int interruptible, | |
| 970 | + struct intel_ring_buffer *ring); | |
| 943 | 971 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
| 944 | 972 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
| 945 | 973 | int write); |
| @@ -1015,7 +1043,7 @@ extern void g4x_disable_fbc(struct drm_device *dev); · 69 unmodified lines | ||
| 1015 | 1043 | extern void intel_disable_fbc(struct drm_device *dev); |
| 1016 | 1044 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); |
| 1017 | 1045 | extern bool intel_fbc_enabled(struct drm_device *dev); |
| 1018 | − | |
| 1046 | +extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | |
| 1019 | 1047 | extern void intel_detect_pch (struct drm_device *dev); |
| 1020 | 1048 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
| 1021 | 1049 | |
| @@ -1026,7 +1054,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); · 4 unmodified lines | ||
| 1026 | 1054 | * has access to the ring. |
| 1027 | 1055 | */ |
| 1028 | 1056 | #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ |
| 1029 | − if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \ | |
| 1057 | + if (((drm_i915_private_t *)dev->dev_private)->render_ring.gem_object \ | |
| 1058 | + == NULL) \ | |
| 1030 | 1059 | LOCK_TEST_WITH_RETURN(dev, file_priv); \ |
| 1031 | 1060 | } while (0) |
| 1032 | 1061 | |
| @@ -1039,35 +1068,31 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); · 6 unmodified lines | ||
| 1039 | 1068 | #define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) |
| 1040 | 1069 | #define I915_READ64(reg) readq(dev_priv->regs + (reg)) |
| 1041 | 1070 | #define POSTING_READ(reg) (void)I915_READ(reg) |
| 1071 | +#define POSTING_READ16(reg) (void)I915_READ16(reg) | |
| 1042 | 1072 | |
| 1043 | 1073 | #define I915_VERBOSE 0 |
| 1044 | 1074 | |
| 1045 | −#define RING_LOCALS volatile unsigned int *ring_virt__; | |
| 1046 | − | |
| 1047 | −#define BEGIN_LP_RING(n) do { \ | |
| 1048 | − int bytes__ = 4*(n); \ | |
| 1049 | − if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ | |
| 1050 | − /* a wrap must occur between instructions so pad beforehand */ \ | |
| 1051 | − if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \ | |
| 1052 | − i915_wrap_ring(dev); \ | |
| 1053 | − if (unlikely (dev_priv->ring.space < bytes__)) \ | |
| 1054 | − i915_wait_ring(dev, bytes__, __func__); \ | |
| 1055 | − ring_virt__ = (unsigned int *) \ | |
| 1056 | − (dev_priv->ring.virtual_start + dev_priv->ring.tail); \ | |
| 1057 | − dev_priv->ring.tail += bytes__; \ | |
| 1058 | − dev_priv->ring.tail &= dev_priv->ring.Size - 1; \ | |
| 1059 | − dev_priv->ring.space -= bytes__; \ | |
| 1075 | +#define BEGIN_LP_RING(n) do { \ | |
| 1076 | + drm_i915_private_t *dev_priv = dev->dev_private; \ | |
| 1077 | + if (I915_VERBOSE) \ | |
| 1078 | + DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ | |
| 1079 | + intel_ring_begin(dev, &dev_priv->render_ring, 4*(n)); \ | |
| 1060 | 1080 | } while (0) |
| 1061 | 1081 | |
| 1062 | −#define OUT_RING(n) do { \ | |
| 1063 | − if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ | |
| 1064 | − *ring_virt__++ = (n); \ | |
| 1082 | + | |
| 1083 | +#define OUT_RING(x) do { \ | |
| 1084 | + drm_i915_private_t *dev_priv = dev->dev_private; \ | |
| 1085 | + if (I915_VERBOSE) \ | |
| 1086 | + DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ | |
| 1087 | + intel_ring_emit(dev, &dev_priv->render_ring, x); \ | |
| 1065 | 1088 | } while (0) |
| 1066 | 1089 | |
| 1067 | 1090 | #define ADVANCE_LP_RING() do { \ |
| 1091 | + drm_i915_private_t *dev_priv = dev->dev_private; \ | |
| 1068 | 1092 | if (I915_VERBOSE) \ |
| 1069 | − DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \ | |
| 1070 | − I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \ | |
| 1093 | + DRM_DEBUG("ADVANCE_LP_RING %x\n", \ | |
| 1094 | + dev_priv->render_ring.tail); \ | |
| 1095 | + intel_ring_advance(dev, &dev_priv->render_ring); \ | |
| 1071 | 1096 | } while(0) |
| 1072 | 1097 | |
| 1073 | 1098 | /** |
| @@ -1085,14 +1110,12 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); · 11 unmodified lines | ||
| 1085 | 1110 | * |
| 1086 | 1111 | * The area from dword 0x20 to 0x3ff is available for driver usage. |
| 1087 | 1112 | */ |
| 1088 | −#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) | |
| 1113 | +#define READ_HWSP(dev_priv, reg) (((volatile u32 *)\ | |
| 1114 | + (dev_priv->render_ring.status_page.page_addr))[reg]) | |
| 1089 | 1115 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) |
| 1090 | 1116 | #define I915_GEM_HWS_INDEX 0x20 |
| 1091 | 1117 | #define I915_BREADCRUMB_INDEX 0x21 |
| 1092 | 1118 | |
| 1093 | −extern int i915_wrap_ring(struct drm_device * dev); | |
| 1094 | −extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |
| 1095 | − | |
| 1096 | 1119 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) |
| 1097 | 1120 | |
| 1098 | 1121 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
| @@ -1138,6 +1161,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); · 39 unmodified lines | ||
| 1138 | 1161 | (dev)->pci_device == 0x2A42 || \ |
| 1139 | 1162 | (dev)->pci_device == 0x2E42) |
| 1140 | 1163 | |
| 1164 | +#define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) | |
| 1141 | 1165 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
| 1142 | 1166 | |
| 1143 | 1167 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte |
| @@ -35,8 +35,6 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <linux/swap.h> |
| 36 | 36 | #include <linux/pci.h> |
| 37 | 37 | |
| 38 | −#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) | |
| 39 | − | |
| 40 | 38 | static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
| 41 | 39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
| 42 | 40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
| @@ -169,7 +167,7 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) · 126 unmodified lines | ||
| 169 | 167 | obj_priv->tiling_mode != I915_TILING_NONE; |
| 170 | 168 | } |
| 171 | 169 | |
| 172 | −static inline int | |
| 170 | +static inline void | |
| 173 | 171 | slow_shmem_copy(struct page *dst_page, |
| 174 | 172 | int dst_offset, |
| 175 | 173 | struct page *src_page, |
| @@ -178,25 +176,16 @@ slow_shmem_copy(struct page *dst_page, · 2 unmodified lines | ||
| 178 | 176 | { |
| 179 | 177 | char *dst_vaddr, *src_vaddr; |
| 180 | 178 | |
| 181 | − dst_vaddr = kmap_atomic(dst_page, KM_USER0); | |
| 182 | − if (dst_vaddr == NULL) | |
| 183 | − return -ENOMEM; | |
| 184 | − | |
| 185 | − src_vaddr = kmap_atomic(src_page, KM_USER1); | |
| 186 | − if (src_vaddr == NULL) { | |
| 187 | − kunmap_atomic(dst_vaddr, KM_USER0); | |
| 188 | − return -ENOMEM; | |
| 189 | − } | |
| 179 | + dst_vaddr = kmap(dst_page); | |
| 180 | + src_vaddr = kmap(src_page); | |
| 190 | 181 | |
| 191 | 182 | memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); |
| 192 | 183 | |
| 193 | − kunmap_atomic(src_vaddr, KM_USER1); | |
| 194 | − kunmap_atomic(dst_vaddr, KM_USER0); | |
| 195 | − | |
| 196 | − return 0; | |
| 184 | + kunmap(src_page); | |
| 185 | + kunmap(dst_page); | |
| 197 | 186 | } |
| 198 | 187 | |
| 199 | −static inline int | |
| 188 | +static inline void | |
| 200 | 189 | slow_shmem_bit17_copy(struct page *gpu_page, |
| 201 | 190 | int gpu_offset, |
| 202 | 191 | struct page *cpu_page, |
| @@ -216,15 +205,8 @@ slow_shmem_bit17_copy(struct page *gpu_page, · 13 unmodified lines | ||
| 216 | 205 | cpu_page, cpu_offset, length); |
| 217 | 206 | } |
| 218 | 207 | |
| 219 | − gpu_vaddr = kmap_atomic(gpu_page, KM_USER0); | |
| 220 | − if (gpu_vaddr == NULL) | |
| 221 | − return -ENOMEM; | |
| 222 | − | |
| 223 | − cpu_vaddr = kmap_atomic(cpu_page, KM_USER1); | |
| 224 | − if (cpu_vaddr == NULL) { | |
| 225 | − kunmap_atomic(gpu_vaddr, KM_USER0); | |
| 226 | − return -ENOMEM; | |
| 227 | − } | |
| 208 | + gpu_vaddr = kmap(gpu_page); | |
| 209 | + cpu_vaddr = kmap(cpu_page); | |
| 228 | 210 | |
| 229 | 211 | /* Copy the data, XORing A6 with A17 (1). The user already knows he's |
| 230 | 212 | * XORing with the other bits (A9 for Y, A9 and A10 for X) |
| @@ -248,10 +230,8 @@ slow_shmem_bit17_copy(struct page *gpu_page, · 17 unmodified lines | ||
| 248 | 230 | length -= this_length; |
| 249 | 231 | } |
| 250 | 232 | |
| 251 | − kunmap_atomic(cpu_vaddr, KM_USER1); | |
| 252 | − kunmap_atomic(gpu_vaddr, KM_USER0); | |
| 253 | − | |
| 254 | − return 0; | |
| 233 | + kunmap(cpu_page); | |
| 234 | + kunmap(gpu_page); | |
| 255 | 235 | } |
| 256 | 236 | |
| 257 | 237 | /** |
| @@ -427,21 +407,19 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, · 169 unmodified lines | ||
| 427 | 407 | page_length = PAGE_SIZE - data_page_offset; |
| 428 | 408 | |
| 429 | 409 | if (do_bit17_swizzling) { |
| 430 | − ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | |
| 431 | − shmem_page_offset, | |
| 432 | − user_pages[data_page_index], | |
| 433 | − data_page_offset, | |
| 434 | − page_length, | |
| 435 | − 1); | |
| 436 | − } else { | |
| 437 | − ret = slow_shmem_copy(user_pages[data_page_index], | |
| 438 | − data_page_offset, | |
| 439 | − obj_priv->pages[shmem_page_index], | |
| 410 | + slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | |
| 440 | 411 | shmem_page_offset, |
| 441 | − page_length); | |
| 412 | + user_pages[data_page_index], | |
| 413 | + data_page_offset, | |
| 414 | + page_length, | |
| 415 | + 1); | |
| 416 | + } else { | |
| 417 | + slow_shmem_copy(user_pages[data_page_index], | |
| 418 | + data_page_offset, | |
| 419 | + obj_priv->pages[shmem_page_index], | |
| 420 | + shmem_page_offset, | |
| 421 | + page_length); | |
| 442 | 422 | } |
| 443 | − if (ret) | |
| 444 | − goto fail_put_pages; | |
| 445 | 423 | |
| 446 | 424 | remain -= page_length; |
| 447 | 425 | data_ptr += page_length; |
| @@ -531,25 +509,24 @@ fast_user_write(struct io_mapping *mapping, · 83 unmodified lines | ||
| 531 | 509 | * page faults |
| 532 | 510 | */ |
| 533 | 511 | |
| 534 | −static inline int | |
| 512 | +static inline void | |
| 535 | 513 | slow_kernel_write(struct io_mapping *mapping, |
| 536 | 514 | loff_t gtt_base, int gtt_offset, |
| 537 | 515 | struct page *user_page, int user_offset, |
| 538 | 516 | int length) |
| 539 | 517 | { |
| 540 | − char *src_vaddr, *dst_vaddr; | |
| 541 | − unsigned long unwritten; | |
| 518 | + char __iomem *dst_vaddr; | |
| 519 | + char *src_vaddr; | |
| 542 | 520 | |
| 543 | − dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base); | |
| 544 | − src_vaddr = kmap_atomic(user_page, KM_USER1); | |
| 545 | − unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset, | |
| 546 | − src_vaddr + user_offset, | |
| 547 | − length); | |
| 548 | − kunmap_atomic(src_vaddr, KM_USER1); | |
| 549 | − io_mapping_unmap_atomic(dst_vaddr); | |
| 550 | − if (unwritten) | |
| 551 | − return -EFAULT; | |
| 552 | − return 0; | |
| 521 | + dst_vaddr = io_mapping_map_wc(mapping, gtt_base); | |
| 522 | + src_vaddr = kmap(user_page); | |
| 523 | + | |
| 524 | + memcpy_toio(dst_vaddr + gtt_offset, | |
| 525 | + src_vaddr + user_offset, | |
| 526 | + length); | |
| 527 | + | |
| 528 | + kunmap(user_page); | |
| 529 | + io_mapping_unmap(dst_vaddr); | |
| 553 | 530 | } |
| 554 | 531 | |
| 555 | 532 | static inline int |
| @@ -722,18 +699,11 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, · 166 unmodified lines | ||
| 722 | 699 | if ((data_page_offset + page_length) > PAGE_SIZE) |
| 723 | 700 | page_length = PAGE_SIZE - data_page_offset; |
| 724 | 701 | |
| 725 | − ret = slow_kernel_write(dev_priv->mm.gtt_mapping, | |
| 726 | − gtt_page_base, gtt_page_offset, | |
| 727 | − user_pages[data_page_index], | |
| 728 | − data_page_offset, | |
| 729 | − page_length); | |
| 730 | − | |
| 731 | − /* If we get a fault while copying data, then (presumably) our | |
| 732 | − * source page isn't available. Return the error and we'll | |
| 733 | − * retry in the slow path. | |
| 734 | − */ | |
| 735 | − if (ret) | |
| 736 | − goto out_unpin_object; | |
| 702 | + slow_kernel_write(dev_priv->mm.gtt_mapping, | |
| 703 | + gtt_page_base, gtt_page_offset, | |
| 704 | + user_pages[data_page_index], | |
| 705 | + data_page_offset, | |
| 706 | + page_length); | |
| 737 | 707 | |
| 738 | 708 | remain -= page_length; |
| 739 | 709 | offset += page_length; |
| @@ -902,21 +872,19 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, · 162 unmodified lines | ||
| 902 | 872 | page_length = PAGE_SIZE - data_page_offset; |
| 903 | 873 | |
| 904 | 874 | if (do_bit17_swizzling) { |
| 905 | − ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | |
| 906 | − shmem_page_offset, | |
| 907 | − user_pages[data_page_index], | |
| 908 | − data_page_offset, | |
| 909 | − page_length, | |
| 910 | − 0); | |
| 911 | − } else { | |
| 912 | − ret = slow_shmem_copy(obj_priv->pages[shmem_page_index], | |
| 875 | + slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | |
| 913 | 876 | shmem_page_offset, |
| 914 | 877 | user_pages[data_page_index], |
| 915 | 878 | data_page_offset, |
| 916 | − page_length); | |
| 879 | + page_length, | |
| 880 | + 0); | |
| 881 | + } else { | |
| 882 | + slow_shmem_copy(obj_priv->pages[shmem_page_index], | |
| 883 | + shmem_page_offset, | |
| 884 | + user_pages[data_page_index], | |
| 885 | + data_page_offset, | |
| 886 | + page_length); | |
| 917 | 887 | } |
| 918 | − if (ret) | |
| 919 | − goto fail_put_pages; | |
| 920 | 888 | |
| 921 | 889 | remain -= page_length; |
| 922 | 890 | data_ptr += page_length; |
| @@ -973,7 +941,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, · 50 unmodified lines | ||
| 973 | 941 | if (obj_priv->phys_obj) |
| 974 | 942 | ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); |
| 975 | 943 | else if (obj_priv->tiling_mode == I915_TILING_NONE && |
| 976 | − dev->gtt_total != 0) { | |
| 944 | + dev->gtt_total != 0 && | |
| 945 | + obj->write_domain != I915_GEM_DOMAIN_CPU) { | |
| 977 | 946 | ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv); |
| 978 | 947 | if (ret == -EFAULT) { |
| 979 | 948 | ret = i915_gem_gtt_pwrite_slow(dev, obj, args, |
| @@ -1484,11 +1453,14 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) · 504 unmodified lines | ||
| 1484 | 1453 | } |
| 1485 | 1454 | |
| 1486 | 1455 | static void |
| 1487 | −i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) | |
| 1456 | +i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno, | |
| 1457 | + struct intel_ring_buffer *ring) | |
| 1488 | 1458 | { |
| 1489 | 1459 | struct drm_device *dev = obj->dev; |
| 1490 | 1460 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1491 | 1461 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 1462 | + BUG_ON(ring == NULL); | |
| 1463 | + obj_priv->ring = ring; | |
| 1492 | 1464 | |
| 1493 | 1465 | /* Add a reference if we're newly entering the active list. */ |
| 1494 | 1466 | if (!obj_priv->active) { |
| @@ -1497,8 +1469,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) · 2 unmodified lines | ||
| 1497 | 1469 | } |
| 1498 | 1470 | /* Move from whatever list we were on to the tail of execution. */ |
| 1499 | 1471 | spin_lock(&dev_priv->mm.active_list_lock); |
| 1500 | − list_move_tail(&obj_priv->list, | |
| 1501 | − &dev_priv->mm.active_list); | |
| 1472 | + list_move_tail(&obj_priv->list, &ring->active_list); | |
| 1502 | 1473 | spin_unlock(&dev_priv->mm.active_list_lock); |
| 1503 | 1474 | obj_priv->last_rendering_seqno = seqno; |
| 1504 | 1475 | } |
| @@ -1551,6 +1522,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) · 46 unmodified lines | ||
| 1551 | 1522 | BUG_ON(!list_empty(&obj_priv->gpu_write_list)); |
| 1552 | 1523 | |
| 1553 | 1524 | obj_priv->last_rendering_seqno = 0; |
| 1525 | + obj_priv->ring = NULL; | |
| 1554 | 1526 | if (obj_priv->active) { |
| 1555 | 1527 | obj_priv->active = 0; |
| 1556 | 1528 | drm_gem_object_unreference(obj); |
| @@ -1560,7 +1532,8 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) · 3 unmodified lines | ||
| 1560 | 1532 | |
| 1561 | 1533 | static void |
| 1562 | 1534 | i915_gem_process_flushing_list(struct drm_device *dev, |
| 1563 | − uint32_t flush_domains, uint32_t seqno) | |
| 1535 | + uint32_t flush_domains, uint32_t seqno, | |
| 1536 | + struct intel_ring_buffer *ring) | |
| 1564 | 1537 | { |
| 1565 | 1538 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1566 | 1539 | struct drm_i915_gem_object *obj_priv, *next; |
| @@ -1571,12 +1544,13 @@ i915_gem_process_flushing_list(struct drm_device *dev, · 4 unmodified lines | ||
| 1571 | 1544 | struct drm_gem_object *obj = &obj_priv->base; |
| 1572 | 1545 | |
| 1573 | 1546 | if ((obj->write_domain & flush_domains) == |
| 1574 | − obj->write_domain) { | |
| 1547 | + obj->write_domain && | |
| 1548 | + obj_priv->ring->ring_flag == ring->ring_flag) { | |
| 1575 | 1549 | uint32_t old_write_domain = obj->write_domain; |
| 1576 | 1550 | |
| 1577 | 1551 | obj->write_domain = 0; |
| 1578 | 1552 | list_del_init(&obj_priv->gpu_write_list); |
| 1579 | − i915_gem_object_move_to_active(obj, seqno); | |
| 1553 | + i915_gem_object_move_to_active(obj, seqno, ring); | |
| 1580 | 1554 | |
| 1581 | 1555 | /* update the fence lru list */ |
| 1582 | 1556 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
| @@ -1593,31 +1567,15 @@ i915_gem_process_flushing_list(struct drm_device *dev, · 10 unmodified lines | ||
| 1593 | 1567 | } |
| 1594 | 1568 | } |
| 1595 | 1569 | |
| 1596 | −#define PIPE_CONTROL_FLUSH(addr) \ | |
| 1597 | − OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | |
| 1598 | − PIPE_CONTROL_DEPTH_STALL); \ | |
| 1599 | − OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ | |
| 1600 | − OUT_RING(0); \ | |
| 1601 | − OUT_RING(0); \ | |
| 1602 | − | |
| 1603 | −/** | |
| 1604 | − * Creates a new sequence number, emitting a write of it to the status page | |
| 1605 | − * plus an interrupt, which will trigger i915_user_interrupt_handler. | |
| 1606 | − * | |
| 1607 | − * Must be called with struct_lock held. | |
| 1608 | − * | |
| 1609 | − * Returned sequence numbers are nonzero on success. | |
| 1610 | − */ | |
| 1611 | 1570 | uint32_t |
| 1612 | 1571 | i915_add_request(struct drm_device *dev, struct drm_file *file_priv, |
| 1613 | − uint32_t flush_domains) | |
| 1572 | + uint32_t flush_domains, struct intel_ring_buffer *ring) | |
| 1614 | 1573 | { |
| 1615 | 1574 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1616 | 1575 | struct drm_i915_file_private *i915_file_priv = NULL; |
| 1617 | 1576 | struct drm_i915_gem_request *request; |
| 1618 | 1577 | uint32_t seqno; |
| 1619 | 1578 | int was_empty; |
| 1620 | − RING_LOCALS; | |
| 1621 | 1579 | |
| 1622 | 1580 | if (file_priv != NULL) |
| 1623 | 1581 | i915_file_priv = file_priv->driver_priv; |
| @@ -1626,62 +1584,14 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, · 2 unmodified lines | ||
| 1626 | 1584 | if (request == NULL) |
| 1627 | 1585 | return 0; |
| 1628 | 1586 | |
| 1629 | − /* Grab the seqno we're going to make this request be, and bump the | |
| 1630 | − * next (skipping 0 so it can be the reserved no-seqno value). | |
| 1631 | − */ | |
| 1632 | − seqno = dev_priv->mm.next_gem_seqno; | |
| 1633 | − dev_priv->mm.next_gem_seqno++; | |
| 1634 | − if (dev_priv->mm.next_gem_seqno == 0) | |
| 1635 | − dev_priv->mm.next_gem_seqno++; | |
| 1636 | − | |
| 1637 | − if (HAS_PIPE_CONTROL(dev)) { | |
| 1638 | − u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; | |
| 1639 | − | |
| 1640 | − /* | |
| 1641 | − * Workaround qword write incoherence by flushing the | |
| 1642 | − * PIPE_NOTIFY buffers out to memory before requesting | |
| 1643 | − * an interrupt. | |
| 1644 | − */ | |
| 1645 | − BEGIN_LP_RING(32); | |
| 1646 | − OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | |
| 1647 | − PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | |
| 1648 | − OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | |
| 1649 | − OUT_RING(seqno); | |
| 1650 | − OUT_RING(0); | |
| 1651 | − PIPE_CONTROL_FLUSH(scratch_addr); | |
| 1652 | − scratch_addr += 128; /* write to separate cachelines */ | |
| 1653 | − PIPE_CONTROL_FLUSH(scratch_addr); | |
| 1654 | − scratch_addr += 128; | |
| 1655 | − PIPE_CONTROL_FLUSH(scratch_addr); | |
| 1656 | − scratch_addr += 128; | |
| 1657 | − PIPE_CONTROL_FLUSH(scratch_addr); | |
| 1658 | − scratch_addr += 128; | |
| 1659 | − PIPE_CONTROL_FLUSH(scratch_addr); | |
| 1660 | − scratch_addr += 128; | |
| 1661 | − PIPE_CONTROL_FLUSH(scratch_addr); | |
| 1662 | − OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | |
| 1663 | − PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | |
| 1664 | − PIPE_CONTROL_NOTIFY); | |
| 1665 | − OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | |
| 1666 | − OUT_RING(seqno); | |
| 1667 | − OUT_RING(0); | |
| 1668 | − ADVANCE_LP_RING(); | |
| 1669 | − } else { | |
| 1670 | − BEGIN_LP_RING(4); | |
| 1671 | − OUT_RING(MI_STORE_DWORD_INDEX); | |
| 1672 | − OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | |
| 1673 | − OUT_RING(seqno); | |
| 1674 | − | |
| 1675 | − OUT_RING(MI_USER_INTERRUPT); | |
| 1676 | − ADVANCE_LP_RING(); | |
| 1677 | − } | |
| 1678 | − | |
| 1679 | − DRM_DEBUG_DRIVER("%d\n", seqno); | |
| 1587 | + seqno = ring->add_request(dev, ring, file_priv, flush_domains); | |
| 1680 | 1588 | |
| 1681 | 1589 | request->seqno = seqno; |
| 1590 | + request->ring = ring; | |
| 1682 | 1591 | request->emitted_jiffies = jiffies; |
| 1683 | − was_empty = list_empty(&dev_priv->mm.request_list); | |
| 1684 | − list_add_tail(&request->list, &dev_priv->mm.request_list); | |
| 1592 | + was_empty = list_empty(&ring->request_list); | |
| 1593 | + list_add_tail(&request->list, &ring->request_list); | |
| 1594 | + | |
| 1685 | 1595 | if (i915_file_priv) { |
| 1686 | 1596 | list_add_tail(&request->client_list, |
| 1687 | 1597 | &i915_file_priv->mm.request_list); |
| @@ -1693,7 +1603,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, · 5 unmodified lines | ||
| 1693 | 1603 | * domain we're flushing with our flush. |
| 1694 | 1604 | */ |
| 1695 | 1605 | if (flush_domains != 0) |
| 1696 | − i915_gem_process_flushing_list(dev, flush_domains, seqno); | |
| 1606 | + i915_gem_process_flushing_list(dev, flush_domains, seqno, ring); | |
| 1697 | 1607 | |
| 1698 | 1608 | if (!dev_priv->mm.suspended) { |
| 1699 | 1609 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
| @@ -1710,20 +1620,16 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, · 10 unmodified lines | ||
| 1710 | 1620 | * before signalling the CPU |
| 1711 | 1621 | */ |
| 1712 | 1622 | static uint32_t |
| 1713 | −i915_retire_commands(struct drm_device *dev) | |
| 1623 | +i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) | |
| 1714 | 1624 | { |
| 1715 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 1716 | − uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | |
| 1717 | 1625 | uint32_t flush_domains = 0; |
| 1718 | − RING_LOCALS; | |
| 1719 | 1626 | |
| 1720 | 1627 | /* The sampler always gets flushed on i965 (sigh) */ |
| 1721 | 1628 | if (IS_I965G(dev)) |
| 1722 | 1629 | flush_domains |= I915_GEM_DOMAIN_SAMPLER; |
| 1723 | − BEGIN_LP_RING(2); | |
| 1724 | − OUT_RING(cmd); | |
| 1725 | − OUT_RING(0); /* noop */ | |
| 1726 | − ADVANCE_LP_RING(); | |
| 1630 | + | |
| 1631 | + ring->flush(dev, ring, | |
| 1632 | + I915_GEM_DOMAIN_COMMAND, flush_domains); | |
| 1727 | 1633 | return flush_domains; |
| 1728 | 1634 | } |
| 1729 | 1635 | |
| @@ -1743,11 +1649,11 @@ i915_gem_retire_request(struct drm_device *dev, · 13 unmodified lines | ||
| 1743 | 1649 | * by the ringbuffer to the flushing/inactive lists as appropriate. |
| 1744 | 1650 | */ |
| 1745 | 1651 | spin_lock(&dev_priv->mm.active_list_lock); |
| 1746 | − while (!list_empty(&dev_priv->mm.active_list)) { | |
| 1652 | + while (!list_empty(&request->ring->active_list)) { | |
| 1747 | 1653 | struct drm_gem_object *obj; |
| 1748 | 1654 | struct drm_i915_gem_object *obj_priv; |
| 1749 | 1655 | |
| 1750 | − obj_priv = list_first_entry(&dev_priv->mm.active_list, | |
| 1656 | + obj_priv = list_first_entry(&request->ring->active_list, | |
| 1751 | 1657 | struct drm_i915_gem_object, |
| 1752 | 1658 | list); |
| 1753 | 1659 | obj = &obj_priv->base; |
| @@ -1794,35 +1700,33 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) · 40 unmodified lines | ||
| 1794 | 1700 | } |
| 1795 | 1701 | |
| 1796 | 1702 | uint32_t |
| 1797 | −i915_get_gem_seqno(struct drm_device *dev) | |
| 1703 | +i915_get_gem_seqno(struct drm_device *dev, | |
| 1704 | + struct intel_ring_buffer *ring) | |
| 1798 | 1705 | { |
| 1799 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 1800 | − | |
| 1801 | − if (HAS_PIPE_CONTROL(dev)) | |
| 1802 | − return ((volatile u32 *)(dev_priv->seqno_page))[0]; | |
| 1803 | − else | |
| 1804 | − return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); | |
| 1706 | + return ring->get_gem_seqno(dev, ring); | |
| 1805 | 1707 | } |
| 1806 | 1708 | |
| 1807 | 1709 | /** |
| 1808 | 1710 | * This function clears the request list as sequence numbers are passed. |
| 1809 | 1711 | */ |
| 1810 | 1712 | void |
| 1811 | −i915_gem_retire_requests(struct drm_device *dev) | |
| 1713 | +i915_gem_retire_requests(struct drm_device *dev, | |
| 1714 | + struct intel_ring_buffer *ring) | |
| 1812 | 1715 | { |
| 1813 | 1716 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1814 | 1717 | uint32_t seqno; |
| 1815 | 1718 | |
| 1816 | − if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list)) | |
| 1719 | + if (!ring->status_page.page_addr | |
| 1720 | + || list_empty(&ring->request_list)) | |
| 1817 | 1721 | return; |
| 1818 | 1722 | |
| 1819 | − seqno = i915_get_gem_seqno(dev); | |
| 1723 | + seqno = i915_get_gem_seqno(dev, ring); | |
| 1820 | 1724 | |
| 1821 | − while (!list_empty(&dev_priv->mm.request_list)) { | |
| 1725 | + while (!list_empty(&ring->request_list)) { | |
| 1822 | 1726 | struct drm_i915_gem_request *request; |
| 1823 | 1727 | uint32_t retiring_seqno; |
| 1824 | 1728 | |
| 1825 | − request = list_first_entry(&dev_priv->mm.request_list, | |
| 1729 | + request = list_first_entry(&ring->request_list, | |
| 1826 | 1730 | struct drm_i915_gem_request, |
| 1827 | 1731 | list); |
| 1828 | 1732 | retiring_seqno = request->seqno; |
| @@ -1840,7 +1744,8 @@ i915_gem_retire_requests(struct drm_device *dev) · 11 unmodified lines | ||
| 1840 | 1744 | |
| 1841 | 1745 | if (unlikely (dev_priv->trace_irq_seqno && |
| 1842 | 1746 | i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { |
| 1843 | − i915_user_irq_put(dev); | |
| 1747 | + | |
| 1748 | + ring->user_irq_put(dev, ring); | |
| 1844 | 1749 | dev_priv->trace_irq_seqno = 0; |
| 1845 | 1750 | } |
| 1846 | 1751 | } |
| @@ -1856,15 +1761,22 @@ i915_gem_retire_work_handler(struct work_struct *work) · 9 unmodified lines | ||
| 1856 | 1761 | dev = dev_priv->dev; |
| 1857 | 1762 | |
| 1858 | 1763 | mutex_lock(&dev->struct_mutex); |
| 1859 | − i915_gem_retire_requests(dev); | |
| 1764 | + i915_gem_retire_requests(dev, &dev_priv->render_ring); | |
| 1765 | + | |
| 1766 | + if (HAS_BSD(dev)) | |
| 1767 | + i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | |
| 1768 | + | |
| 1860 | 1769 | if (!dev_priv->mm.suspended && |
| 1861 | − !list_empty(&dev_priv->mm.request_list)) | |
| 1770 | + (!list_empty(&dev_priv->render_ring.request_list) || | |
| 1771 | + (HAS_BSD(dev) && | |
| 1772 | + !list_empty(&dev_priv->bsd_ring.request_list)))) | |
| 1862 | 1773 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
| 1863 | 1774 | mutex_unlock(&dev->struct_mutex); |
| 1864 | 1775 | } |
| 1865 | 1776 | |
| 1866 | 1777 | int |
| 1867 | −i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | |
| 1778 | +i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |
| 1779 | + int interruptible, struct intel_ring_buffer *ring) | |
| 1868 | 1780 | { |
| 1869 | 1781 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1870 | 1782 | u32 ier; |
| @@ -1875,7 +1787,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) · 4 unmodified lines | ||
| 1875 | 1787 | if (atomic_read(&dev_priv->mm.wedged)) |
| 1876 | 1788 | return -EIO; |
| 1877 | 1789 | |
| 1878 | − if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { | |
| 1790 | + if (!i915_seqno_passed(ring->get_gem_seqno(dev, ring), seqno)) { | |
| 1879 | 1791 | if (HAS_PCH_SPLIT(dev)) |
| 1880 | 1792 | ier = I915_READ(DEIER) | I915_READ(GTIER); |
| 1881 | 1793 | else |
| @@ -1889,19 +1801,21 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) · 7 unmodified lines | ||
| 1889 | 1801 | |
| 1890 | 1802 | trace_i915_gem_request_wait_begin(dev, seqno); |
| 1891 | 1803 | |
| 1892 | − dev_priv->mm.waiting_gem_seqno = seqno; | |
| 1893 | − i915_user_irq_get(dev); | |
| 1804 | + ring->waiting_gem_seqno = seqno; | |
| 1805 | + ring->user_irq_get(dev, ring); | |
| 1894 | 1806 | if (interruptible) |
| 1895 | − ret = wait_event_interruptible(dev_priv->irq_queue, | |
| 1896 | − i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || | |
| 1897 | − atomic_read(&dev_priv->mm.wedged)); | |
| 1807 | + ret = wait_event_interruptible(ring->irq_queue, | |
| 1808 | + i915_seqno_passed( | |
| 1809 | + ring->get_gem_seqno(dev, ring), seqno) | |
| 1810 | + || atomic_read(&dev_priv->mm.wedged)); | |
| 1898 | 1811 | else |
| 1899 | − wait_event(dev_priv->irq_queue, | |
| 1900 | − i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || | |
| 1901 | − atomic_read(&dev_priv->mm.wedged)); | |
| 1812 | + wait_event(ring->irq_queue, | |
| 1813 | + i915_seqno_passed( | |
| 1814 | + ring->get_gem_seqno(dev, ring), seqno) | |
| 1815 | + || atomic_read(&dev_priv->mm.wedged)); | |
| 1902 | 1816 | |
| 1903 | − i915_user_irq_put(dev); | |
| 1904 | − dev_priv->mm.waiting_gem_seqno = 0; | |
| 1817 | + ring->user_irq_put(dev, ring); | |
| 1818 | + ring->waiting_gem_seqno = 0; | |
| 1905 | 1819 | |
| 1906 | 1820 | trace_i915_gem_request_wait_end(dev, seqno); |
| 1907 | 1821 | } |
| @@ -1910,7 +1824,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) · 2 unmodified lines | ||
| 1910 | 1824 | |
| 1911 | 1825 | if (ret && ret != -ERESTARTSYS) |
| 1912 | 1826 | DRM_ERROR("%s returns %d (awaiting %d at %d)\n", |
| 1913 | − __func__, ret, seqno, i915_get_gem_seqno(dev)); | |
| 1827 | + __func__, ret, seqno, ring->get_gem_seqno(dev, ring)); | |
| 1914 | 1828 | |
| 1915 | 1829 | /* Directly dispatch request retiring. While we have the work queue |
| 1916 | 1830 | * to handle this, the waiter on a request often wants an associated |
| @@ -1918,7 +1832,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) · 1 unmodified line | ||
| 1918 | 1832 | * a separate wait queue to handle that. |
| 1919 | 1833 | */ |
| 1920 | 1834 | if (ret == 0) |
| 1921 | − i915_gem_retire_requests(dev); | |
| 1835 | + i915_gem_retire_requests(dev, ring); | |
| 1922 | 1836 | |
| 1923 | 1837 | return ret; |
| 1924 | 1838 | } |
| @@ -1928,9 +1842,10 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) · 3 unmodified lines | ||
| 1928 | 1842 | * request and object lists appropriately for that event. |
| 1929 | 1843 | */ |
| 1930 | 1844 | static int |
| 1931 | −i915_wait_request(struct drm_device *dev, uint32_t seqno) | |
| 1845 | +i915_wait_request(struct drm_device *dev, uint32_t seqno, | |
| 1846 | + struct intel_ring_buffer *ring) | |
| 1932 | 1847 | { |
| 1933 | − return i915_do_wait_request(dev, seqno, 1); | |
| 1848 | + return i915_do_wait_request(dev, seqno, 1, ring); | |
| 1934 | 1849 | } |
| 1935 | 1850 | |
| 1936 | 1851 | static void |
| @@ -1939,71 +1854,29 @@ i915_gem_flush(struct drm_device *dev, · 2 unmodified lines | ||
| 1939 | 1854 | uint32_t flush_domains) |
| 1940 | 1855 | { |
| 1941 | 1856 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1942 | − uint32_t cmd; | |
| 1943 | − RING_LOCALS; | |
| 1944 | − | |
| 1945 | −#if WATCH_EXEC | |
| 1946 | − DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | |
| 1947 | − invalidate_domains, flush_domains); | |
| 1948 | −#endif | |
| 1949 | − trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno, | |
| 1950 | − invalidate_domains, flush_domains); | |
| 1951 | − | |
| 1952 | 1857 | if (flush_domains & I915_GEM_DOMAIN_CPU) |
| 1953 | 1858 | drm_agp_chipset_flush(dev); |
| 1859 | + dev_priv->render_ring.flush(dev, &dev_priv->render_ring, | |
| 1860 | + invalidate_domains, | |
| 1861 | + flush_domains); | |
| 1862 | + | |
| 1863 | + if (HAS_BSD(dev)) | |
| 1864 | + dev_priv->bsd_ring.flush(dev, &dev_priv->bsd_ring, | |
| 1865 | + invalidate_domains, | |
| 1866 | + flush_domains); | |
| 1867 | +} | |
| 1954 | 1868 | |
| 1955 | − if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | |
| 1956 | − /* | |
| 1957 | − * read/write caches: | |
| 1958 | − * | |
| 1959 | − * I915_GEM_DOMAIN_RENDER is always invalidated, but is | |
| 1960 | − * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is | |
| 1961 | − * also flushed at 2d versus 3d pipeline switches. | |
| 1962 | − * | |
| 1963 | − * read-only caches: | |
| 1964 | − * | |
| 1965 | − * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if | |
| 1966 | − * MI_READ_FLUSH is set, and is always flushed on 965. | |
| 1967 | − * | |
| 1968 | − * I915_GEM_DOMAIN_COMMAND may not exist? | |
| 1969 | − * | |
| 1970 | − * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is | |
| 1971 | − * invalidated when MI_EXE_FLUSH is set. | |
| 1972 | − * | |
| 1973 | − * I915_GEM_DOMAIN_VERTEX, which exists on 965, is | |
| 1974 | − * invalidated with every MI_FLUSH. | |
| 1975 | − * | |
| 1976 | − * TLBs: | |
| 1977 | − * | |
| 1978 | − * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND | |
| 1979 | − * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and | |
| 1980 | − * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER | |
| 1981 | − * are flushed at any MI_FLUSH. | |
| 1982 | − */ | |
| 1983 | − | |
| 1984 | − cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | |
| 1985 | − if ((invalidate_domains|flush_domains) & | |
| 1986 | − I915_GEM_DOMAIN_RENDER) | |
| 1987 | − cmd &= ~MI_NO_WRITE_FLUSH; | |
| 1988 | − if (!IS_I965G(dev)) { | |
| 1989 | − /* | |
| 1990 | − * On the 965, the sampler cache always gets flushed | |
| 1991 | − * and this bit is reserved. | |
| 1992 | − */ | |
| 1993 | − if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) | |
| 1994 | − cmd |= MI_READ_FLUSH; | |
| 1995 | − } | |
| 1996 | − if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) | |
| 1997 | − cmd |= MI_EXE_FLUSH; | |
| 1998 | − | |
| 1999 | −#if WATCH_EXEC | |
| 2000 | − DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | |
| 2001 | −#endif | |
| 2002 | − BEGIN_LP_RING(2); | |
| 2003 | − OUT_RING(cmd); | |
| 2004 | − OUT_RING(MI_NOOP); | |
| 2005 | − ADVANCE_LP_RING(); | |
| 2006 | − } | |
| 1869 | +static void | |
| 1870 | +i915_gem_flush_ring(struct drm_device *dev, | |
| 1871 | + uint32_t invalidate_domains, | |
| 1872 | + uint32_t flush_domains, | |
| 1873 | + struct intel_ring_buffer *ring) | |
| 1874 | +{ | |
| 1875 | + if (flush_domains & I915_GEM_DOMAIN_CPU) | |
| 1876 | + drm_agp_chipset_flush(dev); | |
| 1877 | + ring->flush(dev, ring, | |
| 1878 | + invalidate_domains, | |
| 1879 | + flush_domains); | |
| 2007 | 1880 | } |
| 2008 | 1881 | |
| 2009 | 1882 | /** |
| @@ -2030,7 +1903,8 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj) · 20 unmodified lines | ||
| 2030 | 1903 | DRM_INFO("%s: object %p wait for seqno %08x\n", |
| 2031 | 1904 | __func__, obj, obj_priv->last_rendering_seqno); |
| 2032 | 1905 | #endif |
| 2033 | − ret = i915_wait_request(dev, obj_priv->last_rendering_seqno); | |
| 1906 | + ret = i915_wait_request(dev, | |
| 1907 | + obj_priv->last_rendering_seqno, obj_priv->ring); | |
| 2034 | 1908 | if (ret != 0) |
| 2035 | 1909 | return ret; |
| 2036 | 1910 | } |
| @@ -2146,11 +2020,14 @@ i915_gpu_idle(struct drm_device *dev) · 109 unmodified lines | ||
| 2146 | 2020 | { |
| 2147 | 2021 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 2148 | 2022 | bool lists_empty; |
| 2149 | − uint32_t seqno; | |
| 2023 | + uint32_t seqno1, seqno2; | |
| 2024 | + int ret; | |
| 2150 | 2025 | |
| 2151 | 2026 | spin_lock(&dev_priv->mm.active_list_lock); |
| 2152 | − lists_empty = list_empty(&dev_priv->mm.flushing_list) && | |
| 2153 | − list_empty(&dev_priv->mm.active_list); | |
| 2027 | + lists_empty = (list_empty(&dev_priv->mm.flushing_list) && | |
| 2028 | + list_empty(&dev_priv->render_ring.active_list) && | |
| 2029 | + (!HAS_BSD(dev) || | |
| 2030 | + list_empty(&dev_priv->bsd_ring.active_list))); | |
| 2154 | 2031 | spin_unlock(&dev_priv->mm.active_list_lock); |
| 2155 | 2032 | |
| 2156 | 2033 | if (lists_empty) |
| @@ -2158,11 +2035,25 @@ i915_gpu_idle(struct drm_device *dev) · 1 unmodified line | ||
| 2158 | 2035 | |
| 2159 | 2036 | /* Flush everything onto the inactive list. */ |
| 2160 | 2037 | i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); |
| 2161 | − seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS); | |
| 2162 | − if (seqno == 0) | |
| 2038 | + seqno1 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, | |
| 2039 | + &dev_priv->render_ring); | |
| 2040 | + if (seqno1 == 0) | |
| 2163 | 2041 | return -ENOMEM; |
| 2042 | + ret = i915_wait_request(dev, seqno1, &dev_priv->render_ring); | |
| 2043 | + | |
| 2044 | + if (HAS_BSD(dev)) { | |
| 2045 | + seqno2 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, | |
| 2046 | + &dev_priv->bsd_ring); | |
| 2047 | + if (seqno2 == 0) | |
| 2048 | + return -ENOMEM; | |
| 2049 | + | |
| 2050 | + ret = i915_wait_request(dev, seqno2, &dev_priv->bsd_ring); | |
| 2051 | + if (ret) | |
| 2052 | + return ret; | |
| 2053 | + } | |
| 2054 | + | |
| 2164 | 2055 | |
| 2165 | − return i915_wait_request(dev, seqno); | |
| 2056 | + return ret; | |
| 2166 | 2057 | } |
| 2167 | 2058 | |
| 2168 | 2059 | static int |
| @@ -2175,7 +2066,9 @@ i915_gem_evict_everything(struct drm_device *dev) · 6 unmodified lines | ||
| 2175 | 2066 | spin_lock(&dev_priv->mm.active_list_lock); |
| 2176 | 2067 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
| 2177 | 2068 | list_empty(&dev_priv->mm.flushing_list) && |
| 2178 | − list_empty(&dev_priv->mm.active_list)); | |
| 2069 | + list_empty(&dev_priv->render_ring.active_list) && | |
| 2070 | + (!HAS_BSD(dev) | |
| 2071 | + || list_empty(&dev_priv->bsd_ring.active_list))); | |
| 2179 | 2072 | spin_unlock(&dev_priv->mm.active_list_lock); |
| 2180 | 2073 | |
| 2181 | 2074 | if (lists_empty) |
| @@ -2195,7 +2088,9 @@ i915_gem_evict_everything(struct drm_device *dev) · 13 unmodified lines | ||
| 2195 | 2088 | spin_lock(&dev_priv->mm.active_list_lock); |
| 2196 | 2089 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
| 2197 | 2090 | list_empty(&dev_priv->mm.flushing_list) && |
| 2198 | − list_empty(&dev_priv->mm.active_list)); | |
| 2091 | + list_empty(&dev_priv->render_ring.active_list) && | |
| 2092 | + (!HAS_BSD(dev) | |
| 2093 | + || list_empty(&dev_priv->bsd_ring.active_list))); | |
| 2199 | 2094 | spin_unlock(&dev_priv->mm.active_list_lock); |
| 2200 | 2095 | BUG_ON(!lists_empty); |
| 2201 | 2096 | |
| @@ -2209,8 +2104,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) · 7 unmodified lines | ||
| 2209 | 2104 | struct drm_gem_object *obj; |
| 2210 | 2105 | int ret; |
| 2211 | 2106 | |
| 2107 | + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | |
| 2108 | + struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; | |
| 2212 | 2109 | for (;;) { |
| 2213 | − i915_gem_retire_requests(dev); | |
| 2110 | + i915_gem_retire_requests(dev, render_ring); | |
| 2111 | + | |
| 2112 | + if (HAS_BSD(dev)) | |
| 2113 | + i915_gem_retire_requests(dev, bsd_ring); | |
| 2214 | 2114 | |
| 2215 | 2115 | /* If there's an inactive buffer available now, grab it |
| 2216 | 2116 | * and be done. |
| @@ -2234,14 +2134,30 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) · 17 unmodified lines | ||
| 2234 | 2134 | * things, wait for the next to finish and hopefully leave us |
| 2235 | 2135 | * a buffer to evict. |
| 2236 | 2136 | */ |
| 2237 | − if (!list_empty(&dev_priv->mm.request_list)) { | |
| 2137 | + if (!list_empty(&render_ring->request_list)) { | |
| 2138 | + struct drm_i915_gem_request *request; | |
| 2139 | + | |
| 2140 | + request = list_first_entry(&render_ring->request_list, | |
| 2141 | + struct drm_i915_gem_request, | |
| 2142 | + list); | |
| 2143 | + | |
| 2144 | + ret = i915_wait_request(dev, | |
| 2145 | + request->seqno, request->ring); | |
| 2146 | + if (ret) | |
| 2147 | + return ret; | |
| 2148 | + | |
| 2149 | + continue; | |
| 2150 | + } | |
| 2151 | + | |
| 2152 | + if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) { | |
| 2238 | 2153 | struct drm_i915_gem_request *request; |
| 2239 | 2154 | |
| 2240 | − request = list_first_entry(&dev_priv->mm.request_list, | |
| 2155 | + request = list_first_entry(&bsd_ring->request_list, | |
| 2241 | 2156 | struct drm_i915_gem_request, |
| 2242 | 2157 | list); |
| 2243 | 2158 | |
| 2244 | − ret = i915_wait_request(dev, request->seqno); | |
| 2159 | + ret = i915_wait_request(dev, | |
| 2160 | + request->seqno, request->ring); | |
| 2245 | 2161 | if (ret) |
| 2246 | 2162 | return ret; |
| 2247 | 2163 | |
| @@ -2268,10 +2184,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) · 20 unmodified lines | ||
| 2268 | 2184 | if (obj != NULL) { |
| 2269 | 2185 | uint32_t seqno; |
| 2270 | 2186 | |
| 2271 | − i915_gem_flush(dev, | |
| 2187 | + i915_gem_flush_ring(dev, | |
| 2188 | + obj->write_domain, | |
| 2272 | 2189 | obj->write_domain, |
| 2273 | − obj->write_domain); | |
| 2274 | − seqno = i915_add_request(dev, NULL, obj->write_domain); | |
| 2190 | + obj_priv->ring); | |
| 2191 | + seqno = i915_add_request(dev, NULL, | |
| 2192 | + obj->write_domain, | |
| 2193 | + obj_priv->ring); | |
| 2275 | 2194 | if (seqno == 0) |
| 2276 | 2195 | return -ENOMEM; |
| 2277 | 2196 | continue; |
| @@ -2299,6 +2218,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, · 21 unmodified lines | ||
| 2299 | 2218 | struct inode *inode; |
| 2300 | 2219 | struct page *page; |
| 2301 | 2220 | |
| 2221 | + BUG_ON(obj_priv->pages_refcount | |
| 2222 | + == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT); | |
| 2223 | + | |
| 2302 | 2224 | if (obj_priv->pages_refcount++ != 0) |
| 2303 | 2225 | return 0; |
| 2304 | 2226 | |
| @@ -2697,6 +2619,14 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) · 392 unmodified lines | ||
| 2697 | 2619 | return -EINVAL; |
| 2698 | 2620 | } |
| 2699 | 2621 | |
| 2622 | + /* If the object is bigger than the entire aperture, reject it early | |
| 2623 | + * before evicting everything in a vain attempt to find space. | |
| 2624 | + */ | |
| 2625 | + if (obj->size > dev->gtt_total) { | |
| 2626 | + DRM_ERROR("Attempting to bind an object larger than the aperture\n"); | |
| 2627 | + return -E2BIG; | |
| 2628 | + } | |
| 2629 | + | |
| 2700 | 2630 | search_free: |
| 2701 | 2631 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, |
| 2702 | 2632 | obj->size, alignment, 0); |
| @@ -2807,6 +2737,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) · 104 unmodified lines | ||
| 2807 | 2737 | { |
| 2808 | 2738 | struct drm_device *dev = obj->dev; |
| 2809 | 2739 | uint32_t old_write_domain; |
| 2740 | + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | |
| 2810 | 2741 | |
| 2811 | 2742 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
| 2812 | 2743 | return; |
| @@ -2814,7 +2745,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) · 1 unmodified line | ||
| 2814 | 2745 | /* Queue the GPU write cache flushing we need. */ |
| 2815 | 2746 | old_write_domain = obj->write_domain; |
| 2816 | 2747 | i915_gem_flush(dev, 0, obj->write_domain); |
| 2817 | − (void) i915_add_request(dev, NULL, obj->write_domain); | |
| 2748 | + (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring); | |
| 2818 | 2749 | BUG_ON(obj->write_domain); |
| 2819 | 2750 | |
| 2820 | 2751 | trace_i915_gem_object_change_domain(obj, |
| @@ -2954,23 +2885,24 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) · 133 unmodified lines | ||
| 2954 | 2885 | DRM_INFO("%s: object %p wait for seqno %08x\n", |
| 2955 | 2886 | __func__, obj, obj_priv->last_rendering_seqno); |
| 2956 | 2887 | #endif |
| 2957 | − ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0); | |
| 2888 | + ret = i915_do_wait_request(dev, | |
| 2889 | + obj_priv->last_rendering_seqno, | |
| 2890 | + 0, | |
| 2891 | + obj_priv->ring); | |
| 2958 | 2892 | if (ret != 0) |
| 2959 | 2893 | return ret; |
| 2960 | 2894 | } |
| 2961 | 2895 | |
| 2896 | + i915_gem_object_flush_cpu_write_domain(obj); | |
| 2897 | + | |
| 2962 | 2898 | old_write_domain = obj->write_domain; |
| 2963 | 2899 | old_read_domains = obj->read_domains; |
| 2964 | 2900 | |
| 2965 | − obj->read_domains &= I915_GEM_DOMAIN_GTT; | |
| 2966 | − | |
| 2967 | − i915_gem_object_flush_cpu_write_domain(obj); | |
| 2968 | − | |
| 2969 | 2901 | /* It should now be out of any other write domains, and we can update |
| 2970 | 2902 | * the domain values for our changes. |
| 2971 | 2903 | */ |
| 2972 | 2904 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); |
| 2973 | − obj->read_domains |= I915_GEM_DOMAIN_GTT; | |
| 2905 | + obj->read_domains = I915_GEM_DOMAIN_GTT; | |
| 2974 | 2906 | obj->write_domain = I915_GEM_DOMAIN_GTT; |
| 2975 | 2907 | obj_priv->dirty = 1; |
| 2976 | 2908 | |
| @@ -3354,9 +3286,13 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, · 377 unmodified lines | ||
| 3354 | 3286 | obj_priv->tiling_mode != I915_TILING_NONE; |
| 3355 | 3287 | |
| 3356 | 3288 | /* Check fence reg constraints and rebind if necessary */ |
| 3357 | − if (need_fence && !i915_gem_object_fence_offset_ok(obj, | |
| 3358 | − obj_priv->tiling_mode)) | |
| 3359 | − i915_gem_object_unbind(obj); | |
| 3289 | + if (need_fence && | |
| 3290 | + !i915_gem_object_fence_offset_ok(obj, | |
| 3291 | + obj_priv->tiling_mode)) { | |
| 3292 | + ret = i915_gem_object_unbind(obj); | |
| 3293 | + if (ret) | |
| 3294 | + return ret; | |
| 3295 | + } | |
| 3360 | 3296 | |
| 3361 | 3297 | /* Choose the GTT offset for our buffer and put it there. */ |
| 3362 | 3298 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); |
| @@ -3370,9 +3306,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, · 7 unmodified lines | ||
| 3370 | 3306 | if (need_fence) { |
| 3371 | 3307 | ret = i915_gem_object_get_fence_reg(obj); |
| 3372 | 3308 | if (ret != 0) { |
| 3373 | − if (ret != -EBUSY && ret != -ERESTARTSYS) | |
| 3374 | − DRM_ERROR("Failure to install fence: %d\n", | |
| 3375 | − ret); | |
| 3376 | 3309 | i915_gem_object_unpin(obj); |
| 3377 | 3310 | return ret; |
| 3378 | 3311 | } |
| @@ -3545,62 +3478,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, · 166 unmodified lines | ||
| 3545 | 3478 | return 0; |
| 3546 | 3479 | } |
| 3547 | 3480 | |
| 3548 | −/** Dispatch a batchbuffer to the ring | |
| 3549 | − */ | |
| 3550 | −static int | |
| 3551 | −i915_dispatch_gem_execbuffer(struct drm_device *dev, | |
| 3552 | − struct drm_i915_gem_execbuffer2 *exec, | |
| 3553 | − struct drm_clip_rect *cliprects, | |
| 3554 | − uint64_t exec_offset) | |
| 3555 | −{ | |
| 3556 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 3557 | − int nbox = exec->num_cliprects; | |
| 3558 | − int i = 0, count; | |
| 3559 | − uint32_t exec_start, exec_len; | |
| 3560 | − RING_LOCALS; | |
| 3561 | − | |
| 3562 | − exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | |
| 3563 | − exec_len = (uint32_t) exec->batch_len; | |
| 3564 | − | |
| 3565 | − trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | |
| 3566 | − | |
| 3567 | − count = nbox ? nbox : 1; | |
| 3568 | − | |
| 3569 | − for (i = 0; i < count; i++) { | |
| 3570 | − if (i < nbox) { | |
| 3571 | − int ret = i915_emit_box(dev, cliprects, i, | |
| 3572 | − exec->DR1, exec->DR4); | |
| 3573 | − if (ret) | |
| 3574 | − return ret; | |
| 3575 | − } | |
| 3576 | − | |
| 3577 | − if (IS_I830(dev) || IS_845G(dev)) { | |
| 3578 | − BEGIN_LP_RING(4); | |
| 3579 | − OUT_RING(MI_BATCH_BUFFER); | |
| 3580 | − OUT_RING(exec_start | MI_BATCH_NON_SECURE); | |
| 3581 | − OUT_RING(exec_start + exec_len - 4); | |
| 3582 | − OUT_RING(0); | |
| 3583 | − ADVANCE_LP_RING(); | |
| 3584 | − } else { | |
| 3585 | − BEGIN_LP_RING(2); | |
| 3586 | − if (IS_I965G(dev)) { | |
| 3587 | − OUT_RING(MI_BATCH_BUFFER_START | | |
| 3588 | − (2 << 6) | | |
| 3589 | − MI_BATCH_NON_SECURE_I965); | |
| 3590 | − OUT_RING(exec_start); | |
| 3591 | − } else { | |
| 3592 | − OUT_RING(MI_BATCH_BUFFER_START | | |
| 3593 | − (2 << 6)); | |
| 3594 | − OUT_RING(exec_start | MI_BATCH_NON_SECURE); | |
| 3595 | − } | |
| 3596 | − ADVANCE_LP_RING(); | |
| 3597 | − } | |
| 3598 | − } | |
| 3599 | − | |
| 3600 | − /* XXX breadcrumb */ | |
| 3601 | − return 0; | |
| 3602 | −} | |
| 3603 | − | |
| 3604 | 3481 | /* Throttle our rendering by waiting until the ring has completed our requests |
| 3605 | 3482 | * emitted over 20 msec ago. |
| 3606 | 3483 | * |
| @@ -3629,7 +3506,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) · 22 unmodified lines | ||
| 3629 | 3506 | if (time_after_eq(request->emitted_jiffies, recent_enough)) |
| 3630 | 3507 | break; |
| 3631 | 3508 | |
| 3632 | − ret = i915_wait_request(dev, request->seqno); | |
| 3509 | + ret = i915_wait_request(dev, request->seqno, request->ring); | |
| 3633 | 3510 | if (ret != 0) |
| 3634 | 3511 | break; |
| 3635 | 3512 | } |
| @@ -3786,10 +3663,22 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, · 150 unmodified lines | ||
| 3786 | 3663 | uint32_t seqno, flush_domains, reloc_index; |
| 3787 | 3664 | int pin_tries, flips; |
| 3788 | 3665 | |
| 3666 | + struct intel_ring_buffer *ring = NULL; | |
| 3667 | + | |
| 3789 | 3668 | #if WATCH_EXEC |
| 3790 | 3669 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", |
| 3791 | 3670 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); |
| 3792 | 3671 | #endif |
| 3672 | + if (args->flags & I915_EXEC_BSD) { | |
| 3673 | + if (!HAS_BSD(dev)) { | |
| 3674 | + DRM_ERROR("execbuf with wrong flag\n"); | |
| 3675 | + return -EINVAL; | |
| 3676 | + } | |
| 3677 | + ring = &dev_priv->bsd_ring; | |
| 3678 | + } else { | |
| 3679 | + ring = &dev_priv->render_ring; | |
| 3680 | + } | |
| 3681 | + | |
| 3793 | 3682 | |
| 3794 | 3683 | if (args->buffer_count < 1) { |
| 3795 | 3684 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); |
| @@ -3902,11 +3791,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, · 106 unmodified lines | ||
| 3902 | 3791 | if (ret != -ENOSPC || pin_tries >= 1) { |
| 3903 | 3792 | if (ret != -ERESTARTSYS) { |
| 3904 | 3793 | unsigned long long total_size = 0; |
| 3905 | − for (i = 0; i < args->buffer_count; i++) | |
| 3794 | + int num_fences = 0; | |
| 3795 | + for (i = 0; i < args->buffer_count; i++) { | |
| 3796 | + obj_priv = object_list[i]->driver_private; | |
| 3797 | + | |
| 3906 | 3798 | total_size += object_list[i]->size; |
| 3907 | − DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes: %d\n", | |
| 3799 | + num_fences += | |
| 3800 | + exec_list[i].flags & EXEC_OBJECT_NEEDS_FENCE && | |
| 3801 | + obj_priv->tiling_mode != I915_TILING_NONE; | |
| 3802 | + } | |
| 3803 | + DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes, %d fences: %d\n", | |
| 3908 | 3804 | pinned+1, args->buffer_count, |
| 3909 | − total_size, ret); | |
| 3805 | + total_size, num_fences, | |
| 3806 | + ret); | |
| 3910 | 3807 | DRM_ERROR("%d objects [%d pinned], " |
| 3911 | 3808 | "%d object bytes [%d pinned], " |
| 3912 | 3809 | "%d/%d gtt bytes\n", |
| @@ -3976,9 +3873,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, · 63 unmodified lines | ||
| 3976 | 3873 | i915_gem_flush(dev, |
| 3977 | 3874 | dev->invalidate_domains, |
| 3978 | 3875 | dev->flush_domains); |
| 3979 | − if (dev->flush_domains & I915_GEM_GPU_DOMAINS) | |
| 3876 | + if (dev->flush_domains & I915_GEM_GPU_DOMAINS) { | |
| 3980 | 3877 | (void)i915_add_request(dev, file_priv, |
| 3981 | − dev->flush_domains); | |
| 3878 | + dev->flush_domains, | |
| 3879 | + &dev_priv->render_ring); | |
| 3880 | + | |
| 3881 | + if (HAS_BSD(dev)) | |
| 3882 | + (void)i915_add_request(dev, file_priv, | |
| 3883 | + dev->flush_domains, | |
| 3884 | + &dev_priv->bsd_ring); | |
| 3885 | + } | |
| 3982 | 3886 | } |
| 3983 | 3887 | |
| 3984 | 3888 | for (i = 0; i < args->buffer_count; i++) { |
| @@ -4015,7 +3919,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, · 30 unmodified lines | ||
| 4015 | 3919 | #endif |
| 4016 | 3920 | |
| 4017 | 3921 | /* Exec the batchbuffer */ |
| 4018 | − ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset); | |
| 3922 | + ret = ring->dispatch_gem_execbuffer(dev, ring, args, | |
| 3923 | + cliprects, exec_offset); | |
| 4019 | 3924 | if (ret) { |
| 4020 | 3925 | DRM_ERROR("dispatch failed %d\n", ret); |
| 4021 | 3926 | goto err; |
| @@ -4025,7 +3930,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, · 3 unmodified lines | ||
| 4025 | 3930 | * Ensure that the commands in the batch buffer are |
| 4026 | 3931 | * finished before the interrupt fires |
| 4027 | 3932 | */ |
| 4028 | − flush_domains = i915_retire_commands(dev); | |
| 3933 | + flush_domains = i915_retire_commands(dev, ring); | |
| 4029 | 3934 | |
| 4030 | 3935 | i915_verify_inactive(dev, __FILE__, __LINE__); |
| 4031 | 3936 | |
| @@ -4036,12 +3941,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, · 4 unmodified lines | ||
| 4036 | 3941 | * *some* interrupts representing completion of buffers that we can |
| 4037 | 3942 | * wait on when trying to clear up gtt space). |
| 4038 | 3943 | */ |
| 4039 | − seqno = i915_add_request(dev, file_priv, flush_domains); | |
| 3944 | + seqno = i915_add_request(dev, file_priv, flush_domains, ring); | |
| 4040 | 3945 | BUG_ON(seqno == 0); |
| 4041 | 3946 | for (i = 0; i < args->buffer_count; i++) { |
| 4042 | 3947 | struct drm_gem_object *obj = object_list[i]; |
| 3948 | + obj_priv = to_intel_bo(obj); | |
| 4043 | 3949 | |
| 4044 | − i915_gem_object_move_to_active(obj, seqno); | |
| 3950 | + i915_gem_object_move_to_active(obj, seqno, ring); | |
| 4045 | 3951 | #if WATCH_LRU |
| 4046 | 3952 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); |
| 4047 | 3953 | #endif |
| @@ -4153,7 +4059,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, · 105 unmodified lines | ||
| 4153 | 4059 | exec2.DR4 = args->DR4; |
| 4154 | 4060 | exec2.num_cliprects = args->num_cliprects; |
| 4155 | 4061 | exec2.cliprects_ptr = args->cliprects_ptr; |
| 4156 | − exec2.flags = 0; | |
| 4062 | + exec2.flags = I915_EXEC_RENDER; | |
| 4157 | 4063 | |
| 4158 | 4064 | ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); |
| 4159 | 4065 | if (!ret) { |
| @@ -4239,7 +4145,20 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) · 79 unmodified lines | ||
| 4239 | 4145 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 4240 | 4146 | int ret; |
| 4241 | 4147 | |
| 4148 | + BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); | |
| 4149 | + | |
| 4242 | 4150 | i915_verify_inactive(dev, __FILE__, __LINE__); |
| 4151 | + | |
| 4152 | + if (obj_priv->gtt_space != NULL) { | |
| 4153 | + if (alignment == 0) | |
| 4154 | + alignment = i915_gem_get_gtt_alignment(obj); | |
| 4155 | + if (obj_priv->gtt_offset & (alignment - 1)) { | |
| 4156 | + ret = i915_gem_object_unbind(obj); | |
| 4157 | + if (ret) | |
| 4158 | + return ret; | |
| 4159 | + } | |
| 4160 | + } | |
| 4161 | + | |
| 4243 | 4162 | if (obj_priv->gtt_space == NULL) { |
| 4244 | 4163 | ret = i915_gem_object_bind_to_gtt(obj, alignment); |
| 4245 | 4164 | if (ret) |
| @@ -4392,6 +4311,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, · 146 unmodified lines | ||
| 4392 | 4311 | struct drm_i915_gem_busy *args = data; |
| 4393 | 4312 | struct drm_gem_object *obj; |
| 4394 | 4313 | struct drm_i915_gem_object *obj_priv; |
| 4314 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 4395 | 4315 | |
| 4396 | 4316 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
| 4397 | 4317 | if (obj == NULL) { |
| @@ -4406,7 +4326,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, · 8 unmodified lines | ||
| 4406 | 4326 | * actually unmasked, and our working set ends up being larger than |
| 4407 | 4327 | * required. |
| 4408 | 4328 | */ |
| 4409 | − i915_gem_retire_requests(dev); | |
| 4329 | + i915_gem_retire_requests(dev, &dev_priv->render_ring); | |
| 4330 | + | |
| 4331 | + if (HAS_BSD(dev)) | |
| 4332 | + i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | |
| 4410 | 4333 | |
| 4411 | 4334 | obj_priv = to_intel_bo(obj); |
| 4412 | 4335 | /* Don't count being on the flushing list against the object being |
| @@ -4573,7 +4496,10 @@ i915_gem_idle(struct drm_device *dev) · 160 unmodified lines | ||
| 4573 | 4496 | |
| 4574 | 4497 | mutex_lock(&dev->struct_mutex); |
| 4575 | 4498 | |
| 4576 | − if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) { | |
| 4499 | + if (dev_priv->mm.suspended || | |
| 4500 | + (dev_priv->render_ring.gem_object == NULL) || | |
| 4501 | + (HAS_BSD(dev) && | |
| 4502 | + dev_priv->bsd_ring.gem_object == NULL)) { | |
| 4577 | 4503 | mutex_unlock(&dev->struct_mutex); |
| 4578 | 4504 | return 0; |
| 4579 | 4505 | } |
| @@ -4654,71 +4580,6 @@ err: · 74 unmodified lines | ||
| 4654 | 4580 | return ret; |
| 4655 | 4581 | } |
| 4656 | 4582 | |
| 4657 | −static int | |
| 4658 | −i915_gem_init_hws(struct drm_device *dev) | |
| 4659 | −{ | |
| 4660 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 4661 | − struct drm_gem_object *obj; | |
| 4662 | − struct drm_i915_gem_object *obj_priv; | |
| 4663 | − int ret; | |
| 4664 | − | |
| 4665 | − /* If we need a physical address for the status page, it's already | |
| 4666 | − * initialized at driver load time. | |
| 4667 | − */ | |
| 4668 | − if (!I915_NEED_GFX_HWS(dev)) | |
| 4669 | − return 0; | |
| 4670 | − | |
| 4671 | − obj = i915_gem_alloc_object(dev, 4096); | |
| 4672 | − if (obj == NULL) { | |
| 4673 | − DRM_ERROR("Failed to allocate status page\n"); | |
| 4674 | − ret = -ENOMEM; | |
| 4675 | − goto err; | |
| 4676 | − } | |
| 4677 | − obj_priv = to_intel_bo(obj); | |
| 4678 | − obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | |
| 4679 | − | |
| 4680 | − ret = i915_gem_object_pin(obj, 4096); | |
| 4681 | − if (ret != 0) { | |
| 4682 | − drm_gem_object_unreference(obj); | |
| 4683 | − goto err_unref; | |
| 4684 | − } | |
| 4685 | − | |
| 4686 | − dev_priv->status_gfx_addr = obj_priv->gtt_offset; | |
| 4687 | − | |
| 4688 | − dev_priv->hw_status_page = kmap(obj_priv->pages[0]); | |
| 4689 | − if (dev_priv->hw_status_page == NULL) { | |
| 4690 | − DRM_ERROR("Failed to map status page.\n"); | |
| 4691 | − memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | |
| 4692 | − ret = -EINVAL; | |
| 4693 | − goto err_unpin; | |
| 4694 | − } | |
| 4695 | − | |
| 4696 | − if (HAS_PIPE_CONTROL(dev)) { | |
| 4697 | − ret = i915_gem_init_pipe_control(dev); | |
| 4698 | − if (ret) | |
| 4699 | − goto err_unpin; | |
| 4700 | − } | |
| 4701 | − | |
| 4702 | − dev_priv->hws_obj = obj; | |
| 4703 | − memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | |
| 4704 | − if (IS_GEN6(dev)) { | |
| 4705 | − I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr); | |
| 4706 | − I915_READ(HWS_PGA_GEN6); /* posting read */ | |
| 4707 | − } else { | |
| 4708 | − I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); | |
| 4709 | − I915_READ(HWS_PGA); /* posting read */ | |
| 4710 | − } | |
| 4711 | − DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); | |
| 4712 | − | |
| 4713 | − return 0; | |
| 4714 | − | |
| 4715 | −err_unpin: | |
| 4716 | − i915_gem_object_unpin(obj); | |
| 4717 | −err_unref: | |
| 4718 | − drm_gem_object_unreference(obj); | |
| 4719 | −err: | |
| 4720 | − return 0; | |
| 4721 | −} | |
| 4722 | 4583 | |
| 4723 | 4584 | static void |
| 4724 | 4585 | i915_gem_cleanup_pipe_control(struct drm_device *dev) |
| @@ -4737,146 +4598,46 @@ i915_gem_cleanup_pipe_control(struct drm_device *dev) · 12 unmodified lines | ||
| 4737 | 4598 | dev_priv->seqno_page = NULL; |
| 4738 | 4599 | } |
| 4739 | 4600 | |
| 4740 | −static void | |
| 4741 | −i915_gem_cleanup_hws(struct drm_device *dev) | |
| 4742 | −{ | |
| 4743 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 4744 | − struct drm_gem_object *obj; | |
| 4745 | − struct drm_i915_gem_object *obj_priv; | |
| 4746 | − | |
| 4747 | − if (dev_priv->hws_obj == NULL) | |
| 4748 | − return; | |
| 4749 | − | |
| 4750 | − obj = dev_priv->hws_obj; | |
| 4751 | − obj_priv = to_intel_bo(obj); | |
| 4752 | − | |
| 4753 | − kunmap(obj_priv->pages[0]); | |
| 4754 | − i915_gem_object_unpin(obj); | |
| 4755 | − drm_gem_object_unreference(obj); | |
| 4756 | − dev_priv->hws_obj = NULL; | |
| 4757 | − | |
| 4758 | − memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | |
| 4759 | − dev_priv->hw_status_page = NULL; | |
| 4760 | − | |
| 4761 | − if (HAS_PIPE_CONTROL(dev)) | |
| 4762 | − i915_gem_cleanup_pipe_control(dev); | |
| 4763 | − | |
| 4764 | − /* Write high address into HWS_PGA when disabling. */ | |
| 4765 | − I915_WRITE(HWS_PGA, 0x1ffff000); | |
| 4766 | −} | |
| 4767 | − | |
| 4768 | 4601 | int |
| 4769 | 4602 | i915_gem_init_ringbuffer(struct drm_device *dev) |
| 4770 | 4603 | { |
| 4771 | 4604 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4772 | − struct drm_gem_object *obj; | |
| 4773 | − struct drm_i915_gem_object *obj_priv; | |
| 4774 | − drm_i915_ring_buffer_t *ring = &dev_priv->ring; | |
| 4775 | 4605 | int ret; |
| 4776 | − u32 head; | |
| 4777 | − | |
| 4778 | − ret = i915_gem_init_hws(dev); | |
| 4779 | − if (ret != 0) | |
| 4780 | − return ret; | |
| 4781 | 4606 | |
| 4782 | − obj = i915_gem_alloc_object(dev, 128 * 1024); | |
| 4783 | − if (obj == NULL) { | |
| 4784 | − DRM_ERROR("Failed to allocate ringbuffer\n"); | |
| 4785 | − i915_gem_cleanup_hws(dev); | |
| 4786 | − return -ENOMEM; | |
| 4787 | − } | |
| 4788 | − obj_priv = to_intel_bo(obj); | |
| 4607 | + dev_priv->render_ring = render_ring; | |
| 4789 | 4608 | |
| 4790 | − ret = i915_gem_object_pin(obj, 4096); | |
| 4791 | − if (ret != 0) { | |
| 4792 | − drm_gem_object_unreference(obj); | |
| 4793 | − i915_gem_cleanup_hws(dev); | |
| 4794 | − return ret; | |
| 4609 | + if (!I915_NEED_GFX_HWS(dev)) { | |
| 4610 | + dev_priv->render_ring.status_page.page_addr | |
| 4611 | + = dev_priv->status_page_dmah->vaddr; | |
| 4612 | + memset(dev_priv->render_ring.status_page.page_addr, | |
| 4613 | + 0, PAGE_SIZE); | |
| 4795 | 4614 | } |
| 4796 | 4615 | |
| 4797 | − /* Set up the kernel mapping for the ring. */ | |
| 4798 | − ring->Size = obj->size; | |
| 4799 | − | |
| 4800 | − ring->map.offset = dev->agp->base + obj_priv->gtt_offset; | |
| 4801 | − ring->map.size = obj->size; | |
| 4802 | − ring->map.type = 0; | |
| 4803 | − ring->map.flags = 0; | |
| 4804 | − ring->map.mtrr = 0; | |
| 4805 | − | |
| 4806 | − drm_core_ioremap_wc(&ring->map, dev); | |
| 4807 | − if (ring->map.handle == NULL) { | |
| 4808 | − DRM_ERROR("Failed to map ringbuffer.\n"); | |
| 4809 | − memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | |
| 4810 | − i915_gem_object_unpin(obj); | |
| 4811 | − drm_gem_object_unreference(obj); | |
| 4812 | − i915_gem_cleanup_hws(dev); | |
| 4813 | − return -EINVAL; | |
| 4814 | − } | |
| 4815 | − ring->ring_obj = obj; | |
| 4816 | − ring->virtual_start = ring->map.handle; | |
| 4817 | − | |
| 4818 | − /* Stop the ring if it's running. */ | |
| 4819 | − I915_WRITE(PRB0_CTL, 0); | |
| 4820 | − I915_WRITE(PRB0_TAIL, 0); | |
| 4821 | − I915_WRITE(PRB0_HEAD, 0); | |
| 4822 | − | |
| 4823 | − /* Initialize the ring. */ | |
| 4824 | − I915_WRITE(PRB0_START, obj_priv->gtt_offset); | |
| 4825 | − head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | |
| 4826 | − | |
| 4827 | − /* G45 ring initialization fails to reset head to zero */ | |
| 4828 | − if (head != 0) { | |
| 4829 | − DRM_ERROR("Ring head not reset to zero " | |
| 4830 | − "ctl %08x head %08x tail %08x start %08x\n", | |
| 4831 | − I915_READ(PRB0_CTL), | |
| 4832 | − I915_READ(PRB0_HEAD), | |
| 4833 | − I915_READ(PRB0_TAIL), | |
| 4834 | − I915_READ(PRB0_START)); | |
| 4835 | − I915_WRITE(PRB0_HEAD, 0); | |
| 4836 | − | |
| 4837 | − DRM_ERROR("Ring head forced to zero " | |
| 4838 | − "ctl %08x head %08x tail %08x start %08x\n", | |
| 4839 | − I915_READ(PRB0_CTL), | |
| 4840 | − I915_READ(PRB0_HEAD), | |
| 4841 | − I915_READ(PRB0_TAIL), | |
| 4842 | − I915_READ(PRB0_START)); | |
| 4843 | − } | |
| 4844 | − | |
| 4845 | − I915_WRITE(PRB0_CTL, | |
| 4846 | − ((obj->size - 4096) & RING_NR_PAGES) | | |
| 4847 | − RING_NO_REPORT | | |
| 4848 | − RING_VALID); | |
| 4849 | − | |
| 4850 | − head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | |
| 4851 | − | |
| 4852 | − /* If the head is still not zero, the ring is dead */ | |
| 4853 | − if (head != 0) { | |
| 4854 | − DRM_ERROR("Ring initialization failed " | |
| 4855 | − "ctl %08x head %08x tail %08x start %08x\n", | |
| 4856 | − I915_READ(PRB0_CTL), | |
| 4857 | − I915_READ(PRB0_HEAD), | |
| 4858 | − I915_READ(PRB0_TAIL), | |
| 4859 | − I915_READ(PRB0_START)); | |
| 4860 | − return -EIO; | |
| 4616 | + if (HAS_PIPE_CONTROL(dev)) { | |
| 4617 | + ret = i915_gem_init_pipe_control(dev); | |
| 4618 | + if (ret) | |
| 4619 | + return ret; | |
| 4861 | 4620 | } |
| 4862 | 4621 | |
| 4863 | − /* Update our cache of the ring state */ | |
| 4864 | − if (!drm_core_check_feature(dev, DRIVER_MODESET)) | |
| 4865 | − i915_kernel_lost_context(dev); | |
| 4866 | − else { | |
| 4867 | − ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | |
| 4868 | − ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | |
| 4869 | − ring->space = ring->head - (ring->tail + 8); | |
| 4870 | − if (ring->space < 0) | |
| 4871 | − ring->space += ring->Size; | |
| 4872 | − } | |
| 4622 | + ret = intel_init_ring_buffer(dev, &dev_priv->render_ring); | |
| 4623 | + if (ret) | |
| 4624 | + goto cleanup_pipe_control; | |
| 4873 | 4625 | |
| 4874 | − if (IS_I9XX(dev) && !IS_GEN3(dev)) { | |
| 4875 | − I915_WRITE(MI_MODE, | |
| 4876 | − (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); | |
| 4626 | + if (HAS_BSD(dev)) { | |
| 4627 | + dev_priv->bsd_ring = bsd_ring; | |
| 4628 | + ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring); | |
| 4629 | + if (ret) | |
| 4630 | + goto cleanup_render_ring; | |
| 4877 | 4631 | } |
| 4878 | 4632 | |
| 4879 | 4633 | return 0; |
| 4634 | + | |
| 4635 | +cleanup_render_ring: | |
| 4636 | + intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | |
| 4637 | +cleanup_pipe_control: | |
| 4638 | + if (HAS_PIPE_CONTROL(dev)) | |
| 4639 | + i915_gem_cleanup_pipe_control(dev); | |
| 4640 | + return ret; | |
| 4880 | 4641 | } |
| 4881 | 4642 | |
| 4882 | 4643 | void |
| @@ -4884,17 +4645,11 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) · 1 unmodified line | ||
| 4884 | 4645 | { |
| 4885 | 4646 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4886 | 4647 | |
| 4887 | − if (dev_priv->ring.ring_obj == NULL) | |
| 4888 | − return; | |
| 4889 | − | |
| 4890 | − drm_core_ioremapfree(&dev_priv->ring.map, dev); | |
| 4891 | − | |
| 4892 | − i915_gem_object_unpin(dev_priv->ring.ring_obj); | |
| 4893 | − drm_gem_object_unreference(dev_priv->ring.ring_obj); | |
| 4894 | − dev_priv->ring.ring_obj = NULL; | |
| 4895 | − memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | |
| 4896 | − | |
| 4897 | − i915_gem_cleanup_hws(dev); | |
| 4648 | + intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | |
| 4649 | + if (HAS_BSD(dev)) | |
| 4650 | + intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | |
| 4651 | + if (HAS_PIPE_CONTROL(dev)) | |
| 4652 | + i915_gem_cleanup_pipe_control(dev); | |
| 4898 | 4653 | } |
| 4899 | 4654 | |
| 4900 | 4655 | int |
| @@ -4922,12 +4677,14 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, · 21 unmodified lines | ||
| 4922 | 4677 | } |
| 4923 | 4678 | |
| 4924 | 4679 | spin_lock(&dev_priv->mm.active_list_lock); |
| 4925 | − BUG_ON(!list_empty(&dev_priv->mm.active_list)); | |
| 4680 | + BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); | |
| 4681 | + BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.active_list)); | |
| 4926 | 4682 | spin_unlock(&dev_priv->mm.active_list_lock); |
| 4927 | 4683 | |
| 4928 | 4684 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); |
| 4929 | 4685 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); |
| 4930 | − BUG_ON(!list_empty(&dev_priv->mm.request_list)); | |
| 4686 | + BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); | |
| 4687 | + BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list)); | |
| 4931 | 4688 | mutex_unlock(&dev->struct_mutex); |
| 4932 | 4689 | |
| 4933 | 4690 | drm_irq_install(dev); |
| @@ -4966,18 +4723,20 @@ i915_gem_load(struct drm_device *dev) · 32 unmodified lines | ||
| 4966 | 4723 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4967 | 4724 | |
| 4968 | 4725 | spin_lock_init(&dev_priv->mm.active_list_lock); |
| 4969 | − INIT_LIST_HEAD(&dev_priv->mm.active_list); | |
| 4970 | 4726 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); |
| 4971 | 4727 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); |
| 4972 | 4728 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
| 4973 | − INIT_LIST_HEAD(&dev_priv->mm.request_list); | |
| 4974 | 4729 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
| 4730 | + INIT_LIST_HEAD(&dev_priv->render_ring.active_list); | |
| 4731 | + INIT_LIST_HEAD(&dev_priv->render_ring.request_list); | |
| 4732 | + if (HAS_BSD(dev)) { | |
| 4733 | + INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list); | |
| 4734 | + INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list); | |
| 4735 | + } | |
| 4975 | 4736 | for (i = 0; i < 16; i++) |
| 4976 | 4737 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); |
| 4977 | 4738 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
| 4978 | 4739 | i915_gem_retire_work_handler); |
| 4979 | − dev_priv->mm.next_gem_seqno = 1; | |
| 4980 | − | |
| 4981 | 4740 | spin_lock(&shrink_list_lock); |
| 4982 | 4741 | list_add(&dev_priv->mm.shrink_list, &shrink_list); |
| 4983 | 4742 | spin_unlock(&shrink_list_lock); |
| @@ -5209,7 +4968,9 @@ i915_gpu_is_active(struct drm_device *dev) · 225 unmodified lines | ||
| 5209 | 4968 | |
| 5210 | 4969 | spin_lock(&dev_priv->mm.active_list_lock); |
| 5211 | 4970 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && |
| 5212 | − list_empty(&dev_priv->mm.active_list); | |
| 4971 | + list_empty(&dev_priv->render_ring.active_list); | |
| 4972 | + if (HAS_BSD(dev)) | |
| 4973 | + lists_empty &= list_empty(&dev_priv->bsd_ring.active_list); | |
| 5213 | 4974 | spin_unlock(&dev_priv->mm.active_list_lock); |
| 5214 | 4975 | |
| 5215 | 4976 | return !lists_empty; |
| @@ -5254,8 +5015,10 @@ rescan: · 38 unmodified lines | ||
| 5254 | 5015 | continue; |
| 5255 | 5016 | |
| 5256 | 5017 | spin_unlock(&shrink_list_lock); |
| 5018 | + i915_gem_retire_requests(dev, &dev_priv->render_ring); | |
| 5257 | 5019 | |
| 5258 | − i915_gem_retire_requests(dev); | |
| 5020 | + if (HAS_BSD(dev)) | |
| 5021 | + i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | |
| 5259 | 5022 | |
| 5260 | 5023 | list_for_each_entry_safe(obj_priv, next_obj, |
| 5261 | 5024 | &dev_priv->mm.inactive_list, |
| @@ -53,7 +53,7 @@ · 52 unmodified lines | ||
| 53 | 53 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
| 54 | 54 | |
| 55 | 55 | /** Interrupts that we mask and unmask at runtime. */ |
| 56 | −#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) | |
| 56 | +#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT | I915_BSD_USER_INTERRUPT) | |
| 57 | 57 | |
| 58 | 58 | #define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ |
| 59 | 59 | PIPE_VBLANK_INTERRUPT_STATUS) |
| @@ -74,7 +74,7 @@ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) · 14 unmodified lines | ||
| 74 | 74 | } |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | −static inline void | |
| 77 | +void | |
| 78 | 78 | ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) |
| 79 | 79 | { |
| 80 | 80 | if ((dev_priv->gt_irq_mask_reg & mask) != mask) { |
| @@ -115,7 +115,7 @@ i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) · 34 unmodified lines | ||
| 115 | 115 | } |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | −static inline void | |
| 118 | +void | |
| 119 | 119 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) |
| 120 | 120 | { |
| 121 | 121 | if ((dev_priv->irq_mask_reg & mask) != mask) { |
| @@ -278,10 +278,9 @@ static void i915_handle_rps_change(struct drm_device *dev) · 156 unmodified lines | ||
| 278 | 278 | { |
| 279 | 279 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 280 | 280 | u32 busy_up, busy_down, max_avg, min_avg; |
| 281 | − u16 rgvswctl; | |
| 282 | 281 | u8 new_delay = dev_priv->cur_delay; |
| 283 | 282 | |
| 284 | − I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS) & ~MEMINT_EVAL_CHG); | |
| 283 | + I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG); | |
| 285 | 284 | busy_up = I915_READ(RCPREVBSYTUPAVG); |
| 286 | 285 | busy_down = I915_READ(RCPREVBSYTDNAVG); |
| 287 | 286 | max_avg = I915_READ(RCBMAXAVG); |
| @@ -300,27 +299,8 @@ static void i915_handle_rps_change(struct drm_device *dev) · 12 unmodified lines | ||
| 300 | 299 | new_delay = dev_priv->min_delay; |
| 301 | 300 | } |
| 302 | 301 | |
| 303 | − DRM_DEBUG("rps change requested: %d -> %d\n", | |
| 304 | − dev_priv->cur_delay, new_delay); | |
| 305 | − | |
| 306 | − rgvswctl = I915_READ(MEMSWCTL); | |
| 307 | − if (rgvswctl & MEMCTL_CMD_STS) { | |
| 308 | − DRM_ERROR("gpu busy, RCS change rejected\n"); | |
| 309 | − return; /* still busy with another command */ | |
| 310 | − } | |
| 311 | − | |
| 312 | − /* Program the new state */ | |
| 313 | − rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | |
| 314 | − (new_delay << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | |
| 315 | − I915_WRITE(MEMSWCTL, rgvswctl); | |
| 316 | − POSTING_READ(MEMSWCTL); | |
| 317 | − | |
| 318 | − rgvswctl |= MEMCTL_CMD_STS; | |
| 319 | − I915_WRITE(MEMSWCTL, rgvswctl); | |
| 320 | − | |
| 321 | − dev_priv->cur_delay = new_delay; | |
| 322 | − | |
| 323 | − DRM_DEBUG("rps changed\n"); | |
| 302 | + if (ironlake_set_drps(dev, new_delay)) | |
| 303 | + dev_priv->cur_delay = new_delay; | |
| 324 | 304 | |
| 325 | 305 | return; |
| 326 | 306 | } |
| @@ -331,6 +311,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) · 4 unmodified lines | ||
| 331 | 311 | int ret = IRQ_NONE; |
| 332 | 312 | u32 de_iir, gt_iir, de_ier, pch_iir; |
| 333 | 313 | struct drm_i915_master_private *master_priv; |
| 314 | + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | |
| 334 | 315 | |
| 335 | 316 | /* disable master interrupt before clearing iir */ |
| 336 | 317 | de_ier = I915_READ(DEIER); |
| @@ -354,13 +335,16 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) · 17 unmodified lines | ||
| 354 | 335 | } |
| 355 | 336 | |
| 356 | 337 | if (gt_iir & GT_PIPE_NOTIFY) { |
| 357 | − u32 seqno = i915_get_gem_seqno(dev); | |
| 358 | − dev_priv->mm.irq_gem_seqno = seqno; | |
| 338 | + u32 seqno = render_ring->get_gem_seqno(dev, render_ring); | |
| 339 | + render_ring->irq_gem_seqno = seqno; | |
| 359 | 340 | trace_i915_gem_request_complete(dev, seqno); |
| 360 | − DRM_WAKEUP(&dev_priv->irq_queue); | |
| 341 | + DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | |
| 361 | 342 | dev_priv->hangcheck_count = 0; |
| 362 | 343 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
| 363 | 344 | } |
| 345 | + if (gt_iir & GT_BSD_USER_INTERRUPT) | |
| 346 | + DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | |
| 347 | + | |
| 364 | 348 | |
| 365 | 349 | if (de_iir & DE_GSE) |
| 366 | 350 | ironlake_opregion_gse_intr(dev); |
| @@ -388,7 +372,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) · 21 unmodified lines | ||
| 388 | 372 | } |
| 389 | 373 | |
| 390 | 374 | if (de_iir & DE_PCU_EVENT) { |
| 391 | − I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS)); | |
| 375 | + I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); | |
| 392 | 376 | i915_handle_rps_change(dev); |
| 393 | 377 | } |
| 394 | 378 | |
| @@ -536,17 +520,18 @@ i915_ringbuffer_last_batch(struct drm_device *dev) · 141 unmodified lines | ||
| 536 | 520 | */ |
| 537 | 521 | bbaddr = 0; |
| 538 | 522 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; |
| 539 | − ring = (u32 *)(dev_priv->ring.virtual_start + head); | |
| 523 | + ring = (u32 *)(dev_priv->render_ring.virtual_start + head); | |
| 540 | 524 | |
| 541 | − while (--ring >= (u32 *)dev_priv->ring.virtual_start) { | |
| 525 | + while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { | |
| 542 | 526 | bbaddr = i915_get_bbaddr(dev, ring); |
| 543 | 527 | if (bbaddr) |
| 544 | 528 | break; |
| 545 | 529 | } |
| 546 | 530 | |
| 547 | 531 | if (bbaddr == 0) { |
| 548 | − ring = (u32 *)(dev_priv->ring.virtual_start + dev_priv->ring.Size); | |
| 549 | − while (--ring >= (u32 *)dev_priv->ring.virtual_start) { | |
| 532 | + ring = (u32 *)(dev_priv->render_ring.virtual_start | |
| 533 | + + dev_priv->render_ring.size); | |
| 534 | + while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { | |
| 550 | 535 | bbaddr = i915_get_bbaddr(dev, ring); |
| 551 | 536 | if (bbaddr) |
| 552 | 537 | break; |
| @@ -587,7 +572,7 @@ static void i915_capture_error_state(struct drm_device *dev) · 34 unmodified lines | ||
| 587 | 572 | return; |
| 588 | 573 | } |
| 589 | 574 | |
| 590 | − error->seqno = i915_get_gem_seqno(dev); | |
| 575 | + error->seqno = i915_get_gem_seqno(dev, &dev_priv->render_ring); | |
| 591 | 576 | error->eir = I915_READ(EIR); |
| 592 | 577 | error->pgtbl_er = I915_READ(PGTBL_ER); |
| 593 | 578 | error->pipeastat = I915_READ(PIPEASTAT); |
| @@ -615,7 +600,9 @@ static void i915_capture_error_state(struct drm_device *dev) · 21 unmodified lines | ||
| 615 | 600 | batchbuffer[0] = NULL; |
| 616 | 601 | batchbuffer[1] = NULL; |
| 617 | 602 | count = 0; |
| 618 | − list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | |
| 603 | + list_for_each_entry(obj_priv, | |
| 604 | + &dev_priv->render_ring.active_list, list) { | |
| 605 | + | |
| 619 | 606 | struct drm_gem_object *obj = &obj_priv->base; |
| 620 | 607 | |
| 621 | 608 | if (batchbuffer[0] == NULL && |
| @@ -639,7 +626,8 @@ static void i915_capture_error_state(struct drm_device *dev) · 17 unmodified lines | ||
| 639 | 626 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); |
| 640 | 627 | |
| 641 | 628 | /* Record the ringbuffer */ |
| 642 | − error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj); | |
| 629 | + error->ringbuffer = i915_error_object_create(dev, | |
| 630 | + dev_priv->render_ring.gem_object); | |
| 643 | 631 | |
| 644 | 632 | /* Record buffers on the active list. */ |
| 645 | 633 | error->active_bo = NULL; |
| @@ -651,7 +639,8 @@ static void i915_capture_error_state(struct drm_device *dev) · 5 unmodified lines | ||
| 651 | 639 | |
| 652 | 640 | if (error->active_bo) { |
| 653 | 641 | int i = 0; |
| 654 | − list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | |
| 642 | + list_for_each_entry(obj_priv, | |
| 643 | + &dev_priv->render_ring.active_list, list) { | |
| 655 | 644 | struct drm_gem_object *obj = &obj_priv->base; |
| 656 | 645 | |
| 657 | 646 | error->active_bo[i].size = obj->size; |
| @@ -703,24 +692,13 @@ void i915_destroy_error_state(struct drm_device *dev) · 45 unmodified lines | ||
| 703 | 692 | i915_error_state_free(dev, error); |
| 704 | 693 | } |
| 705 | 694 | |
| 706 | −/** | |
| 707 | − * i915_handle_error - handle an error interrupt | |
| 708 | − * @dev: drm device | |
| 709 | − * | |
| 710 | − * Do some basic checking of regsiter state at error interrupt time and | |
| 711 | − * dump it to the syslog. Also call i915_capture_error_state() to make | |
| 712 | − * sure we get a record and make it available in debugfs. Fire a uevent | |
| 713 | − * so userspace knows something bad happened (should trigger collection | |
| 714 | − * of a ring dump etc.). | |
| 715 | − */ | |
| 716 | −static void i915_handle_error(struct drm_device *dev, bool wedged) | |
| 695 | +static void i915_report_and_clear_eir(struct drm_device *dev) | |
| 717 | 696 | { |
| 718 | 697 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 719 | 698 | u32 eir = I915_READ(EIR); |
| 720 | − u32 pipea_stats = I915_READ(PIPEASTAT); | |
| 721 | − u32 pipeb_stats = I915_READ(PIPEBSTAT); | |
| 722 | 699 | |
| 723 | − i915_capture_error_state(dev); | |
| 700 | + if (!eir) | |
| 701 | + return; | |
| 724 | 702 | |
| 725 | 703 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", |
| 726 | 704 | eir); |
| @@ -766,6 +744,9 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) · 39 unmodified lines | ||
| 766 | 744 | } |
| 767 | 745 | |
| 768 | 746 | if (eir & I915_ERROR_MEMORY_REFRESH) { |
| 747 | + u32 pipea_stats = I915_READ(PIPEASTAT); | |
| 748 | + u32 pipeb_stats = I915_READ(PIPEBSTAT); | |
| 749 | + | |
| 769 | 750 | printk(KERN_ERR "memory refresh error\n"); |
| 770 | 751 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", |
| 771 | 752 | pipea_stats); |
| @@ -822,6 +803,24 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) · 50 unmodified lines | ||
| 822 | 803 | I915_WRITE(EMR, I915_READ(EMR) | eir); |
| 823 | 804 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); |
| 824 | 805 | } |
| 806 | +} | |
| 807 | + | |
| 808 | +/** | |
| 809 | + * i915_handle_error - handle an error interrupt | |
| 810 | + * @dev: drm device | |
| 811 | + * | |
| 812 | + * Do some basic checking of regsiter state at error interrupt time and | |
| 813 | + * dump it to the syslog. Also call i915_capture_error_state() to make | |
| 814 | + * sure we get a record and make it available in debugfs. Fire a uevent | |
| 815 | + * so userspace knows something bad happened (should trigger collection | |
| 816 | + * of a ring dump etc.). | |
| 817 | + */ | |
| 818 | +static void i915_handle_error(struct drm_device *dev, bool wedged) | |
| 819 | +{ | |
| 820 | + struct drm_i915_private *dev_priv = dev->dev_private; | |
| 821 | + | |
| 822 | + i915_capture_error_state(dev); | |
| 823 | + i915_report_and_clear_eir(dev); | |
| 825 | 824 | |
| 826 | 825 | if (wedged) { |
| 827 | 826 | atomic_set(&dev_priv->mm.wedged, 1); |
| @@ -829,7 +828,7 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) · 1 unmodified line | ||
| 829 | 828 | /* |
| 830 | 829 | * Wakeup waiting processes so they don't hang |
| 831 | 830 | */ |
| 832 | − DRM_WAKEUP(&dev_priv->irq_queue); | |
| 831 | + DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | |
| 833 | 832 | } |
| 834 | 833 | |
| 835 | 834 | queue_work(dev_priv->wq, &dev_priv->error_work); |
| @@ -848,6 +847,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) · 12 unmodified lines | ||
| 848 | 847 | unsigned long irqflags; |
| 849 | 848 | int irq_received; |
| 850 | 849 | int ret = IRQ_NONE; |
| 850 | + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | |
| 851 | 851 | |
| 852 | 852 | atomic_inc(&dev_priv->irq_received); |
| 853 | 853 | |
| @@ -928,14 +928,18 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) · 74 unmodified lines | ||
| 928 | 928 | } |
| 929 | 929 | |
| 930 | 930 | if (iir & I915_USER_INTERRUPT) { |
| 931 | − u32 seqno = i915_get_gem_seqno(dev); | |
| 932 | − dev_priv->mm.irq_gem_seqno = seqno; | |
| 931 | + u32 seqno = | |
| 932 | + render_ring->get_gem_seqno(dev, render_ring); | |
| 933 | + render_ring->irq_gem_seqno = seqno; | |
| 933 | 934 | trace_i915_gem_request_complete(dev, seqno); |
| 934 | − DRM_WAKEUP(&dev_priv->irq_queue); | |
| 935 | + DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | |
| 935 | 936 | dev_priv->hangcheck_count = 0; |
| 936 | 937 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
| 937 | 938 | } |
| 938 | 939 | |
| 940 | + if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) | |
| 941 | + DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | |
| 942 | + | |
| 939 | 943 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) |
| 940 | 944 | intel_prepare_page_flip(dev, 0); |
| 941 | 945 | |
| @@ -984,7 +988,6 @@ static int i915_emit_irq(struct drm_device * dev) · 42 unmodified lines | ||
| 984 | 988 | { |
| 985 | 989 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 986 | 990 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
| 987 | − RING_LOCALS; | |
| 988 | 991 | |
| 989 | 992 | i915_kernel_lost_context(dev); |
| 990 | 993 | |
| @@ -1006,43 +1009,13 @@ static int i915_emit_irq(struct drm_device * dev) · 15 unmodified lines | ||
| 1006 | 1009 | return dev_priv->counter; |
| 1007 | 1010 | } |
| 1008 | 1011 | |
| 1009 | −void i915_user_irq_get(struct drm_device *dev) | |
| 1010 | −{ | |
| 1011 | − drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | |
| 1012 | − unsigned long irqflags; | |
| 1013 | − | |
| 1014 | − spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | |
| 1015 | − if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { | |
| 1016 | − if (HAS_PCH_SPLIT(dev)) | |
| 1017 | − ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | |
| 1018 | − else | |
| 1019 | − i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | |
| 1020 | − } | |
| 1021 | − spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | |
| 1022 | −} | |
| 1023 | − | |
| 1024 | −void i915_user_irq_put(struct drm_device *dev) | |
| 1025 | −{ | |
| 1026 | − drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | |
| 1027 | − unsigned long irqflags; | |
| 1028 | − | |
| 1029 | − spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | |
| 1030 | − BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); | |
| 1031 | − if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { | |
| 1032 | − if (HAS_PCH_SPLIT(dev)) | |
| 1033 | − ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | |
| 1034 | − else | |
| 1035 | − i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | |
| 1036 | − } | |
| 1037 | − spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | |
| 1038 | −} | |
| 1039 | − | |
| 1040 | 1012 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno) |
| 1041 | 1013 | { |
| 1042 | 1014 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 1015 | + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | |
| 1043 | 1016 | |
| 1044 | 1017 | if (dev_priv->trace_irq_seqno == 0) |
| 1045 | − i915_user_irq_get(dev); | |
| 1018 | + render_ring->user_irq_get(dev, render_ring); | |
| 1046 | 1019 | |
| 1047 | 1020 | dev_priv->trace_irq_seqno = seqno; |
| 1048 | 1021 | } |
| @@ -1052,6 +1025,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) · 3 unmodified lines | ||
| 1052 | 1025 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 1053 | 1026 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
| 1054 | 1027 | int ret = 0; |
| 1028 | + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | |
| 1055 | 1029 | |
| 1056 | 1030 | DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, |
| 1057 | 1031 | READ_BREADCRUMB(dev_priv)); |
| @@ -1065,10 +1039,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) · 7 unmodified lines | ||
| 1065 | 1039 | if (master_priv->sarea_priv) |
| 1066 | 1040 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; |
| 1067 | 1041 | |
| 1068 | − i915_user_irq_get(dev); | |
| 1069 | − DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, | |
| 1042 | + render_ring->user_irq_get(dev, render_ring); | |
| 1043 | + DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ, | |
| 1070 | 1044 | READ_BREADCRUMB(dev_priv) >= irq_nr); |
| 1071 | − i915_user_irq_put(dev); | |
| 1045 | + render_ring->user_irq_put(dev, render_ring); | |
| 1072 | 1046 | |
| 1073 | 1047 | if (ret == -EBUSY) { |
| 1074 | 1048 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", |
| @@ -1087,7 +1061,7 @@ int i915_irq_emit(struct drm_device *dev, void *data, · 12 unmodified lines | ||
| 1087 | 1061 | drm_i915_irq_emit_t *emit = data; |
| 1088 | 1062 | int result; |
| 1089 | 1063 | |
| 1090 | − if (!dev_priv || !dev_priv->ring.virtual_start) { | |
| 1064 | + if (!dev_priv || !dev_priv->render_ring.virtual_start) { | |
| 1091 | 1065 | DRM_ERROR("called with no initialization\n"); |
| 1092 | 1066 | return -EINVAL; |
| 1093 | 1067 | } |
| @@ -1233,9 +1207,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data, · 139 unmodified lines | ||
| 1233 | 1207 | return -EINVAL; |
| 1234 | 1208 | } |
| 1235 | 1209 | |
| 1236 | −struct drm_i915_gem_request *i915_get_tail_request(struct drm_device *dev) { | |
| 1210 | +struct drm_i915_gem_request * | |
| 1211 | +i915_get_tail_request(struct drm_device *dev) | |
| 1212 | +{ | |
| 1237 | 1213 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1238 | − return list_entry(dev_priv->mm.request_list.prev, struct drm_i915_gem_request, list); | |
| 1214 | + return list_entry(dev_priv->render_ring.request_list.prev, | |
| 1215 | + struct drm_i915_gem_request, list); | |
| 1239 | 1216 | } |
| 1240 | 1217 | |
| 1241 | 1218 | /** |
| @@ -1260,8 +1237,10 @@ void i915_hangcheck_elapsed(unsigned long data) · 18 unmodified lines | ||
| 1260 | 1237 | acthd = I915_READ(ACTHD_I965); |
| 1261 | 1238 | |
| 1262 | 1239 | /* If all work is done then ACTHD clearly hasn't advanced. */ |
| 1263 | − if (list_empty(&dev_priv->mm.request_list) || | |
| 1264 | − i915_seqno_passed(i915_get_gem_seqno(dev), i915_get_tail_request(dev)->seqno)) { | |
| 1240 | + if (list_empty(&dev_priv->render_ring.request_list) || | |
| 1241 | + i915_seqno_passed(i915_get_gem_seqno(dev, | |
| 1242 | + &dev_priv->render_ring), | |
| 1243 | + i915_get_tail_request(dev)->seqno)) { | |
| 1265 | 1244 | dev_priv->hangcheck_count = 0; |
| 1266 | 1245 | return; |
| 1267 | 1246 | } |
| @@ -1314,7 +1293,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) · 46 unmodified lines | ||
| 1314 | 1293 | /* enable kind of interrupts always enabled */ |
| 1315 | 1294 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
| 1316 | 1295 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; |
| 1317 | − u32 render_mask = GT_PIPE_NOTIFY; | |
| 1296 | + u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT; | |
| 1318 | 1297 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | |
| 1319 | 1298 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
| 1320 | 1299 | |
| @@ -1328,7 +1307,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) · 7 unmodified lines | ||
| 1328 | 1307 | (void) I915_READ(DEIER); |
| 1329 | 1308 | |
| 1330 | 1309 | /* user interrupt should be enabled, but masked initial */ |
| 1331 | − dev_priv->gt_irq_mask_reg = 0xffffffff; | |
| 1310 | + dev_priv->gt_irq_mask_reg = ~render_mask; | |
| 1332 | 1311 | dev_priv->gt_irq_enable_reg = render_mask; |
| 1333 | 1312 | |
| 1334 | 1313 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
| @@ -1391,7 +1370,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev) · 56 unmodified lines | ||
| 1391 | 1370 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
| 1392 | 1371 | u32 error_mask; |
| 1393 | 1372 | |
| 1394 | − DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | |
| 1373 | + DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue); | |
| 1374 | + | |
| 1375 | + if (HAS_BSD(dev)) | |
| 1376 | + DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue); | |
| 1395 | 1377 | |
| 1396 | 1378 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; |
| 1397 | 1379 | |
| @@ -334,6 +334,7 @@ · 333 unmodified lines | ||
| 334 | 334 | #define I915_DEBUG_INTERRUPT (1<<2) |
| 335 | 335 | #define I915_USER_INTERRUPT (1<<1) |
| 336 | 336 | #define I915_ASLE_INTERRUPT (1<<0) |
| 337 | +#define I915_BSD_USER_INTERRUPT (1<<25) | |
| 337 | 338 | #define EIR 0x020b0 |
| 338 | 339 | #define EMR 0x020b4 |
| 339 | 340 | #define ESR 0x020b8 |
| @@ -368,6 +369,36 @@ · 28 unmodified lines | ||
| 368 | 369 | #define BB_ADDR 0x02140 /* 8 bytes */ |
| 369 | 370 | #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ |
| 370 | 371 | |
| 372 | +/* GEN6 interrupt control */ | |
| 373 | +#define GEN6_RENDER_HWSTAM 0x2098 | |
| 374 | +#define GEN6_RENDER_IMR 0x20a8 | |
| 375 | +#define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) | |
| 376 | +#define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) | |
| 377 | +#define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6) | |
| 378 | +#define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) | |
| 379 | +#define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) | |
| 380 | +#define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) | |
| 381 | +#define GEN6_RENDER_SYNC_STATUS (1 << 2) | |
| 382 | +#define GEN6_RENDER_DEBUG_INTERRUPT (1 << 1) | |
| 383 | +#define GEN6_RENDER_USER_INTERRUPT (1 << 0) | |
| 384 | + | |
| 385 | +#define GEN6_BLITTER_HWSTAM 0x22098 | |
| 386 | +#define GEN6_BLITTER_IMR 0x220a8 | |
| 387 | +#define GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT (1 << 26) | |
| 388 | +#define GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR (1 << 25) | |
| 389 | +#define GEN6_BLITTER_SYNC_STATUS (1 << 24) | |
| 390 | +#define GEN6_BLITTER_USER_INTERRUPT (1 << 22) | |
| 391 | +/* | |
| 392 | + * BSD (bit stream decoder instruction and interrupt control register defines | |
| 393 | + * (G4X and Ironlake only) | |
| 394 | + */ | |
| 395 | + | |
| 396 | +#define BSD_RING_TAIL 0x04030 | |
| 397 | +#define BSD_RING_HEAD 0x04034 | |
| 398 | +#define BSD_RING_START 0x04038 | |
| 399 | +#define BSD_RING_CTL 0x0403c | |
| 400 | +#define BSD_RING_ACTHD 0x04074 | |
| 401 | +#define BSD_HWS_PGA 0x04080 | |
| 371 | 402 | |
| 372 | 403 | /* |
| 373 | 404 | * Framebuffer compression (915+ only) |
| @@ -805,6 +836,10 @@ · 431 unmodified lines | ||
| 805 | 836 | #define DCC_CHANNEL_XOR_DISABLE (1 << 10) |
| 806 | 837 | #define DCC_CHANNEL_XOR_BIT_17 (1 << 9) |
| 807 | 838 | |
| 839 | +/** Pineview MCH register contains DDR3 setting */ | |
| 840 | +#define CSHRDDR3CTL 0x101a8 | |
| 841 | +#define CSHRDDR3CTL_DDR3 (1 << 2) | |
| 842 | + | |
| 808 | 843 | /** 965 MCH register controlling DRAM channel configuration */ |
| 809 | 844 | #define C0DRB3 0x10206 |
| 810 | 845 | #define C1DRB3 0x10606 |
| @@ -826,6 +861,12 @@ · 15 unmodified lines | ||
| 826 | 861 | #define CLKCFG_MEM_800 (3 << 4) |
| 827 | 862 | #define CLKCFG_MEM_MASK (7 << 4) |
| 828 | 863 | |
| 864 | +#define TR1 0x11006 | |
| 865 | +#define TSFS 0x11020 | |
| 866 | +#define TSFS_SLOPE_MASK 0x0000ff00 | |
| 867 | +#define TSFS_SLOPE_SHIFT 8 | |
| 868 | +#define TSFS_INTR_MASK 0x000000ff | |
| 869 | + | |
| 829 | 870 | #define CRSTANDVID 0x11100 |
| 830 | 871 | #define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */ |
| 831 | 872 | #define PXVFREQ_PX_MASK 0x7f000000 |
| @@ -964,6 +1005,41 @@ · 132 unmodified lines | ||
| 964 | 1005 | #define MEMSTAT_SRC_CTL_STDBY 3 |
| 965 | 1006 | #define RCPREVBSYTUPAVG 0x113b8 |
| 966 | 1007 | #define RCPREVBSYTDNAVG 0x113bc |
| 1008 | +#define SDEW 0x1124c | |
| 1009 | +#define CSIEW0 0x11250 | |
| 1010 | +#define CSIEW1 0x11254 | |
| 1011 | +#define CSIEW2 0x11258 | |
| 1012 | +#define PEW 0x1125c | |
| 1013 | +#define DEW 0x11270 | |
| 1014 | +#define MCHAFE 0x112c0 | |
| 1015 | +#define CSIEC 0x112e0 | |
| 1016 | +#define DMIEC 0x112e4 | |
| 1017 | +#define DDREC 0x112e8 | |
| 1018 | +#define PEG0EC 0x112ec | |
| 1019 | +#define PEG1EC 0x112f0 | |
| 1020 | +#define GFXEC 0x112f4 | |
| 1021 | +#define RPPREVBSYTUPAVG 0x113b8 | |
| 1022 | +#define RPPREVBSYTDNAVG 0x113bc | |
| 1023 | +#define ECR 0x11600 | |
| 1024 | +#define ECR_GPFE (1<<31) | |
| 1025 | +#define ECR_IMONE (1<<30) | |
| 1026 | +#define ECR_CAP_MASK 0x0000001f /* Event range, 0-31 */ | |
| 1027 | +#define OGW0 0x11608 | |
| 1028 | +#define OGW1 0x1160c | |
| 1029 | +#define EG0 0x11610 | |
| 1030 | +#define EG1 0x11614 | |
| 1031 | +#define EG2 0x11618 | |
| 1032 | +#define EG3 0x1161c | |
| 1033 | +#define EG4 0x11620 | |
| 1034 | +#define EG5 0x11624 | |
| 1035 | +#define EG6 0x11628 | |
| 1036 | +#define EG7 0x1162c | |
| 1037 | +#define PXW 0x11664 | |
| 1038 | +#define PXWL 0x11680 | |
| 1039 | +#define LCFUSE02 0x116c0 | |
| 1040 | +#define LCFUSE_HIV_MASK 0x000000ff | |
| 1041 | +#define CSIPLL0 0x12c10 | |
| 1042 | +#define DDRMPLL1 0X12c20 | |
| 967 | 1043 | #define PEG_BAND_GAP_DATA 0x14d68 |
| 968 | 1044 | |
| 969 | 1045 | /* |
| @@ -1055,7 +1131,6 @@ · 85 unmodified lines | ||
| 1055 | 1131 | #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) |
| 1056 | 1132 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
| 1057 | 1133 | #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ |
| 1058 | −#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f | |
| 1059 | 1134 | |
| 1060 | 1135 | #define PORT_HOTPLUG_STAT 0x61114 |
| 1061 | 1136 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) |
| @@ -2355,6 +2430,8 @@ · 1293 unmodified lines | ||
| 2355 | 2430 | #define GT_PIPE_NOTIFY (1 << 4) |
| 2356 | 2431 | #define GT_SYNC_STATUS (1 << 2) |
| 2357 | 2432 | #define GT_USER_INTERRUPT (1 << 0) |
| 2433 | +#define GT_BSD_USER_INTERRUPT (1 << 5) | |
| 2434 | + | |
| 2358 | 2435 | |
| 2359 | 2436 | #define GTISR 0x44010 |
| 2360 | 2437 | #define GTIMR 0x44014 |
| @@ -2690,6 +2767,9 @@ · 329 unmodified lines | ||
| 2690 | 2767 | #define SDVO_ENCODING (0) |
| 2691 | 2768 | #define TMDS_ENCODING (2 << 10) |
| 2692 | 2769 | #define NULL_PACKET_VSYNC_ENABLE (1 << 9) |
| 2770 | +/* CPT */ | |
| 2771 | +#define HDMI_MODE_SELECT (1 << 9) | |
| 2772 | +#define DVI_MODE_SELECT (0) | |
| 2693 | 2773 | #define SDVOB_BORDER_ENABLE (1 << 7) |
| 2694 | 2774 | #define AUDIO_ENABLE (1 << 6) |
| 2695 | 2775 | #define VSYNC_ACTIVE_HIGH (1 << 4) |
| @@ -53,23 +53,6 @@ TRACE_EVENT(i915_gem_object_bind, · 52 unmodified lines | ||
| 53 | 53 | __entry->obj, __entry->gtt_offset) |
| 54 | 54 | ); |
| 55 | 55 | |
| 56 | −TRACE_EVENT(i915_gem_object_clflush, | |
| 57 | − | |
| 58 | − TP_PROTO(struct drm_gem_object *obj), | |
| 59 | − | |
| 60 | − TP_ARGS(obj), | |
| 61 | − | |
| 62 | − TP_STRUCT__entry( | |
| 63 | − __field(struct drm_gem_object *, obj) | |
| 64 | − ), | |
| 65 | − | |
| 66 | − TP_fast_assign( | |
| 67 | − __entry->obj = obj; | |
| 68 | − ), | |
| 69 | − | |
| 70 | − TP_printk("obj=%p", __entry->obj) | |
| 71 | −); | |
| 72 | − | |
| 73 | 56 | TRACE_EVENT(i915_gem_object_change_domain, |
| 74 | 57 | |
| 75 | 58 | TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), |
| @@ -132,6 +115,13 @@ DECLARE_EVENT_CLASS(i915_gem_object, · 56 unmodified lines | ||
| 132 | 115 | TP_printk("obj=%p", __entry->obj) |
| 133 | 116 | ); |
| 134 | 117 | |
| 118 | +DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush, | |
| 119 | + | |
| 120 | + TP_PROTO(struct drm_gem_object *obj), | |
| 121 | + | |
| 122 | + TP_ARGS(obj) | |
| 123 | +); | |
| 124 | + | |
| 135 | 125 | DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, |
| 136 | 126 | |
| 137 | 127 | TP_PROTO(struct drm_gem_object *obj), |
| @@ -95,6 +95,16 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, · 94 unmodified lines | ||
| 95 | 95 | panel_fixed_mode->clock = dvo_timing->clock * 10; |
| 96 | 96 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; |
| 97 | 97 | |
| 98 | + if (dvo_timing->hsync_positive) | |
| 99 | + panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC; | |
| 100 | + else | |
| 101 | + panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC; | |
| 102 | + | |
| 103 | + if (dvo_timing->vsync_positive) | |
| 104 | + panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC; | |
| 105 | + else | |
| 106 | + panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; | |
| 107 | + | |
| 98 | 108 | /* Some VBTs have bogus h/vtotal values */ |
| 99 | 109 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) |
| 100 | 110 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; |
| @@ -217,7 +217,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) · 216 unmodified lines | ||
| 217 | 217 | { |
| 218 | 218 | struct drm_device *dev = connector->dev; |
| 219 | 219 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 220 | − u32 hotplug_en; | |
| 220 | + u32 hotplug_en, orig, stat; | |
| 221 | + bool ret = false; | |
| 221 | 222 | int i, tries = 0; |
| 222 | 223 | |
| 223 | 224 | if (HAS_PCH_SPLIT(dev)) |
| @@ -232,8 +233,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) · 8 unmodified lines | ||
| 232 | 233 | tries = 2; |
| 233 | 234 | else |
| 234 | 235 | tries = 1; |
| 235 | − hotplug_en = I915_READ(PORT_HOTPLUG_EN); | |
| 236 | − hotplug_en &= CRT_FORCE_HOTPLUG_MASK; | |
| 236 | + hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); | |
| 237 | + hotplug_en &= CRT_HOTPLUG_MASK; | |
| 237 | 238 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
| 238 | 239 | |
| 239 | 240 | if (IS_G4X(dev)) |
| @@ -255,11 +256,17 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) · 15 unmodified lines | ||
| 255 | 256 | } while (time_after(timeout, jiffies)); |
| 256 | 257 | } |
| 257 | 258 | |
| 258 | − if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != | |
| 259 | − CRT_HOTPLUG_MONITOR_NONE) | |
| 260 | − return true; | |
| 259 | + stat = I915_READ(PORT_HOTPLUG_STAT); | |
| 260 | + if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE) | |
| 261 | + ret = true; | |
| 262 | + | |
| 263 | + /* clear the interrupt we just generated, if any */ | |
| 264 | + I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS); | |
| 261 | 265 | |
| 262 | − return false; | |
| 266 | + /* and put the bits back */ | |
| 267 | + I915_WRITE(PORT_HOTPLUG_EN, orig); | |
| 268 | + | |
| 269 | + return ret; | |
| 263 | 270 | } |
| 264 | 271 | |
| 265 | 272 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) |
| @@ -569,7 +576,7 @@ void intel_crt_init(struct drm_device *dev) · 303 unmodified lines | ||
| 569 | 576 | (1 << INTEL_ANALOG_CLONE_BIT) | |
| 570 | 577 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); |
| 571 | 578 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
| 572 | − connector->interlace_allowed = 0; | |
| 579 | + connector->interlace_allowed = 1; | |
| 573 | 580 | connector->doublescan_allowed = 0; |
| 574 | 581 | |
| 575 | 582 | drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); |
| @@ -1029,19 +1029,28 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) · 1028 unmodified lines | ||
| 1029 | 1029 | void i8xx_disable_fbc(struct drm_device *dev) |
| 1030 | 1030 | { |
| 1031 | 1031 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1032 | + unsigned long timeout = jiffies + msecs_to_jiffies(1); | |
| 1032 | 1033 | u32 fbc_ctl; |
| 1033 | 1034 | |
| 1034 | 1035 | if (!I915_HAS_FBC(dev)) |
| 1035 | 1036 | return; |
| 1036 | 1037 | |
| 1038 | + if (!(I915_READ(FBC_CONTROL) & FBC_CTL_EN)) | |
| 1039 | + return; /* Already off, just return */ | |
| 1040 | + | |
| 1037 | 1041 | /* Disable compression */ |
| 1038 | 1042 | fbc_ctl = I915_READ(FBC_CONTROL); |
| 1039 | 1043 | fbc_ctl &= ~FBC_CTL_EN; |
| 1040 | 1044 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
| 1041 | 1045 | |
| 1042 | 1046 | /* Wait for compressing bit to clear */ |
| 1043 | − while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) | |
| 1044 | − ; /* nothing */ | |
| 1047 | + while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { | |
| 1048 | + if (time_after(jiffies, timeout)) { | |
| 1049 | + DRM_DEBUG_DRIVER("FBC idle timed out\n"); | |
| 1050 | + break; | |
| 1051 | + } | |
| 1052 | + ; /* do nothing */ | |
| 1053 | + } | |
| 1045 | 1054 | |
| 1046 | 1055 | intel_wait_for_vblank(dev); |
| 1047 | 1056 | |
| @@ -1239,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc, · 191 unmodified lines | ||
| 1239 | 1248 | return; |
| 1240 | 1249 | |
| 1241 | 1250 | out_disable: |
| 1242 | − DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | |
| 1243 | 1251 | /* Multiple disables should be harmless */ |
| 1244 | − if (intel_fbc_enabled(dev)) | |
| 1252 | + if (intel_fbc_enabled(dev)) { | |
| 1253 | + DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | |
| 1245 | 1254 | intel_disable_fbc(dev); |
| 1255 | + } | |
| 1246 | 1256 | } |
| 1247 | 1257 | |
| 1248 | 1258 | static int |
| @@ -1386,7 +1396,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, · 137 unmodified lines | ||
| 1386 | 1396 | Start = obj_priv->gtt_offset; |
| 1387 | 1397 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); |
| 1388 | 1398 | |
| 1389 | − DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); | |
| 1399 | + DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | |
| 1400 | + Start, Offset, x, y, crtc->fb->pitch); | |
| 1390 | 1401 | I915_WRITE(dspstride, crtc->fb->pitch); |
| 1391 | 1402 | if (IS_I965G(dev)) { |
| 1392 | 1403 | I915_WRITE(dspbase, Offset); |
| @@ -2345,6 +2356,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, · 952 unmodified lines | ||
| 2345 | 2356 | if (mode->clock * 3 > 27000 * 4) |
| 2346 | 2357 | return MODE_CLOCK_HIGH; |
| 2347 | 2358 | } |
| 2359 | + | |
| 2360 | + drm_mode_set_crtcinfo(adjusted_mode, 0); | |
| 2348 | 2361 | return true; |
| 2349 | 2362 | } |
| 2350 | 2363 | |
| @@ -2629,6 +2642,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, · 278 unmodified lines | ||
| 2629 | 2642 | |
| 2630 | 2643 | struct cxsr_latency { |
| 2631 | 2644 | int is_desktop; |
| 2645 | + int is_ddr3; | |
| 2632 | 2646 | unsigned long fsb_freq; |
| 2633 | 2647 | unsigned long mem_freq; |
| 2634 | 2648 | unsigned long display_sr; |
| @@ -2638,33 +2652,45 @@ struct cxsr_latency { · 3 unmodified lines | ||
| 2638 | 2652 | }; |
| 2639 | 2653 | |
| 2640 | 2654 | static struct cxsr_latency cxsr_latency_table[] = { |
| 2641 | − {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | |
| 2642 | − {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | |
| 2643 | − {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | |
| 2644 | − | |
| 2645 | − {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | |
| 2646 | − {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | |
| 2647 | − {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | |
| 2648 | − | |
| 2649 | − {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | |
| 2650 | − {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | |
| 2651 | − {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | |
| 2652 | − | |
| 2653 | − {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | |
| 2654 | − {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | |
| 2655 | − {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | |
| 2656 | − | |
| 2657 | − {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | |
| 2658 | − {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | |
| 2659 | − {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | |
| 2660 | − | |
| 2661 | − {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | |
| 2662 | − {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | |
| 2663 | − {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | |
| 2655 | + {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | |
| 2656 | + {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | |
| 2657 | + {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | |
| 2658 | + {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ | |
| 2659 | + {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ | |
| 2660 | + | |
| 2661 | + {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | |
| 2662 | + {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | |
| 2663 | + {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | |
| 2664 | + {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ | |
| 2665 | + {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ | |
| 2666 | + | |
| 2667 | + {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | |
| 2668 | + {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | |
| 2669 | + {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | |
| 2670 | + {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ | |
| 2671 | + {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ | |
| 2672 | + | |
| 2673 | + {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | |
| 2674 | + {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | |
| 2675 | + {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | |
| 2676 | + {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ | |
| 2677 | + {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ | |
| 2678 | + | |
| 2679 | + {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | |
| 2680 | + {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | |
| 2681 | + {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | |
| 2682 | + {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ | |
| 2683 | + {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ | |
| 2684 | + | |
| 2685 | + {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | |
| 2686 | + {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | |
| 2687 | + {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | |
| 2688 | + {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ | |
| 2689 | + {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | |
| 2664 | 2690 | }; |
| 2665 | 2691 | |
| 2666 | −static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | |
| 2667 | − int mem) | |
| 2692 | +static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | |
| 2693 | + int fsb, int mem) | |
| 2668 | 2694 | { |
| 2669 | 2695 | int i; |
| 2670 | 2696 | struct cxsr_latency *latency; |
| @@ -2675,6 +2701,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, · 4 unmodified lines | ||
| 2675 | 2701 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { |
| 2676 | 2702 | latency = &cxsr_latency_table[i]; |
| 2677 | 2703 | if (is_desktop == latency->is_desktop && |
| 2704 | + is_ddr3 == latency->is_ddr3 && | |
| 2678 | 2705 | fsb == latency->fsb_freq && mem == latency->mem_freq) |
| 2679 | 2706 | return latency; |
| 2680 | 2707 | } |
| @@ -2789,8 +2816,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, · 108 unmodified lines | ||
| 2789 | 2816 | struct cxsr_latency *latency; |
| 2790 | 2817 | int sr_clock; |
| 2791 | 2818 | |
| 2792 | − latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, | |
| 2793 | − dev_priv->mem_freq); | |
| 2819 | + latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | |
| 2820 | + dev_priv->fsb_freq, dev_priv->mem_freq); | |
| 2794 | 2821 | if (!latency) { |
| 2795 | 2822 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
| 2796 | 2823 | pineview_disable_cxsr(dev); |
| @@ -3626,6 +3653,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, · 829 unmodified lines | ||
| 3626 | 3653 | pipeconf &= ~PIPEACONF_DOUBLE_WIDE; |
| 3627 | 3654 | } |
| 3628 | 3655 | |
| 3656 | + dspcntr |= DISPLAY_PLANE_ENABLE; | |
| 3657 | + pipeconf |= PIPEACONF_ENABLE; | |
| 3658 | + dpll |= DPLL_VCO_ENABLE; | |
| 3659 | + | |
| 3660 | + | |
| 3629 | 3661 | /* Disable the panel fitter if it was on our pipe */ |
| 3630 | 3662 | if (!HAS_PCH_SPLIT(dev) && intel_panel_fitter_pipe(dev) == pipe) |
| 3631 | 3663 | I915_WRITE(PFIT_CONTROL, 0); |
| @@ -3772,6 +3804,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, · 140 unmodified lines | ||
| 3772 | 3804 | } |
| 3773 | 3805 | } |
| 3774 | 3806 | |
| 3807 | + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { | |
| 3808 | + pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; | |
| 3809 | + /* the chip adds 2 halflines automatically */ | |
| 3810 | + adjusted_mode->crtc_vdisplay -= 1; | |
| 3811 | + adjusted_mode->crtc_vtotal -= 1; | |
| 3812 | + adjusted_mode->crtc_vblank_start -= 1; | |
| 3813 | + adjusted_mode->crtc_vblank_end -= 1; | |
| 3814 | + adjusted_mode->crtc_vsync_end -= 1; | |
| 3815 | + adjusted_mode->crtc_vsync_start -= 1; | |
| 3816 | + } else | |
| 3817 | + pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ | |
| 3818 | + | |
| 3775 | 3819 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
| 3776 | 3820 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
| 3777 | 3821 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | |
| @@ -3934,6 +3978,13 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, · 156 unmodified lines | ||
| 3934 | 3978 | DRM_ERROR("failed to pin cursor bo\n"); |
| 3935 | 3979 | goto fail_locked; |
| 3936 | 3980 | } |
| 3981 | + | |
| 3982 | + ret = i915_gem_object_set_to_gtt_domain(bo, 0); | |
| 3983 | + if (ret) { | |
| 3984 | + DRM_ERROR("failed to move cursor bo into the GTT\n"); | |
| 3985 | + goto fail_unpin; | |
| 3986 | + } | |
| 3987 | + | |
| 3937 | 3988 | addr = obj_priv->gtt_offset; |
| 3938 | 3989 | } else { |
| 3939 | 3990 | ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); |
| @@ -3977,6 +4028,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, · 37 unmodified lines | ||
| 3977 | 4028 | intel_crtc->cursor_bo = bo; |
| 3978 | 4029 | |
| 3979 | 4030 | return 0; |
| 4031 | +fail_unpin: | |
| 4032 | + i915_gem_object_unpin(bo); | |
| 3980 | 4033 | fail_locked: |
| 3981 | 4034 | mutex_unlock(&dev->struct_mutex); |
| 3982 | 4035 | fail: |
| @@ -4436,6 +4489,8 @@ static void intel_idle_update(struct work_struct *work) · 453 unmodified lines | ||
| 4436 | 4489 | |
| 4437 | 4490 | mutex_lock(&dev->struct_mutex); |
| 4438 | 4491 | |
| 4492 | + i915_update_gfx_val(dev_priv); | |
| 4493 | + | |
| 4439 | 4494 | if (IS_I945G(dev) || IS_I945GM(dev)) { |
| 4440 | 4495 | DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); |
| 4441 | 4496 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); |
| @@ -4564,12 +4619,6 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) · 122 unmodified lines | ||
| 4564 | 4619 | spin_lock_irqsave(&dev->event_lock, flags); |
| 4565 | 4620 | work = intel_crtc->unpin_work; |
| 4566 | 4621 | if (work == NULL || !work->pending) { |
| 4567 | − if (work && !work->pending) { | |
| 4568 | − obj_priv = to_intel_bo(work->pending_flip_obj); | |
| 4569 | − DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", | |
| 4570 | − obj_priv, | |
| 4571 | − atomic_read(&obj_priv->pending_flip)); | |
| 4572 | − } | |
| 4573 | 4622 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 4574 | 4623 | return; |
| 4575 | 4624 | } |
| @@ -4629,14 +4678,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, · 53 unmodified lines | ||
| 4629 | 4678 | unsigned long flags; |
| 4630 | 4679 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; |
| 4631 | 4680 | int ret, pipesrc; |
| 4632 | − RING_LOCALS; | |
| 4633 | 4681 | |
| 4634 | 4682 | work = kzalloc(sizeof *work, GFP_KERNEL); |
| 4635 | 4683 | if (work == NULL) |
| 4636 | 4684 | return -ENOMEM; |
| 4637 | 4685 | |
| 4638 | − mutex_lock(&dev->struct_mutex); | |
| 4639 | − | |
| 4640 | 4686 | work->event = event; |
| 4641 | 4687 | work->dev = crtc->dev; |
| 4642 | 4688 | intel_fb = to_intel_framebuffer(crtc->fb); |
| @@ -4646,10 +4692,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, · 3 unmodified lines | ||
| 4646 | 4692 | /* We borrow the event spin lock for protecting unpin_work */ |
| 4647 | 4693 | spin_lock_irqsave(&dev->event_lock, flags); |
| 4648 | 4694 | if (intel_crtc->unpin_work) { |
| 4649 | − DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | |
| 4650 | 4695 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 4651 | 4696 | kfree(work); |
| 4652 | − mutex_unlock(&dev->struct_mutex); | |
| 4697 | + | |
| 4698 | + DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | |
| 4653 | 4699 | return -EBUSY; |
| 4654 | 4700 | } |
| 4655 | 4701 | intel_crtc->unpin_work = work; |
| @@ -4658,13 +4704,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, · 2 unmodified lines | ||
| 4658 | 4704 | intel_fb = to_intel_framebuffer(fb); |
| 4659 | 4705 | obj = intel_fb->obj; |
| 4660 | 4706 | |
| 4707 | + mutex_lock(&dev->struct_mutex); | |
| 4661 | 4708 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
| 4662 | 4709 | if (ret != 0) { |
| 4663 | − DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | |
| 4664 | − to_intel_bo(obj)); | |
| 4665 | − kfree(work); | |
| 4666 | − intel_crtc->unpin_work = NULL; | |
| 4667 | 4710 | mutex_unlock(&dev->struct_mutex); |
| 4711 | + | |
| 4712 | + spin_lock_irqsave(&dev->event_lock, flags); | |
| 4713 | + intel_crtc->unpin_work = NULL; | |
| 4714 | + spin_unlock_irqrestore(&dev->event_lock, flags); | |
| 4715 | + | |
| 4716 | + kfree(work); | |
| 4717 | + | |
| 4718 | + DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | |
| 4719 | + to_intel_bo(obj)); | |
| 4668 | 4720 | return ret; |
| 4669 | 4721 | } |
| 4670 | 4722 | |
| @@ -5023,10 +5075,32 @@ err_unref: · 352 unmodified lines | ||
| 5023 | 5075 | return NULL; |
| 5024 | 5076 | } |
| 5025 | 5077 | |
| 5078 | +bool ironlake_set_drps(struct drm_device *dev, u8 val) | |
| 5079 | +{ | |
| 5080 | + struct drm_i915_private *dev_priv = dev->dev_private; | |
| 5081 | + u16 rgvswctl; | |
| 5082 | + | |
| 5083 | + rgvswctl = I915_READ16(MEMSWCTL); | |
| 5084 | + if (rgvswctl & MEMCTL_CMD_STS) { | |
| 5085 | + DRM_DEBUG("gpu busy, RCS change rejected\n"); | |
| 5086 | + return false; /* still busy with another command */ | |
| 5087 | + } | |
| 5088 | + | |
| 5089 | + rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | |
| 5090 | + (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | |
| 5091 | + I915_WRITE16(MEMSWCTL, rgvswctl); | |
| 5092 | + POSTING_READ16(MEMSWCTL); | |
| 5093 | + | |
| 5094 | + rgvswctl |= MEMCTL_CMD_STS; | |
| 5095 | + I915_WRITE16(MEMSWCTL, rgvswctl); | |
| 5096 | + | |
| 5097 | + return true; | |
| 5098 | +} | |
| 5099 | + | |
| 5026 | 5100 | void ironlake_enable_drps(struct drm_device *dev) |
| 5027 | 5101 | { |
| 5028 | 5102 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 5029 | − u32 rgvmodectl = I915_READ(MEMMODECTL), rgvswctl; | |
| 5103 | + u32 rgvmodectl = I915_READ(MEMMODECTL); | |
| 5030 | 5104 | u8 fmax, fmin, fstart, vstart; |
| 5031 | 5105 | int i = 0; |
| 5032 | 5106 | |
| @@ -5045,13 +5119,21 @@ void ironlake_enable_drps(struct drm_device *dev) · 12 unmodified lines | ||
| 5045 | 5119 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
| 5046 | 5120 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
| 5047 | 5121 | MEMMODE_FSTART_SHIFT; |
| 5122 | + fstart = fmax; | |
| 5123 | + | |
| 5048 | 5124 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> |
| 5049 | 5125 | PXVFREQ_PX_SHIFT; |
| 5050 | 5126 | |
| 5051 | − dev_priv->max_delay = fstart; /* can't go to fmax w/o IPS */ | |
| 5127 | + dev_priv->fmax = fstart; /* IPS callback will increase this */ | |
| 5128 | + dev_priv->fstart = fstart; | |
| 5129 | + | |
| 5130 | + dev_priv->max_delay = fmax; | |
| 5052 | 5131 | dev_priv->min_delay = fmin; |
| 5053 | 5132 | dev_priv->cur_delay = fstart; |
| 5054 | 5133 | |
| 5134 | + DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, | |
| 5135 | + fstart); | |
| 5136 | + | |
| 5055 | 5137 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); |
| 5056 | 5138 | |
| 5057 | 5139 | /* |
| @@ -5073,20 +5155,19 @@ void ironlake_enable_drps(struct drm_device *dev) · 15 unmodified lines | ||
| 5073 | 5155 | } |
| 5074 | 5156 | msleep(1); |
| 5075 | 5157 | |
| 5076 | − rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | |
| 5077 | − (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | |
| 5078 | − I915_WRITE(MEMSWCTL, rgvswctl); | |
| 5079 | − POSTING_READ(MEMSWCTL); | |
| 5158 | + ironlake_set_drps(dev, fstart); | |
| 5080 | 5159 | |
| 5081 | − rgvswctl |= MEMCTL_CMD_STS; | |
| 5082 | − I915_WRITE(MEMSWCTL, rgvswctl); | |
| 5160 | + dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + | |
| 5161 | + I915_READ(0x112e0); | |
| 5162 | + dev_priv->last_time1 = jiffies_to_msecs(jiffies); | |
| 5163 | + dev_priv->last_count2 = I915_READ(0x112f4); | |
| 5164 | + getrawmonotonic(&dev_priv->last_time2); | |
| 5083 | 5165 | } |
| 5084 | 5166 | |
| 5085 | 5167 | void ironlake_disable_drps(struct drm_device *dev) |
| 5086 | 5168 | { |
| 5087 | 5169 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 5088 | − u32 rgvswctl; | |
| 5089 | − u8 fstart; | |
| 5170 | + u16 rgvswctl = I915_READ16(MEMSWCTL); | |
| 5090 | 5171 | |
| 5091 | 5172 | /* Ack interrupts, disable EFC interrupt */ |
| 5092 | 5173 | I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); |
| @@ -5096,11 +5177,7 @@ void ironlake_disable_drps(struct drm_device *dev) · 3 unmodified lines | ||
| 5096 | 5177 | I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); |
| 5097 | 5178 | |
| 5098 | 5179 | /* Go back to the starting frequency */ |
| 5099 | − fstart = (I915_READ(MEMMODECTL) & MEMMODE_FSTART_MASK) >> | |
| 5100 | − MEMMODE_FSTART_SHIFT; | |
| 5101 | − rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | |
| 5102 | − (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | |
| 5103 | − I915_WRITE(MEMSWCTL, rgvswctl); | |
| 5180 | + ironlake_set_drps(dev, dev_priv->fstart); | |
| 5104 | 5181 | msleep(1); |
| 5105 | 5182 | rgvswctl |= MEMCTL_CMD_STS; |
| 5106 | 5183 | I915_WRITE(MEMSWCTL, rgvswctl); |
| @@ -5108,6 +5185,92 @@ void ironlake_disable_drps(struct drm_device *dev) · 1 unmodified line | ||
| 5108 | 5185 | |
| 5109 | 5186 | } |
| 5110 | 5187 | |
| 5188 | +static unsigned long intel_pxfreq(u32 vidfreq) | |
| 5189 | +{ | |
| 5190 | + unsigned long freq; | |
| 5191 | + int div = (vidfreq & 0x3f0000) >> 16; | |
| 5192 | + int post = (vidfreq & 0x3000) >> 12; | |
| 5193 | + int pre = (vidfreq & 0x7); | |
| 5194 | + | |
| 5195 | + if (!pre) | |
| 5196 | + return 0; | |
| 5197 | + | |
| 5198 | + freq = ((div * 133333) / ((1<<post) * pre)); | |
| 5199 | + | |
| 5200 | + return freq; | |
| 5201 | +} | |
| 5202 | + | |
| 5203 | +void intel_init_emon(struct drm_device *dev) | |
| 5204 | +{ | |
| 5205 | + struct drm_i915_private *dev_priv = dev->dev_private; | |
| 5206 | + u32 lcfuse; | |
| 5207 | + u8 pxw[16]; | |
| 5208 | + int i; | |
| 5209 | + | |
| 5210 | + /* Disable to program */ | |
| 5211 | + I915_WRITE(ECR, 0); | |
| 5212 | + POSTING_READ(ECR); | |
| 5213 | + | |
| 5214 | + /* Program energy weights for various events */ | |
| 5215 | + I915_WRITE(SDEW, 0x15040d00); | |
| 5216 | + I915_WRITE(CSIEW0, 0x007f0000); | |
| 5217 | + I915_WRITE(CSIEW1, 0x1e220004); | |
| 5218 | + I915_WRITE(CSIEW2, 0x04000004); | |
| 5219 | + | |
| 5220 | + for (i = 0; i < 5; i++) | |
| 5221 | + I915_WRITE(PEW + (i * 4), 0); | |
| 5222 | + for (i = 0; i < 3; i++) | |
| 5223 | + I915_WRITE(DEW + (i * 4), 0); | |
| 5224 | + | |
| 5225 | + /* Program P-state weights to account for frequency power adjustment */ | |
| 5226 | + for (i = 0; i < 16; i++) { | |
| 5227 | + u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); | |
| 5228 | + unsigned long freq = intel_pxfreq(pxvidfreq); | |
| 5229 | + unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> | |
| 5230 | + PXVFREQ_PX_SHIFT; | |
| 5231 | + unsigned long val; | |
| 5232 | + | |
| 5233 | + val = vid * vid; | |
| 5234 | + val *= (freq / 1000); | |
| 5235 | + val *= 255; | |
| 5236 | + val /= (127*127*900); | |
| 5237 | + if (val > 0xff) | |
| 5238 | + DRM_ERROR("bad pxval: %ld\n", val); | |
| 5239 | + pxw[i] = val; | |
| 5240 | + } | |
| 5241 | + /* Render standby states get 0 weight */ | |
| 5242 | + pxw[14] = 0; | |
| 5243 | + pxw[15] = 0; | |
| 5244 | + | |
| 5245 | + for (i = 0; i < 4; i++) { | |
| 5246 | + u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | | |
| 5247 | + (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); | |
| 5248 | + I915_WRITE(PXW + (i * 4), val); | |
| 5249 | + } | |
| 5250 | + | |
| 5251 | + /* Adjust magic regs to magic values (more experimental results) */ | |
| 5252 | + I915_WRITE(OGW0, 0); | |
| 5253 | + I915_WRITE(OGW1, 0); | |
| 5254 | + I915_WRITE(EG0, 0x00007f00); | |
| 5255 | + I915_WRITE(EG1, 0x0000000e); | |
| 5256 | + I915_WRITE(EG2, 0x000e0000); | |
| 5257 | + I915_WRITE(EG3, 0x68000300); | |
| 5258 | + I915_WRITE(EG4, 0x42000000); | |
| 5259 | + I915_WRITE(EG5, 0x00140031); | |
| 5260 | + I915_WRITE(EG6, 0); | |
| 5261 | + I915_WRITE(EG7, 0); | |
| 5262 | + | |
| 5263 | + for (i = 0; i < 8; i++) | |
| 5264 | + I915_WRITE(PXWL + (i * 4), 0); | |
| 5265 | + | |
| 5266 | + /* Enable PMON + select events */ | |
| 5267 | + I915_WRITE(ECR, 0x80000019); | |
| 5268 | + | |
| 5269 | + lcfuse = I915_READ(LCFUSE02); | |
| 5270 | + | |
| 5271 | + dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | |
| 5272 | +} | |
| 5273 | + | |
| 5111 | 5274 | void intel_init_clock_gating(struct drm_device *dev) |
| 5112 | 5275 | { |
| 5113 | 5276 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -5277,11 +5440,13 @@ static void intel_init_display(struct drm_device *dev) · 163 unmodified lines | ||
| 5277 | 5440 | dev_priv->display.update_wm = NULL; |
| 5278 | 5441 | } else if (IS_PINEVIEW(dev)) { |
| 5279 | 5442 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), |
| 5443 | + dev_priv->is_ddr3, | |
| 5280 | 5444 | dev_priv->fsb_freq, |
| 5281 | 5445 | dev_priv->mem_freq)) { |
| 5282 | 5446 | DRM_INFO("failed to find known CxSR latency " |
| 5283 | − "(found fsb freq %d, mem freq %d), " | |
| 5447 | + "(found ddr%s fsb freq %d, mem freq %d), " | |
| 5284 | 5448 | "disabling CxSR\n", |
| 5449 | + (dev_priv->is_ddr3 == 1) ? "3": "2", | |
| 5285 | 5450 | dev_priv->fsb_freq, dev_priv->mem_freq); |
| 5286 | 5451 | /* Disable CxSR and never update its watermark again */ |
| 5287 | 5452 | pineview_disable_cxsr(dev); |
| @@ -5310,7 +5475,6 @@ static void intel_init_display(struct drm_device *dev) · 22 unmodified lines | ||
| 5310 | 5475 | void intel_modeset_init(struct drm_device *dev) |
| 5311 | 5476 | { |
| 5312 | 5477 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 5313 | − int num_pipe; | |
| 5314 | 5478 | int i; |
| 5315 | 5479 | |
| 5316 | 5480 | drm_mode_config_init(dev); |
| @@ -5340,13 +5504,13 @@ void intel_modeset_init(struct drm_device *dev) · 23 unmodified lines | ||
| 5340 | 5504 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0); |
| 5341 | 5505 | |
| 5342 | 5506 | if (IS_MOBILE(dev) || IS_I9XX(dev)) |
| 5343 | − num_pipe = 2; | |
| 5507 | + dev_priv->num_pipe = 2; | |
| 5344 | 5508 | else |
| 5345 | − num_pipe = 1; | |
| 5509 | + dev_priv->num_pipe = 1; | |
| 5346 | 5510 | DRM_DEBUG_KMS("%d display pipe%s available.\n", |
| 5347 | − num_pipe, num_pipe > 1 ? "s" : ""); | |
| 5511 | + dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); | |
| 5348 | 5512 | |
| 5349 | − for (i = 0; i < num_pipe; i++) { | |
| 5513 | + for (i = 0; i < dev_priv->num_pipe; i++) { | |
| 5350 | 5514 | intel_crtc_init(dev, i); |
| 5351 | 5515 | } |
| 5352 | 5516 | |
| @@ -5354,8 +5518,10 @@ void intel_modeset_init(struct drm_device *dev) · 1 unmodified line | ||
| 5354 | 5518 | |
| 5355 | 5519 | intel_init_clock_gating(dev); |
| 5356 | 5520 | |
| 5357 | − if (IS_IRONLAKE_M(dev)) | |
| 5521 | + if (IS_IRONLAKE_M(dev)) { | |
| 5358 | 5522 | ironlake_enable_drps(dev); |
| 5523 | + intel_init_emon(dev); | |
| 5524 | + } | |
| 5359 | 5525 | |
| 5360 | 5526 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
| 5361 | 5527 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
| @@ -576,7 +576,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, · 575 unmodified lines | ||
| 576 | 576 | struct intel_encoder *intel_encoder; |
| 577 | 577 | struct intel_dp_priv *dp_priv; |
| 578 | 578 | |
| 579 | − if (!encoder || encoder->crtc != crtc) | |
| 579 | + if (encoder->crtc != crtc) | |
| 580 | 580 | continue; |
| 581 | 581 | |
| 582 | 582 | intel_encoder = enc_to_intel_encoder(encoder); |
| @@ -675,10 +675,9 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, · 92 unmodified lines | ||
| 675 | 675 | dp_priv->link_configuration[1] = dp_priv->lane_count; |
| 676 | 676 | |
| 677 | 677 | /* |
| 678 | − * Check for DPCD version > 1.1, | |
| 679 | − * enable enahanced frame stuff in that case | |
| 678 | + * Check for DPCD version > 1.1 and enhanced framing support | |
| 680 | 679 | */ |
| 681 | − if (dp_priv->dpcd[0] >= 0x11) { | |
| 680 | + if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | |
| 682 | 681 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
| 683 | 682 | dp_priv->DP |= DP_ENHANCED_FRAMING; |
| 684 | 683 | } |
| @@ -1208,6 +1207,8 @@ ironlake_dp_detect(struct drm_connector *connector) · 523 unmodified lines | ||
| 1208 | 1207 | if (dp_priv->dpcd[0] != 0) |
| 1209 | 1208 | status = connector_status_connected; |
| 1210 | 1209 | } |
| 1210 | + DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0], | |
| 1211 | + dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]); | |
| 1211 | 1212 | return status; |
| 1212 | 1213 | } |
| 1213 | 1214 | |
| @@ -1352,7 +1353,7 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) · 138 unmodified lines | ||
| 1352 | 1353 | struct intel_encoder *intel_encoder = NULL; |
| 1353 | 1354 | |
| 1354 | 1355 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 1355 | − if (!encoder || encoder->crtc != crtc) | |
| 1356 | + if (encoder->crtc != crtc) | |
| 1356 | 1357 | continue; |
| 1357 | 1358 | |
| 1358 | 1359 | intel_encoder = enc_to_intel_encoder(encoder); |
| @@ -105,7 +105,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev, · 104 unmodified lines | ||
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | /* Flush everything out, we'll be doing GTT only from now on */ |
| 108 | − i915_gem_object_set_to_gtt_domain(fbo, 1); | |
| 108 | + ret = i915_gem_object_set_to_gtt_domain(fbo, 1); | |
| 109 | + if (ret) { | |
| 110 | + DRM_ERROR("failed to bind fb: %d.\n", ret); | |
| 111 | + goto out_unpin; | |
| 112 | + } | |
| 109 | 113 | |
| 110 | 114 | info = framebuffer_alloc(0, device); |
| 111 | 115 | if (!info) { |
| @@ -241,6 +245,7 @@ int intel_fbdev_init(struct drm_device *dev) · 129 unmodified lines | ||
| 241 | 245 | { |
| 242 | 246 | struct intel_fbdev *ifbdev; |
| 243 | 247 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 248 | + int ret; | |
| 244 | 249 | |
| 245 | 250 | ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL); |
| 246 | 251 | if (!ifbdev) |
| @@ -249,8 +254,13 @@ int intel_fbdev_init(struct drm_device *dev) · 2 unmodified lines | ||
| 249 | 254 | dev_priv->fbdev = ifbdev; |
| 250 | 255 | ifbdev->helper.funcs = &intel_fb_helper_funcs; |
| 251 | 256 | |
| 252 | − drm_fb_helper_init(dev, &ifbdev->helper, 2, | |
| 253 | − INTELFB_CONN_LIMIT); | |
| 257 | + ret = drm_fb_helper_init(dev, &ifbdev->helper, | |
| 258 | + dev_priv->num_pipe, | |
| 259 | + INTELFB_CONN_LIMIT); | |
| 260 | + if (ret) { | |
| 261 | + kfree(ifbdev); | |
| 262 | + return ret; | |
| 263 | + } | |
| 254 | 264 | |
| 255 | 265 | drm_fb_helper_single_add_all_connectors(&ifbdev->helper); |
| 256 | 266 | drm_fb_helper_initial_config(&ifbdev->helper, 32); |
| @@ -59,8 +59,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, · 58 unmodified lines | ||
| 59 | 59 | SDVO_VSYNC_ACTIVE_HIGH | |
| 60 | 60 | SDVO_HSYNC_ACTIVE_HIGH; |
| 61 | 61 | |
| 62 | − if (hdmi_priv->has_hdmi_sink) | |
| 62 | + if (hdmi_priv->has_hdmi_sink) { | |
| 63 | 63 | sdvox |= SDVO_AUDIO_ENABLE; |
| 64 | + if (HAS_PCH_CPT(dev)) | |
| 65 | + sdvox |= HDMI_MODE_SELECT; | |
| 66 | + } | |
| 64 | 67 | |
| 65 | 68 | if (intel_crtc->pipe == 1) { |
| 66 | 69 | if (HAS_PCH_CPT(dev)) |
| @@ -211,9 +211,8 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) · 210 unmodified lines | ||
| 211 | 211 | static int intel_overlay_on(struct intel_overlay *overlay) |
| 212 | 212 | { |
| 213 | 213 | struct drm_device *dev = overlay->dev; |
| 214 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 215 | 214 | int ret; |
| 216 | − RING_LOCALS; | |
| 215 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 217 | 216 | |
| 218 | 217 | BUG_ON(overlay->active); |
| 219 | 218 | |
| @@ -227,11 +226,13 @@ static int intel_overlay_on(struct intel_overlay *overlay) · 7 unmodified lines | ||
| 227 | 226 | OUT_RING(MI_NOOP); |
| 228 | 227 | ADVANCE_LP_RING(); |
| 229 | 228 | |
| 230 | − overlay->last_flip_req = i915_add_request(dev, NULL, 0); | |
| 229 | + overlay->last_flip_req = | |
| 230 | + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | |
| 231 | 231 | if (overlay->last_flip_req == 0) |
| 232 | 232 | return -ENOMEM; |
| 233 | 233 | |
| 234 | − ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | |
| 234 | + ret = i915_do_wait_request(dev, | |
| 235 | + overlay->last_flip_req, 1, &dev_priv->render_ring); | |
| 235 | 236 | if (ret != 0) |
| 236 | 237 | return ret; |
| 237 | 238 | |
| @@ -248,7 +249,6 @@ static void intel_overlay_continue(struct intel_overlay *overlay, · 10 unmodified lines | ||
| 248 | 249 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 249 | 250 | u32 flip_addr = overlay->flip_addr; |
| 250 | 251 | u32 tmp; |
| 251 | − RING_LOCALS; | |
| 252 | 252 | |
| 253 | 253 | BUG_ON(!overlay->active); |
| 254 | 254 | |
| @@ -265,7 +265,8 @@ static void intel_overlay_continue(struct intel_overlay *overlay, · 10 unmodified lines | ||
| 265 | 265 | OUT_RING(flip_addr); |
| 266 | 266 | ADVANCE_LP_RING(); |
| 267 | 267 | |
| 268 | − overlay->last_flip_req = i915_add_request(dev, NULL, 0); | |
| 268 | + overlay->last_flip_req = | |
| 269 | + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | |
| 269 | 270 | } |
| 270 | 271 | |
| 271 | 272 | static int intel_overlay_wait_flip(struct intel_overlay *overlay) |
| @@ -274,10 +275,10 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay) · 2 unmodified lines | ||
| 274 | 275 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 275 | 276 | int ret; |
| 276 | 277 | u32 tmp; |
| 277 | − RING_LOCALS; | |
| 278 | 278 | |
| 279 | 279 | if (overlay->last_flip_req != 0) { |
| 280 | − ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | |
| 280 | + ret = i915_do_wait_request(dev, overlay->last_flip_req, | |
| 281 | + 1, &dev_priv->render_ring); | |
| 281 | 282 | if (ret == 0) { |
| 282 | 283 | overlay->last_flip_req = 0; |
| 283 | 284 | |
| @@ -296,11 +297,13 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay) · 12 unmodified lines | ||
| 296 | 297 | OUT_RING(MI_NOOP); |
| 297 | 298 | ADVANCE_LP_RING(); |
| 298 | 299 | |
| 299 | − overlay->last_flip_req = i915_add_request(dev, NULL, 0); | |
| 300 | + overlay->last_flip_req = | |
| 301 | + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | |
| 300 | 302 | if (overlay->last_flip_req == 0) |
| 301 | 303 | return -ENOMEM; |
| 302 | 304 | |
| 303 | − ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | |
| 305 | + ret = i915_do_wait_request(dev, overlay->last_flip_req, | |
| 306 | + 1, &dev_priv->render_ring); | |
| 304 | 307 | if (ret != 0) |
| 305 | 308 | return ret; |
| 306 | 309 | |
| @@ -314,9 +317,8 @@ static int intel_overlay_off(struct intel_overlay *overlay) · 7 unmodified lines | ||
| 314 | 317 | { |
| 315 | 318 | u32 flip_addr = overlay->flip_addr; |
| 316 | 319 | struct drm_device *dev = overlay->dev; |
| 317 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 320 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 318 | 321 | int ret; |
| 319 | − RING_LOCALS; | |
| 320 | 322 | |
| 321 | 323 | BUG_ON(!overlay->active); |
| 322 | 324 | |
| @@ -336,11 +338,13 @@ static int intel_overlay_off(struct intel_overlay *overlay) · 13 unmodified lines | ||
| 336 | 338 | OUT_RING(MI_NOOP); |
| 337 | 339 | ADVANCE_LP_RING(); |
| 338 | 340 | |
| 339 | − overlay->last_flip_req = i915_add_request(dev, NULL, 0); | |
| 341 | + overlay->last_flip_req = | |
| 342 | + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | |
| 340 | 343 | if (overlay->last_flip_req == 0) |
| 341 | 344 | return -ENOMEM; |
| 342 | 345 | |
| 343 | − ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | |
| 346 | + ret = i915_do_wait_request(dev, overlay->last_flip_req, | |
| 347 | + 1, &dev_priv->render_ring); | |
| 344 | 348 | if (ret != 0) |
| 345 | 349 | return ret; |
| 346 | 350 | |
| @@ -354,11 +358,13 @@ static int intel_overlay_off(struct intel_overlay *overlay) · 7 unmodified lines | ||
| 354 | 358 | OUT_RING(MI_NOOP); |
| 355 | 359 | ADVANCE_LP_RING(); |
| 356 | 360 | |
| 357 | − overlay->last_flip_req = i915_add_request(dev, NULL, 0); | |
| 361 | + overlay->last_flip_req = | |
| 362 | + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | |
| 358 | 363 | if (overlay->last_flip_req == 0) |
| 359 | 364 | return -ENOMEM; |
| 360 | 365 | |
| 361 | − ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | |
| 366 | + ret = i915_do_wait_request(dev, overlay->last_flip_req, | |
| 367 | + 1, &dev_priv->render_ring); | |
| 362 | 368 | if (ret != 0) |
| 363 | 369 | return ret; |
| 364 | 370 | |
| @@ -390,22 +396,23 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, · 25 unmodified lines | ||
| 390 | 396 | int interruptible) |
| 391 | 397 | { |
| 392 | 398 | struct drm_device *dev = overlay->dev; |
| 393 | − drm_i915_private_t *dev_priv = dev->dev_private; | |
| 394 | 399 | struct drm_gem_object *obj; |
| 400 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 395 | 401 | u32 flip_addr; |
| 396 | 402 | int ret; |
| 397 | − RING_LOCALS; | |
| 398 | 403 | |
| 399 | 404 | if (overlay->hw_wedged == HW_WEDGED) |
| 400 | 405 | return -EIO; |
| 401 | 406 | |
| 402 | 407 | if (overlay->last_flip_req == 0) { |
| 403 | − overlay->last_flip_req = i915_add_request(dev, NULL, 0); | |
| 408 | + overlay->last_flip_req = | |
| 409 | + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | |
| 404 | 410 | if (overlay->last_flip_req == 0) |
| 405 | 411 | return -ENOMEM; |
| 406 | 412 | } |
| 407 | 413 | |
| 408 | − ret = i915_do_wait_request(dev, overlay->last_flip_req, interruptible); | |
| 414 | + ret = i915_do_wait_request(dev, overlay->last_flip_req, | |
| 415 | + interruptible, &dev_priv->render_ring); | |
| 409 | 416 | if (ret != 0) |
| 410 | 417 | return ret; |
| 411 | 418 | |
| @@ -429,12 +436,13 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, · 17 unmodified lines | ||
| 429 | 436 | OUT_RING(MI_NOOP); |
| 430 | 437 | ADVANCE_LP_RING(); |
| 431 | 438 | |
| 432 | − overlay->last_flip_req = i915_add_request(dev, NULL, 0); | |
| 439 | + overlay->last_flip_req = i915_add_request(dev, NULL, | |
| 440 | + 0, &dev_priv->render_ring); | |
| 433 | 441 | if (overlay->last_flip_req == 0) |
| 434 | 442 | return -ENOMEM; |
| 435 | 443 | |
| 436 | 444 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
| 437 | − interruptible); | |
| 445 | + interruptible, &dev_priv->render_ring); | |
| 438 | 446 | if (ret != 0) |
| 439 | 447 | return ret; |
| 440 | 448 | |
| @@ -0,0 +1,849 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright © 2008-2010 Intel Corporation | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice (including the next | |
| 12 | + * paragraph) shall be included in all copies or substantial portions of the | |
| 13 | + * Software. | |
| 14 | + * | |
| 15 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 21 | + * IN THE SOFTWARE. | |
| 22 | + * | |
| 23 | + * Authors: | |
| 24 | + * Eric Anholt <eric@anholt.net> | |
| 25 | + * Zou Nan hai <nanhai.zou@intel.com> | |
| 26 | + * Xiang Hai hao<haihao.xiang@intel.com> | |
| 27 | + * | |
| 28 | + */ | |
| 29 | + | |
| 30 | +#include "drmP.h" | |
| 31 | +#include "drm.h" | |
| 32 | +#include "i915_drv.h" | |
| 33 | +#include "i915_drm.h" | |
| 34 | +#include "i915_trace.h" | |
| 35 | + | |
| 36 | +static void | |
| 37 | +render_ring_flush(struct drm_device *dev, | |
| 38 | + struct intel_ring_buffer *ring, | |
| 39 | + u32 invalidate_domains, | |
| 40 | + u32 flush_domains) | |
| 41 | +{ | |
| 42 | +#if WATCH_EXEC | |
| 43 | + DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | |
| 44 | + invalidate_domains, flush_domains); | |
| 45 | +#endif | |
| 46 | + u32 cmd; | |
| 47 | + trace_i915_gem_request_flush(dev, ring->next_seqno, | |
| 48 | + invalidate_domains, flush_domains); | |
| 49 | + | |
| 50 | + if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | |
| 51 | + /* | |
| 52 | + * read/write caches: | |
| 53 | + * | |
| 54 | + * I915_GEM_DOMAIN_RENDER is always invalidated, but is | |
| 55 | + * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is | |
| 56 | + * also flushed at 2d versus 3d pipeline switches. | |
| 57 | + * | |
| 58 | + * read-only caches: | |
| 59 | + * | |
| 60 | + * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if | |
| 61 | + * MI_READ_FLUSH is set, and is always flushed on 965. | |
| 62 | + * | |
| 63 | + * I915_GEM_DOMAIN_COMMAND may not exist? | |
| 64 | + * | |
| 65 | + * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is | |
| 66 | + * invalidated when MI_EXE_FLUSH is set. | |
| 67 | + * | |
| 68 | + * I915_GEM_DOMAIN_VERTEX, which exists on 965, is | |
| 69 | + * invalidated with every MI_FLUSH. | |
| 70 | + * | |
| 71 | + * TLBs: | |
| 72 | + * | |
| 73 | + * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND | |
| 74 | + * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and | |
| 75 | + * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER | |
| 76 | + * are flushed at any MI_FLUSH. | |
| 77 | + */ | |
| 78 | + | |
| 79 | + cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | |
| 80 | + if ((invalidate_domains|flush_domains) & | |
| 81 | + I915_GEM_DOMAIN_RENDER) | |
| 82 | + cmd &= ~MI_NO_WRITE_FLUSH; | |
| 83 | + if (!IS_I965G(dev)) { | |
| 84 | + /* | |
| 85 | + * On the 965, the sampler cache always gets flushed | |
| 86 | + * and this bit is reserved. | |
| 87 | + */ | |
| 88 | + if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) | |
| 89 | + cmd |= MI_READ_FLUSH; | |
| 90 | + } | |
| 91 | + if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) | |
| 92 | + cmd |= MI_EXE_FLUSH; | |
| 93 | + | |
| 94 | +#if WATCH_EXEC | |
| 95 | + DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | |
| 96 | +#endif | |
| 97 | + intel_ring_begin(dev, ring, 8); | |
| 98 | + intel_ring_emit(dev, ring, cmd); | |
| 99 | + intel_ring_emit(dev, ring, MI_NOOP); | |
| 100 | + intel_ring_advance(dev, ring); | |
| 101 | + } | |
| 102 | +} | |
| 103 | + | |
| 104 | +static unsigned int render_ring_get_head(struct drm_device *dev, | |
| 105 | + struct intel_ring_buffer *ring) | |
| 106 | +{ | |
| 107 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 108 | + return I915_READ(PRB0_HEAD) & HEAD_ADDR; | |
| 109 | +} | |
| 110 | + | |
| 111 | +static unsigned int render_ring_get_tail(struct drm_device *dev, | |
| 112 | + struct intel_ring_buffer *ring) | |
| 113 | +{ | |
| 114 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 115 | + return I915_READ(PRB0_TAIL) & TAIL_ADDR; | |
| 116 | +} | |
| 117 | + | |
| 118 | +static unsigned int render_ring_get_active_head(struct drm_device *dev, | |
| 119 | + struct intel_ring_buffer *ring) | |
| 120 | +{ | |
| 121 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 122 | + u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; | |
| 123 | + | |
| 124 | + return I915_READ(acthd_reg); | |
| 125 | +} | |
| 126 | + | |
| 127 | +static void render_ring_advance_ring(struct drm_device *dev, | |
| 128 | + struct intel_ring_buffer *ring) | |
| 129 | +{ | |
| 130 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 131 | + I915_WRITE(PRB0_TAIL, ring->tail); | |
| 132 | +} | |
| 133 | + | |
| 134 | +static int init_ring_common(struct drm_device *dev, | |
| 135 | + struct intel_ring_buffer *ring) | |
| 136 | +{ | |
| 137 | + u32 head; | |
| 138 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 139 | + struct drm_i915_gem_object *obj_priv; | |
| 140 | + obj_priv = to_intel_bo(ring->gem_object); | |
| 141 | + | |
| 142 | + /* Stop the ring if it's running. */ | |
| 143 | + I915_WRITE(ring->regs.ctl, 0); | |
| 144 | + I915_WRITE(ring->regs.head, 0); | |
| 145 | + I915_WRITE(ring->regs.tail, 0); | |
| 146 | + | |
| 147 | + /* Initialize the ring. */ | |
| 148 | + I915_WRITE(ring->regs.start, obj_priv->gtt_offset); | |
| 149 | + head = ring->get_head(dev, ring); | |
| 150 | + | |
| 151 | + /* G45 ring initialization fails to reset head to zero */ | |
| 152 | + if (head != 0) { | |
| 153 | + DRM_ERROR("%s head not reset to zero " | |
| 154 | + "ctl %08x head %08x tail %08x start %08x\n", | |
| 155 | + ring->name, | |
| 156 | + I915_READ(ring->regs.ctl), | |
| 157 | + I915_READ(ring->regs.head), | |
| 158 | + I915_READ(ring->regs.tail), | |
| 159 | + I915_READ(ring->regs.start)); | |
| 160 | + | |
| 161 | + I915_WRITE(ring->regs.head, 0); | |
| 162 | + | |
| 163 | + DRM_ERROR("%s head forced to zero " | |
| 164 | + "ctl %08x head %08x tail %08x start %08x\n", | |
| 165 | + ring->name, | |
| 166 | + I915_READ(ring->regs.ctl), | |
| 167 | + I915_READ(ring->regs.head), | |
| 168 | + I915_READ(ring->regs.tail), | |
| 169 | + I915_READ(ring->regs.start)); | |
| 170 | + } | |
| 171 | + | |
| 172 | + I915_WRITE(ring->regs.ctl, | |
| 173 | + ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | |
| 174 | + | RING_NO_REPORT | RING_VALID); | |
| 175 | + | |
| 176 | + head = I915_READ(ring->regs.head) & HEAD_ADDR; | |
| 177 | + /* If the head is still not zero, the ring is dead */ | |
| 178 | + if (head != 0) { | |
| 179 | + DRM_ERROR("%s initialization failed " | |
| 180 | + "ctl %08x head %08x tail %08x start %08x\n", | |
| 181 | + ring->name, | |
| 182 | + I915_READ(ring->regs.ctl), | |
| 183 | + I915_READ(ring->regs.head), | |
| 184 | + I915_READ(ring->regs.tail), | |
| 185 | + I915_READ(ring->regs.start)); | |
| 186 | + return -EIO; | |
| 187 | + } | |
| 188 | + | |
| 189 | + if (!drm_core_check_feature(dev, DRIVER_MODESET)) | |
| 190 | + i915_kernel_lost_context(dev); | |
| 191 | + else { | |
| 192 | + ring->head = ring->get_head(dev, ring); | |
| 193 | + ring->tail = ring->get_tail(dev, ring); | |
| 194 | + ring->space = ring->head - (ring->tail + 8); | |
| 195 | + if (ring->space < 0) | |
| 196 | + ring->space += ring->size; | |
| 197 | + } | |
| 198 | + return 0; | |
| 199 | +} | |
| 200 | + | |
| 201 | +static int init_render_ring(struct drm_device *dev, | |
| 202 | + struct intel_ring_buffer *ring) | |
| 203 | +{ | |
| 204 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 205 | + int ret = init_ring_common(dev, ring); | |
| 206 | + if (IS_I9XX(dev) && !IS_GEN3(dev)) { | |
| 207 | + I915_WRITE(MI_MODE, | |
| 208 | + (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); | |
| 209 | + } | |
| 210 | + return ret; | |
| 211 | +} | |
| 212 | + | |
| 213 | +#define PIPE_CONTROL_FLUSH(addr) \ | |
| 214 | +do { \ | |
| 215 | + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | |
| 216 | + PIPE_CONTROL_DEPTH_STALL | 2); \ | |
| 217 | + OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ | |
| 218 | + OUT_RING(0); \ | |
| 219 | + OUT_RING(0); \ | |
| 220 | +} while (0) | |
| 221 | + | |
| 222 | +/** | |
| 223 | + * Creates a new sequence number, emitting a write of it to the status page | |
| 224 | + * plus an interrupt, which will trigger i915_user_interrupt_handler. | |
| 225 | + * | |
| 226 | + * Must be called with struct_lock held. | |
| 227 | + * | |
| 228 | + * Returned sequence numbers are nonzero on success. | |
| 229 | + */ | |
| 230 | +static u32 | |
| 231 | +render_ring_add_request(struct drm_device *dev, | |
| 232 | + struct intel_ring_buffer *ring, | |
| 233 | + struct drm_file *file_priv, | |
| 234 | + u32 flush_domains) | |
| 235 | +{ | |
| 236 | + u32 seqno; | |
| 237 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 238 | + seqno = intel_ring_get_seqno(dev, ring); | |
| 239 | + | |
| 240 | + if (IS_GEN6(dev)) { | |
| 241 | + BEGIN_LP_RING(6); | |
| 242 | + OUT_RING(GFX_OP_PIPE_CONTROL | 3); | |
| 243 | + OUT_RING(PIPE_CONTROL_QW_WRITE | | |
| 244 | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | | |
| 245 | + PIPE_CONTROL_NOTIFY); | |
| 246 | + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | |
| 247 | + OUT_RING(seqno); | |
| 248 | + OUT_RING(0); | |
| 249 | + OUT_RING(0); | |
| 250 | + ADVANCE_LP_RING(); | |
| 251 | + } else if (HAS_PIPE_CONTROL(dev)) { | |
| 252 | + u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; | |
| 253 | + | |
| 254 | + /* | |
| 255 | + * Workaround qword write incoherence by flushing the | |
| 256 | + * PIPE_NOTIFY buffers out to memory before requesting | |
| 257 | + * an interrupt. | |
| 258 | + */ | |
| 259 | + BEGIN_LP_RING(32); | |
| 260 | + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | |
| 261 | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | |
| 262 | + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | |
| 263 | + OUT_RING(seqno); | |
| 264 | + OUT_RING(0); | |
| 265 | + PIPE_CONTROL_FLUSH(scratch_addr); | |
| 266 | + scratch_addr += 128; /* write to separate cachelines */ | |
| 267 | + PIPE_CONTROL_FLUSH(scratch_addr); | |
| 268 | + scratch_addr += 128; | |
| 269 | + PIPE_CONTROL_FLUSH(scratch_addr); | |
| 270 | + scratch_addr += 128; | |
| 271 | + PIPE_CONTROL_FLUSH(scratch_addr); | |
| 272 | + scratch_addr += 128; | |
| 273 | + PIPE_CONTROL_FLUSH(scratch_addr); | |
| 274 | + scratch_addr += 128; | |
| 275 | + PIPE_CONTROL_FLUSH(scratch_addr); | |
| 276 | + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | |
| 277 | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | |
| 278 | + PIPE_CONTROL_NOTIFY); | |
| 279 | + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | |
| 280 | + OUT_RING(seqno); | |
| 281 | + OUT_RING(0); | |
| 282 | + ADVANCE_LP_RING(); | |
| 283 | + } else { | |
| 284 | + BEGIN_LP_RING(4); | |
| 285 | + OUT_RING(MI_STORE_DWORD_INDEX); | |
| 286 | + OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | |
| 287 | + OUT_RING(seqno); | |
| 288 | + | |
| 289 | + OUT_RING(MI_USER_INTERRUPT); | |
| 290 | + ADVANCE_LP_RING(); | |
| 291 | + } | |
| 292 | + return seqno; | |
| 293 | +} | |
| 294 | + | |
| 295 | +static u32 | |
| 296 | +render_ring_get_gem_seqno(struct drm_device *dev, | |
| 297 | + struct intel_ring_buffer *ring) | |
| 298 | +{ | |
| 299 | + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | |
| 300 | + if (HAS_PIPE_CONTROL(dev)) | |
| 301 | + return ((volatile u32 *)(dev_priv->seqno_page))[0]; | |
| 302 | + else | |
| 303 | + return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | |
| 304 | +} | |
| 305 | + | |
| 306 | +static void | |
| 307 | +render_ring_get_user_irq(struct drm_device *dev, | |
| 308 | + struct intel_ring_buffer *ring) | |
| 309 | +{ | |
| 310 | + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | |
| 311 | + unsigned long irqflags; | |
| 312 | + | |
| 313 | + spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | |
| 314 | + if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) { | |
| 315 | + if (HAS_PCH_SPLIT(dev)) | |
| 316 | + ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | |
| 317 | + else | |
| 318 | + i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | |
| 319 | + } | |
| 320 | + spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | |
| 321 | +} | |
| 322 | + | |
| 323 | +static void | |
| 324 | +render_ring_put_user_irq(struct drm_device *dev, | |
| 325 | + struct intel_ring_buffer *ring) | |
| 326 | +{ | |
| 327 | + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | |
| 328 | + unsigned long irqflags; | |
| 329 | + | |
| 330 | + spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | |
| 331 | + BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0); | |
| 332 | + if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) { | |
| 333 | + if (HAS_PCH_SPLIT(dev)) | |
| 334 | + ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | |
| 335 | + else | |
| 336 | + i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | |
| 337 | + } | |
| 338 | + spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | |
| 339 | +} | |
| 340 | + | |
| 341 | +static void render_setup_status_page(struct drm_device *dev, | |
| 342 | + struct intel_ring_buffer *ring) | |
| 343 | +{ | |
| 344 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 345 | + if (IS_GEN6(dev)) { | |
| 346 | + I915_WRITE(HWS_PGA_GEN6, ring->status_page.gfx_addr); | |
| 347 | + I915_READ(HWS_PGA_GEN6); /* posting read */ | |
| 348 | + } else { | |
| 349 | + I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); | |
| 350 | + I915_READ(HWS_PGA); /* posting read */ | |
| 351 | + } | |
| 352 | + | |
| 353 | +} | |
| 354 | + | |
| 355 | +void | |
| 356 | +bsd_ring_flush(struct drm_device *dev, | |
| 357 | + struct intel_ring_buffer *ring, | |
| 358 | + u32 invalidate_domains, | |
| 359 | + u32 flush_domains) | |
| 360 | +{ | |
| 361 | + intel_ring_begin(dev, ring, 8); | |
| 362 | + intel_ring_emit(dev, ring, MI_FLUSH); | |
| 363 | + intel_ring_emit(dev, ring, MI_NOOP); | |
| 364 | + intel_ring_advance(dev, ring); | |
| 365 | +} | |
| 366 | + | |
| 367 | +static inline unsigned int bsd_ring_get_head(struct drm_device *dev, | |
| 368 | + struct intel_ring_buffer *ring) | |
| 369 | +{ | |
| 370 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 371 | + return I915_READ(BSD_RING_HEAD) & HEAD_ADDR; | |
| 372 | +} | |
| 373 | + | |
| 374 | +static inline unsigned int bsd_ring_get_tail(struct drm_device *dev, | |
| 375 | + struct intel_ring_buffer *ring) | |
| 376 | +{ | |
| 377 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 378 | + return I915_READ(BSD_RING_TAIL) & TAIL_ADDR; | |
| 379 | +} | |
| 380 | + | |
| 381 | +static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, | |
| 382 | + struct intel_ring_buffer *ring) | |
| 383 | +{ | |
| 384 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 385 | + return I915_READ(BSD_RING_ACTHD); | |
| 386 | +} | |
| 387 | + | |
| 388 | +static inline void bsd_ring_advance_ring(struct drm_device *dev, | |
| 389 | + struct intel_ring_buffer *ring) | |
| 390 | +{ | |
| 391 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 392 | + I915_WRITE(BSD_RING_TAIL, ring->tail); | |
| 393 | +} | |
| 394 | + | |
| 395 | +static int init_bsd_ring(struct drm_device *dev, | |
| 396 | + struct intel_ring_buffer *ring) | |
| 397 | +{ | |
| 398 | + return init_ring_common(dev, ring); | |
| 399 | +} | |
| 400 | + | |
| 401 | +static u32 | |
| 402 | +bsd_ring_add_request(struct drm_device *dev, | |
| 403 | + struct intel_ring_buffer *ring, | |
| 404 | + struct drm_file *file_priv, | |
| 405 | + u32 flush_domains) | |
| 406 | +{ | |
| 407 | + u32 seqno; | |
| 408 | + seqno = intel_ring_get_seqno(dev, ring); | |
| 409 | + intel_ring_begin(dev, ring, 4); | |
| 410 | + intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | |
| 411 | + intel_ring_emit(dev, ring, | |
| 412 | + I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | |
| 413 | + intel_ring_emit(dev, ring, seqno); | |
| 414 | + intel_ring_emit(dev, ring, MI_USER_INTERRUPT); | |
| 415 | + intel_ring_advance(dev, ring); | |
| 416 | + | |
| 417 | + DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); | |
| 418 | + | |
| 419 | + return seqno; | |
| 420 | +} | |
| 421 | + | |
| 422 | +static void bsd_setup_status_page(struct drm_device *dev, | |
| 423 | + struct intel_ring_buffer *ring) | |
| 424 | +{ | |
| 425 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 426 | + I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr); | |
| 427 | + I915_READ(BSD_HWS_PGA); | |
| 428 | +} | |
| 429 | + | |
| 430 | +static void | |
| 431 | +bsd_ring_get_user_irq(struct drm_device *dev, | |
| 432 | + struct intel_ring_buffer *ring) | |
| 433 | +{ | |
| 434 | + /* do nothing */ | |
| 435 | +} | |
| 436 | +static void | |
| 437 | +bsd_ring_put_user_irq(struct drm_device *dev, | |
| 438 | + struct intel_ring_buffer *ring) | |
| 439 | +{ | |
| 440 | + /* do nothing */ | |
| 441 | +} | |
| 442 | + | |
| 443 | +static u32 | |
| 444 | +bsd_ring_get_gem_seqno(struct drm_device *dev, | |
| 445 | + struct intel_ring_buffer *ring) | |
| 446 | +{ | |
| 447 | + return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | |
| 448 | +} | |
| 449 | + | |
| 450 | +static int | |
| 451 | +bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |
| 452 | + struct intel_ring_buffer *ring, | |
| 453 | + struct drm_i915_gem_execbuffer2 *exec, | |
| 454 | + struct drm_clip_rect *cliprects, | |
| 455 | + uint64_t exec_offset) | |
| 456 | +{ | |
| 457 | + uint32_t exec_start; | |
| 458 | + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | |
| 459 | + intel_ring_begin(dev, ring, 2); | |
| 460 | + intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | | |
| 461 | + (2 << 6) | MI_BATCH_NON_SECURE_I965); | |
| 462 | + intel_ring_emit(dev, ring, exec_start); | |
| 463 | + intel_ring_advance(dev, ring); | |
| 464 | + return 0; | |
| 465 | +} | |
| 466 | + | |
| 467 | + | |
| 468 | +static int | |
| 469 | +render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |
| 470 | + struct intel_ring_buffer *ring, | |
| 471 | + struct drm_i915_gem_execbuffer2 *exec, | |
| 472 | + struct drm_clip_rect *cliprects, | |
| 473 | + uint64_t exec_offset) | |
| 474 | +{ | |
| 475 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 476 | + int nbox = exec->num_cliprects; | |
| 477 | + int i = 0, count; | |
| 478 | + uint32_t exec_start, exec_len; | |
| 479 | + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | |
| 480 | + exec_len = (uint32_t) exec->batch_len; | |
| 481 | + | |
| 482 | + trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | |
| 483 | + | |
| 484 | + count = nbox ? nbox : 1; | |
| 485 | + | |
| 486 | + for (i = 0; i < count; i++) { | |
| 487 | + if (i < nbox) { | |
| 488 | + int ret = i915_emit_box(dev, cliprects, i, | |
| 489 | + exec->DR1, exec->DR4); | |
| 490 | + if (ret) | |
| 491 | + return ret; | |
| 492 | + } | |
| 493 | + | |
| 494 | + if (IS_I830(dev) || IS_845G(dev)) { | |
| 495 | + intel_ring_begin(dev, ring, 4); | |
| 496 | + intel_ring_emit(dev, ring, MI_BATCH_BUFFER); | |
| 497 | + intel_ring_emit(dev, ring, | |
| 498 | + exec_start | MI_BATCH_NON_SECURE); | |
| 499 | + intel_ring_emit(dev, ring, exec_start + exec_len - 4); | |
| 500 | + intel_ring_emit(dev, ring, 0); | |
| 501 | + } else { | |
| 502 | + intel_ring_begin(dev, ring, 4); | |
| 503 | + if (IS_I965G(dev)) { | |
| 504 | + intel_ring_emit(dev, ring, | |
| 505 | + MI_BATCH_BUFFER_START | (2 << 6) | |
| 506 | + | MI_BATCH_NON_SECURE_I965); | |
| 507 | + intel_ring_emit(dev, ring, exec_start); | |
| 508 | + } else { | |
| 509 | + intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | |
| 510 | + | (2 << 6)); | |
| 511 | + intel_ring_emit(dev, ring, exec_start | | |
| 512 | + MI_BATCH_NON_SECURE); | |
| 513 | + } | |
| 514 | + } | |
| 515 | + intel_ring_advance(dev, ring); | |
| 516 | + } | |
| 517 | + | |
| 518 | + /* XXX breadcrumb */ | |
| 519 | + return 0; | |
| 520 | +} | |
| 521 | + | |
| 522 | +static void cleanup_status_page(struct drm_device *dev, | |
| 523 | + struct intel_ring_buffer *ring) | |
| 524 | +{ | |
| 525 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 526 | + struct drm_gem_object *obj; | |
| 527 | + struct drm_i915_gem_object *obj_priv; | |
| 528 | + | |
| 529 | + obj = ring->status_page.obj; | |
| 530 | + if (obj == NULL) | |
| 531 | + return; | |
| 532 | + obj_priv = to_intel_bo(obj); | |
| 533 | + | |
| 534 | + kunmap(obj_priv->pages[0]); | |
| 535 | + i915_gem_object_unpin(obj); | |
| 536 | + drm_gem_object_unreference(obj); | |
| 537 | + ring->status_page.obj = NULL; | |
| 538 | + | |
| 539 | + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | |
| 540 | +} | |
| 541 | + | |
| 542 | +static int init_status_page(struct drm_device *dev, | |
| 543 | + struct intel_ring_buffer *ring) | |
| 544 | +{ | |
| 545 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 546 | + struct drm_gem_object *obj; | |
| 547 | + struct drm_i915_gem_object *obj_priv; | |
| 548 | + int ret; | |
| 549 | + | |
| 550 | + obj = i915_gem_alloc_object(dev, 4096); | |
| 551 | + if (obj == NULL) { | |
| 552 | + DRM_ERROR("Failed to allocate status page\n"); | |
| 553 | + ret = -ENOMEM; | |
| 554 | + goto err; | |
| 555 | + } | |
| 556 | + obj_priv = to_intel_bo(obj); | |
| 557 | + obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | |
| 558 | + | |
| 559 | + ret = i915_gem_object_pin(obj, 4096); | |
| 560 | + if (ret != 0) { | |
| 561 | + goto err_unref; | |
| 562 | + } | |
| 563 | + | |
| 564 | + ring->status_page.gfx_addr = obj_priv->gtt_offset; | |
| 565 | + ring->status_page.page_addr = kmap(obj_priv->pages[0]); | |
| 566 | + if (ring->status_page.page_addr == NULL) { | |
| 567 | + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | |
| 568 | + goto err_unpin; | |
| 569 | + } | |
| 570 | + ring->status_page.obj = obj; | |
| 571 | + memset(ring->status_page.page_addr, 0, PAGE_SIZE); | |
| 572 | + | |
| 573 | + ring->setup_status_page(dev, ring); | |
| 574 | + DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", | |
| 575 | + ring->name, ring->status_page.gfx_addr); | |
| 576 | + | |
| 577 | + return 0; | |
| 578 | + | |
| 579 | +err_unpin: | |
| 580 | + i915_gem_object_unpin(obj); | |
| 581 | +err_unref: | |
| 582 | + drm_gem_object_unreference(obj); | |
| 583 | +err: | |
| 584 | + return ret; | |
| 585 | +} | |
| 586 | + | |
| 587 | + | |
| 588 | +int intel_init_ring_buffer(struct drm_device *dev, | |
| 589 | + struct intel_ring_buffer *ring) | |
| 590 | +{ | |
| 591 | + int ret; | |
| 592 | + struct drm_i915_gem_object *obj_priv; | |
| 593 | + struct drm_gem_object *obj; | |
| 594 | + ring->dev = dev; | |
| 595 | + | |
| 596 | + if (I915_NEED_GFX_HWS(dev)) { | |
| 597 | + ret = init_status_page(dev, ring); | |
| 598 | + if (ret) | |
| 599 | + return ret; | |
| 600 | + } | |
| 601 | + | |
| 602 | + obj = i915_gem_alloc_object(dev, ring->size); | |
| 603 | + if (obj == NULL) { | |
| 604 | + DRM_ERROR("Failed to allocate ringbuffer\n"); | |
| 605 | + ret = -ENOMEM; | |
| 606 | + goto cleanup; | |
| 607 | + } | |
| 608 | + | |
| 609 | + ring->gem_object = obj; | |
| 610 | + | |
| 611 | + ret = i915_gem_object_pin(obj, ring->alignment); | |
| 612 | + if (ret != 0) { | |
| 613 | + drm_gem_object_unreference(obj); | |
| 614 | + goto cleanup; | |
| 615 | + } | |
| 616 | + | |
| 617 | + obj_priv = to_intel_bo(obj); | |
| 618 | + ring->map.size = ring->size; | |
| 619 | + ring->map.offset = dev->agp->base + obj_priv->gtt_offset; | |
| 620 | + ring->map.type = 0; | |
| 621 | + ring->map.flags = 0; | |
| 622 | + ring->map.mtrr = 0; | |
| 623 | + | |
| 624 | + drm_core_ioremap_wc(&ring->map, dev); | |
| 625 | + if (ring->map.handle == NULL) { | |
| 626 | + DRM_ERROR("Failed to map ringbuffer.\n"); | |
| 627 | + i915_gem_object_unpin(obj); | |
| 628 | + drm_gem_object_unreference(obj); | |
| 629 | + ret = -EINVAL; | |
| 630 | + goto cleanup; | |
| 631 | + } | |
| 632 | + | |
| 633 | + ring->virtual_start = ring->map.handle; | |
| 634 | + ret = ring->init(dev, ring); | |
| 635 | + if (ret != 0) { | |
| 636 | + intel_cleanup_ring_buffer(dev, ring); | |
| 637 | + return ret; | |
| 638 | + } | |
| 639 | + | |
| 640 | + if (!drm_core_check_feature(dev, DRIVER_MODESET)) | |
| 641 | + i915_kernel_lost_context(dev); | |
| 642 | + else { | |
| 643 | + ring->head = ring->get_head(dev, ring); | |
| 644 | + ring->tail = ring->get_tail(dev, ring); | |
| 645 | + ring->space = ring->head - (ring->tail + 8); | |
| 646 | + if (ring->space < 0) | |
| 647 | + ring->space += ring->size; | |
| 648 | + } | |
| 649 | + INIT_LIST_HEAD(&ring->active_list); | |
| 650 | + INIT_LIST_HEAD(&ring->request_list); | |
| 651 | + return ret; | |
| 652 | +cleanup: | |
| 653 | + cleanup_status_page(dev, ring); | |
| 654 | + return ret; | |
| 655 | +} | |
| 656 | + | |
| 657 | +void intel_cleanup_ring_buffer(struct drm_device *dev, | |
| 658 | + struct intel_ring_buffer *ring) | |
| 659 | +{ | |
| 660 | + if (ring->gem_object == NULL) | |
| 661 | + return; | |
| 662 | + | |
| 663 | + drm_core_ioremapfree(&ring->map, dev); | |
| 664 | + | |
| 665 | + i915_gem_object_unpin(ring->gem_object); | |
| 666 | + drm_gem_object_unreference(ring->gem_object); | |
| 667 | + ring->gem_object = NULL; | |
| 668 | + cleanup_status_page(dev, ring); | |
| 669 | +} | |
| 670 | + | |
| 671 | +int intel_wrap_ring_buffer(struct drm_device *dev, | |
| 672 | + struct intel_ring_buffer *ring) | |
| 673 | +{ | |
| 674 | + unsigned int *virt; | |
| 675 | + int rem; | |
| 676 | + rem = ring->size - ring->tail; | |
| 677 | + | |
| 678 | + if (ring->space < rem) { | |
| 679 | + int ret = intel_wait_ring_buffer(dev, ring, rem); | |
| 680 | + if (ret) | |
| 681 | + return ret; | |
| 682 | + } | |
| 683 | + | |
| 684 | + virt = (unsigned int *)(ring->virtual_start + ring->tail); | |
| 685 | + rem /= 4; | |
| 686 | + while (rem--) | |
| 687 | + *virt++ = MI_NOOP; | |
| 688 | + | |
| 689 | + ring->tail = 0; | |
| 690 | + | |
| 691 | + return 0; | |
| 692 | +} | |
| 693 | + | |
| 694 | +int intel_wait_ring_buffer(struct drm_device *dev, | |
| 695 | + struct intel_ring_buffer *ring, int n) | |
| 696 | +{ | |
| 697 | + unsigned long end; | |
| 698 | + | |
| 699 | + trace_i915_ring_wait_begin (dev); | |
| 700 | + end = jiffies + 3 * HZ; | |
| 701 | + do { | |
| 702 | + ring->head = ring->get_head(dev, ring); | |
| 703 | + ring->space = ring->head - (ring->tail + 8); | |
| 704 | + if (ring->space < 0) | |
| 705 | + ring->space += ring->size; | |
| 706 | + if (ring->space >= n) { | |
| 707 | + trace_i915_ring_wait_end (dev); | |
| 708 | + return 0; | |
| 709 | + } | |
| 710 | + | |
| 711 | + if (dev->primary->master) { | |
| 712 | + struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | |
| 713 | + if (master_priv->sarea_priv) | |
| 714 | + master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | |
| 715 | + } | |
| 716 | + | |
| 717 | + yield(); | |
| 718 | + } while (!time_after(jiffies, end)); | |
| 719 | + trace_i915_ring_wait_end (dev); | |
| 720 | + return -EBUSY; | |
| 721 | +} | |
| 722 | + | |
| 723 | +void intel_ring_begin(struct drm_device *dev, | |
| 724 | + struct intel_ring_buffer *ring, int n) | |
| 725 | +{ | |
| 726 | + if (unlikely(ring->tail + n > ring->size)) | |
| 727 | + intel_wrap_ring_buffer(dev, ring); | |
| 728 | + if (unlikely(ring->space < n)) | |
| 729 | + intel_wait_ring_buffer(dev, ring, n); | |
| 730 | +} | |
| 731 | + | |
| 732 | +void intel_ring_emit(struct drm_device *dev, | |
| 733 | + struct intel_ring_buffer *ring, unsigned int data) | |
| 734 | +{ | |
| 735 | + unsigned int *virt = ring->virtual_start + ring->tail; | |
| 736 | + *virt = data; | |
| 737 | + ring->tail += 4; | |
| 738 | + ring->tail &= ring->size - 1; | |
| 739 | + ring->space -= 4; | |
| 740 | +} | |
| 741 | + | |
| 742 | +void intel_ring_advance(struct drm_device *dev, | |
| 743 | + struct intel_ring_buffer *ring) | |
| 744 | +{ | |
| 745 | + ring->advance_ring(dev, ring); | |
| 746 | +} | |
| 747 | + | |
| 748 | +void intel_fill_struct(struct drm_device *dev, | |
| 749 | + struct intel_ring_buffer *ring, | |
| 750 | + void *data, | |
| 751 | + unsigned int len) | |
| 752 | +{ | |
| 753 | + unsigned int *virt = ring->virtual_start + ring->tail; | |
| 754 | + BUG_ON((len&~(4-1)) != 0); | |
| 755 | + intel_ring_begin(dev, ring, len); | |
| 756 | + memcpy(virt, data, len); | |
| 757 | + ring->tail += len; | |
| 758 | + ring->tail &= ring->size - 1; | |
| 759 | + ring->space -= len; | |
| 760 | + intel_ring_advance(dev, ring); | |
| 761 | +} | |
| 762 | + | |
| 763 | +u32 intel_ring_get_seqno(struct drm_device *dev, | |
| 764 | + struct intel_ring_buffer *ring) | |
| 765 | +{ | |
| 766 | + u32 seqno; | |
| 767 | + seqno = ring->next_seqno; | |
| 768 | + | |
| 769 | + /* reserve 0 for non-seqno */ | |
| 770 | + if (++ring->next_seqno == 0) | |
| 771 | + ring->next_seqno = 1; | |
| 772 | + return seqno; | |
| 773 | +} | |
| 774 | + | |
| 775 | +struct intel_ring_buffer render_ring = { | |
| 776 | + .name = "render ring", | |
| 777 | + .regs = { | |
| 778 | + .ctl = PRB0_CTL, | |
| 779 | + .head = PRB0_HEAD, | |
| 780 | + .tail = PRB0_TAIL, | |
| 781 | + .start = PRB0_START | |
| 782 | + }, | |
| 783 | + .ring_flag = I915_EXEC_RENDER, | |
| 784 | + .size = 32 * PAGE_SIZE, | |
| 785 | + .alignment = PAGE_SIZE, | |
| 786 | + .virtual_start = NULL, | |
| 787 | + .dev = NULL, | |
| 788 | + .gem_object = NULL, | |
| 789 | + .head = 0, | |
| 790 | + .tail = 0, | |
| 791 | + .space = 0, | |
| 792 | + .next_seqno = 1, | |
| 793 | + .user_irq_refcount = 0, | |
| 794 | + .irq_gem_seqno = 0, | |
| 795 | + .waiting_gem_seqno = 0, | |
| 796 | + .setup_status_page = render_setup_status_page, | |
| 797 | + .init = init_render_ring, | |
| 798 | + .get_head = render_ring_get_head, | |
| 799 | + .get_tail = render_ring_get_tail, | |
| 800 | + .get_active_head = render_ring_get_active_head, | |
| 801 | + .advance_ring = render_ring_advance_ring, | |
| 802 | + .flush = render_ring_flush, | |
| 803 | + .add_request = render_ring_add_request, | |
| 804 | + .get_gem_seqno = render_ring_get_gem_seqno, | |
| 805 | + .user_irq_get = render_ring_get_user_irq, | |
| 806 | + .user_irq_put = render_ring_put_user_irq, | |
| 807 | + .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer, | |
| 808 | + .status_page = {NULL, 0, NULL}, | |
| 809 | + .map = {0,} | |
| 810 | +}; | |
| 811 | + | |
| 812 | +/* ring buffer for bit-stream decoder */ | |
| 813 | + | |
| 814 | +struct intel_ring_buffer bsd_ring = { | |
| 815 | + .name = "bsd ring", | |
| 816 | + .regs = { | |
| 817 | + .ctl = BSD_RING_CTL, | |
| 818 | + .head = BSD_RING_HEAD, | |
| 819 | + .tail = BSD_RING_TAIL, | |
| 820 | + .start = BSD_RING_START | |
| 821 | + }, | |
| 822 | + .ring_flag = I915_EXEC_BSD, | |
| 823 | + .size = 32 * PAGE_SIZE, | |
| 824 | + .alignment = PAGE_SIZE, | |
| 825 | + .virtual_start = NULL, | |
| 826 | + .dev = NULL, | |
| 827 | + .gem_object = NULL, | |
| 828 | + .head = 0, | |
| 829 | + .tail = 0, | |
| 830 | + .space = 0, | |
| 831 | + .next_seqno = 1, | |
| 832 | + .user_irq_refcount = 0, | |
| 833 | + .irq_gem_seqno = 0, | |
| 834 | + .waiting_gem_seqno = 0, | |
| 835 | + .setup_status_page = bsd_setup_status_page, | |
| 836 | + .init = init_bsd_ring, | |
| 837 | + .get_head = bsd_ring_get_head, | |
| 838 | + .get_tail = bsd_ring_get_tail, | |
| 839 | + .get_active_head = bsd_ring_get_active_head, | |
| 840 | + .advance_ring = bsd_ring_advance_ring, | |
| 841 | + .flush = bsd_ring_flush, | |
| 842 | + .add_request = bsd_ring_add_request, | |
| 843 | + .get_gem_seqno = bsd_ring_get_gem_seqno, | |
| 844 | + .user_irq_get = bsd_ring_get_user_irq, | |
| 845 | + .user_irq_put = bsd_ring_put_user_irq, | |
| 846 | + .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer, | |
| 847 | + .status_page = {NULL, 0, NULL}, | |
| 848 | + .map = {0,} | |
| 849 | +}; | |
| @@ -0,0 +1,124 @@ | ||
| 1 | +#ifndef _INTEL_RINGBUFFER_H_ | |
| 2 | +#define _INTEL_RINGBUFFER_H_ | |
| 3 | + | |
| 4 | +struct intel_hw_status_page { | |
| 5 | + void *page_addr; | |
| 6 | + unsigned int gfx_addr; | |
| 7 | + struct drm_gem_object *obj; | |
| 8 | +}; | |
| 9 | + | |
| 10 | +struct drm_i915_gem_execbuffer2; | |
| 11 | +struct intel_ring_buffer { | |
| 12 | + const char *name; | |
| 13 | + struct ring_regs { | |
| 14 | + u32 ctl; | |
| 15 | + u32 head; | |
| 16 | + u32 tail; | |
| 17 | + u32 start; | |
| 18 | + } regs; | |
| 19 | + unsigned int ring_flag; | |
| 20 | + unsigned long size; | |
| 21 | + unsigned int alignment; | |
| 22 | + void *virtual_start; | |
| 23 | + struct drm_device *dev; | |
| 24 | + struct drm_gem_object *gem_object; | |
| 25 | + | |
| 26 | + unsigned int head; | |
| 27 | + unsigned int tail; | |
| 28 | + unsigned int space; | |
| 29 | + u32 next_seqno; | |
| 30 | + struct intel_hw_status_page status_page; | |
| 31 | + | |
| 32 | + u32 irq_gem_seqno; /* last seq seem at irq time */ | |
| 33 | + u32 waiting_gem_seqno; | |
| 34 | + int user_irq_refcount; | |
| 35 | + void (*user_irq_get)(struct drm_device *dev, | |
| 36 | + struct intel_ring_buffer *ring); | |
| 37 | + void (*user_irq_put)(struct drm_device *dev, | |
| 38 | + struct intel_ring_buffer *ring); | |
| 39 | + void (*setup_status_page)(struct drm_device *dev, | |
| 40 | + struct intel_ring_buffer *ring); | |
| 41 | + | |
| 42 | + int (*init)(struct drm_device *dev, | |
| 43 | + struct intel_ring_buffer *ring); | |
| 44 | + | |
| 45 | + unsigned int (*get_head)(struct drm_device *dev, | |
| 46 | + struct intel_ring_buffer *ring); | |
| 47 | + unsigned int (*get_tail)(struct drm_device *dev, | |
| 48 | + struct intel_ring_buffer *ring); | |
| 49 | + unsigned int (*get_active_head)(struct drm_device *dev, | |
| 50 | + struct intel_ring_buffer *ring); | |
| 51 | + void (*advance_ring)(struct drm_device *dev, | |
| 52 | + struct intel_ring_buffer *ring); | |
| 53 | + void (*flush)(struct drm_device *dev, | |
| 54 | + struct intel_ring_buffer *ring, | |
| 55 | + u32 invalidate_domains, | |
| 56 | + u32 flush_domains); | |
| 57 | + u32 (*add_request)(struct drm_device *dev, | |
| 58 | + struct intel_ring_buffer *ring, | |
| 59 | + struct drm_file *file_priv, | |
| 60 | + u32 flush_domains); | |
| 61 | + u32 (*get_gem_seqno)(struct drm_device *dev, | |
| 62 | + struct intel_ring_buffer *ring); | |
| 63 | + int (*dispatch_gem_execbuffer)(struct drm_device *dev, | |
| 64 | + struct intel_ring_buffer *ring, | |
| 65 | + struct drm_i915_gem_execbuffer2 *exec, | |
| 66 | + struct drm_clip_rect *cliprects, | |
| 67 | + uint64_t exec_offset); | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * List of objects currently involved in rendering from the | |
| 71 | + * ringbuffer. | |
| 72 | + * | |
| 73 | + * Includes buffers having the contents of their GPU caches | |
| 74 | + * flushed, not necessarily primitives. last_rendering_seqno | |
| 75 | + * represents when the rendering involved will be completed. | |
| 76 | + * | |
| 77 | + * A reference is held on the buffer while on this list. | |
| 78 | + */ | |
| 79 | + struct list_head active_list; | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * List of breadcrumbs associated with GPU requests currently | |
| 83 | + * outstanding. | |
| 84 | + */ | |
| 85 | + struct list_head request_list; | |
| 86 | + | |
| 87 | + wait_queue_head_t irq_queue; | |
| 88 | + drm_local_map_t map; | |
| 89 | +}; | |
| 90 | + | |
| 91 | +static inline u32 | |
| 92 | +intel_read_status_page(struct intel_ring_buffer *ring, | |
| 93 | + int reg) | |
| 94 | +{ | |
| 95 | + u32 *regs = ring->status_page.page_addr; | |
| 96 | + return regs[reg]; | |
| 97 | +} | |
| 98 | + | |
| 99 | +int intel_init_ring_buffer(struct drm_device *dev, | |
| 100 | + struct intel_ring_buffer *ring); | |
| 101 | +void intel_cleanup_ring_buffer(struct drm_device *dev, | |
| 102 | + struct intel_ring_buffer *ring); | |
| 103 | +int intel_wait_ring_buffer(struct drm_device *dev, | |
| 104 | + struct intel_ring_buffer *ring, int n); | |
| 105 | +int intel_wrap_ring_buffer(struct drm_device *dev, | |
| 106 | + struct intel_ring_buffer *ring); | |
| 107 | +void intel_ring_begin(struct drm_device *dev, | |
| 108 | + struct intel_ring_buffer *ring, int n); | |
| 109 | +void intel_ring_emit(struct drm_device *dev, | |
| 110 | + struct intel_ring_buffer *ring, u32 data); | |
| 111 | +void intel_fill_struct(struct drm_device *dev, | |
| 112 | + struct intel_ring_buffer *ring, | |
| 113 | + void *data, | |
| 114 | + unsigned int len); | |
| 115 | +void intel_ring_advance(struct drm_device *dev, | |
| 116 | + struct intel_ring_buffer *ring); | |
| 117 | + | |
| 118 | +u32 intel_ring_get_seqno(struct drm_device *dev, | |
| 119 | + struct intel_ring_buffer *ring); | |
| 120 | + | |
| 121 | +extern struct intel_ring_buffer render_ring; | |
| 122 | +extern struct intel_ring_buffer bsd_ring; | |
| 123 | + | |
| 124 | +#endif /* _INTEL_RINGBUFFER_H_ */ | |
| @@ -1479,7 +1479,7 @@ intel_find_analog_connector(struct drm_device *dev) · 1478 unmodified lines | ||
| 1479 | 1479 | intel_encoder = enc_to_intel_encoder(encoder); |
| 1480 | 1480 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { |
| 1481 | 1481 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 1482 | − if (connector && encoder == intel_attached_encoder(connector)) | |
| 1482 | + if (encoder == intel_attached_encoder(connector)) | |
| 1483 | 1483 | return connector; |
| 1484 | 1484 | } |
| 1485 | 1485 | } |
| @@ -34,7 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | static struct nouveau_dsm_priv { |
| 35 | 35 | bool dsm_detected; |
| 36 | 36 | acpi_handle dhandle; |
| 37 | − acpi_handle dsm_handle; | |
| 37 | + acpi_handle rom_handle; | |
| 38 | 38 | } nouveau_dsm_priv; |
| 39 | 39 | |
| 40 | 40 | static const char nouveau_dsm_muid[] = { |
| @@ -107,9 +107,9 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero · 66 unmodified lines | ||
| 107 | 107 | static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) |
| 108 | 108 | { |
| 109 | 109 | if (id == VGA_SWITCHEROO_IGD) |
| 110 | − return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_STAMINA); | |
| 110 | + return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); | |
| 111 | 111 | else |
| 112 | − return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_SPEED); | |
| 112 | + return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED); | |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | 115 | static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, |
| @@ -118,7 +118,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, · 2 unmodified lines | ||
| 118 | 118 | if (id == VGA_SWITCHEROO_IGD) |
| 119 | 119 | return 0; |
| 120 | 120 | |
| 121 | − return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dsm_handle, state); | |
| 121 | + return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); | |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | static int nouveau_dsm_init(void) |
| @@ -151,18 +151,18 @@ static bool nouveau_dsm_pci_probe(struct pci_dev *pdev) · 26 unmodified lines | ||
| 151 | 151 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); |
| 152 | 152 | if (!dhandle) |
| 153 | 153 | return false; |
| 154 | + | |
| 154 | 155 | status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle); |
| 155 | 156 | if (ACPI_FAILURE(status)) { |
| 156 | 157 | return false; |
| 157 | 158 | } |
| 158 | 159 | |
| 159 | − ret= nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED, | |
| 160 | − NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); | |
| 160 | + ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED, | |
| 161 | + NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); | |
| 161 | 162 | if (ret < 0) |
| 162 | 163 | return false; |
| 163 | 164 | |
| 164 | 165 | nouveau_dsm_priv.dhandle = dhandle; |
| 165 | − nouveau_dsm_priv.dsm_handle = nvidia_handle; | |
| 166 | 166 | return true; |
| 167 | 167 | } |
| 168 | 168 | |
| @@ -173,6 +173,7 @@ static bool nouveau_dsm_detect(void) · 4 unmodified lines | ||
| 173 | 173 | struct pci_dev *pdev = NULL; |
| 174 | 174 | int has_dsm = 0; |
| 175 | 175 | int vga_count = 0; |
| 176 | + | |
| 176 | 177 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { |
| 177 | 178 | vga_count++; |
| 178 | 179 | |
| @@ -180,7 +181,7 @@ static bool nouveau_dsm_detect(void) · 1 unmodified line | ||
| 180 | 181 | } |
| 181 | 182 | |
| 182 | 183 | if (vga_count == 2 && has_dsm) { |
| 183 | − acpi_get_name(nouveau_dsm_priv.dsm_handle, ACPI_FULL_PATHNAME, &buffer); | |
| 184 | + acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer); | |
| 184 | 185 | printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", |
| 185 | 186 | acpi_method_name); |
| 186 | 187 | nouveau_dsm_priv.dsm_detected = true; |
| @@ -204,3 +205,57 @@ void nouveau_unregister_dsm_handler(void) · 17 unmodified lines | ||
| 204 | 205 | { |
| 205 | 206 | vga_switcheroo_unregister_handler(); |
| 206 | 207 | } |
| 208 | + | |
| 209 | +/* retrieve the ROM in 4k blocks */ | |
| 210 | +static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios, | |
| 211 | + int offset, int len) | |
| 212 | +{ | |
| 213 | + acpi_status status; | |
| 214 | + union acpi_object rom_arg_elements[2], *obj; | |
| 215 | + struct acpi_object_list rom_arg; | |
| 216 | + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | |
| 217 | + | |
| 218 | + rom_arg.count = 2; | |
| 219 | + rom_arg.pointer = &rom_arg_elements[0]; | |
| 220 | + | |
| 221 | + rom_arg_elements[0].type = ACPI_TYPE_INTEGER; | |
| 222 | + rom_arg_elements[0].integer.value = offset; | |
| 223 | + | |
| 224 | + rom_arg_elements[1].type = ACPI_TYPE_INTEGER; | |
| 225 | + rom_arg_elements[1].integer.value = len; | |
| 226 | + | |
| 227 | + status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); | |
| 228 | + if (ACPI_FAILURE(status)) { | |
| 229 | + printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status)); | |
| 230 | + return -ENODEV; | |
| 231 | + } | |
| 232 | + obj = (union acpi_object *)buffer.pointer; | |
| 233 | + memcpy(bios+offset, obj->buffer.pointer, len); | |
| 234 | + kfree(buffer.pointer); | |
| 235 | + return len; | |
| 236 | +} | |
| 237 | + | |
| 238 | +bool nouveau_acpi_rom_supported(struct pci_dev *pdev) | |
| 239 | +{ | |
| 240 | + acpi_status status; | |
| 241 | + acpi_handle dhandle, rom_handle; | |
| 242 | + | |
| 243 | + if (!nouveau_dsm_priv.dsm_detected) | |
| 244 | + return false; | |
| 245 | + | |
| 246 | + dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); | |
| 247 | + if (!dhandle) | |
| 248 | + return false; | |
| 249 | + | |
| 250 | + status = acpi_get_handle(dhandle, "_ROM", &rom_handle); | |
| 251 | + if (ACPI_FAILURE(status)) | |
| 252 | + return false; | |
| 253 | + | |
| 254 | + nouveau_dsm_priv.rom_handle = rom_handle; | |
| 255 | + return true; | |
| 256 | +} | |
| 257 | + | |
| 258 | +int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) | |
| 259 | +{ | |
| 260 | + return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); | |
| 261 | +} | |
| @@ -178,6 +178,25 @@ out: · 177 unmodified lines | ||
| 178 | 178 | pci_disable_rom(dev->pdev); |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | +static void load_vbios_acpi(struct drm_device *dev, uint8_t *data) | |
| 182 | +{ | |
| 183 | + int i; | |
| 184 | + int ret; | |
| 185 | + int size = 64 * 1024; | |
| 186 | + | |
| 187 | + if (!nouveau_acpi_rom_supported(dev->pdev)) | |
| 188 | + return; | |
| 189 | + | |
| 190 | + for (i = 0; i < (size / ROM_BIOS_PAGE); i++) { | |
| 191 | + ret = nouveau_acpi_get_bios_chunk(data, | |
| 192 | + (i * ROM_BIOS_PAGE), | |
| 193 | + ROM_BIOS_PAGE); | |
| 194 | + if (ret <= 0) | |
| 195 | + break; | |
| 196 | + } | |
| 197 | + return; | |
| 198 | +} | |
| 199 | + | |
| 181 | 200 | struct methods { |
| 182 | 201 | const char desc[8]; |
| 183 | 202 | void (*loadbios)(struct drm_device *, uint8_t *); |
| @@ -191,6 +210,7 @@ static struct methods nv04_methods[] = { · 7 unmodified lines | ||
| 191 | 210 | }; |
| 192 | 211 | |
| 193 | 212 | static struct methods nv50_methods[] = { |
| 213 | + { "ACPI", load_vbios_acpi, true }, | |
| 194 | 214 | { "PRAMIN", load_vbios_pramin, true }, |
| 195 | 215 | { "PROM", load_vbios_prom, false }, |
| 196 | 216 | { "PCIROM", load_vbios_pci, true }, |
| @@ -814,7 +834,7 @@ init_i2c_device_find(struct drm_device *dev, int i2c_index) · 617 unmodified lines | ||
| 814 | 834 | if (i2c_index == 0x81) |
| 815 | 835 | i2c_index = (dcb->i2c_default_indices & 0xf0) >> 4; |
| 816 | 836 | |
| 817 | − if (i2c_index > DCB_MAX_NUM_I2C_ENTRIES) { | |
| 837 | + if (i2c_index >= DCB_MAX_NUM_I2C_ENTRIES) { | |
| 818 | 838 | NV_ERROR(dev, "invalid i2c_index 0x%x\n", i2c_index); |
| 819 | 839 | return NULL; |
| 820 | 840 | } |
| @@ -2807,7 +2827,10 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) · 1986 unmodified lines | ||
| 2807 | 2827 | |
| 2808 | 2828 | BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); |
| 2809 | 2829 | |
| 2810 | − nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); | |
| 2830 | + BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", | |
| 2831 | + offset, gpio->tag, gpio->state_default); | |
| 2832 | + if (bios->execute) | |
| 2833 | + nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); | |
| 2811 | 2834 | |
| 2812 | 2835 | /* The NVIDIA binary driver doesn't appear to actually do |
| 2813 | 2836 | * any of this, my VBIOS does however. |
| @@ -3897,7 +3920,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b · 1083 unmodified lines | ||
| 3897 | 3920 | |
| 3898 | 3921 | static uint8_t * |
| 3899 | 3922 | bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, |
| 3900 | − uint16_t record, int record_len, int record_nr) | |
| 3923 | + uint16_t record, int record_len, int record_nr, | |
| 3924 | + bool match_link) | |
| 3901 | 3925 | { |
| 3902 | 3926 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 3903 | 3927 | struct nvbios *bios = &dev_priv->vbios; |
| @@ -3905,12 +3929,28 @@ bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, · 1 unmodified line | ||
| 3905 | 3929 | uint16_t table; |
| 3906 | 3930 | int i, v; |
| 3907 | 3931 | |
| 3932 | + switch (dcbent->type) { | |
| 3933 | + case OUTPUT_TMDS: | |
| 3934 | + case OUTPUT_LVDS: | |
| 3935 | + case OUTPUT_DP: | |
| 3936 | + break; | |
| 3937 | + default: | |
| 3938 | + match_link = false; | |
| 3939 | + break; | |
| 3940 | + } | |
| 3941 | + | |
| 3908 | 3942 | for (i = 0; i < record_nr; i++, record += record_len) { |
| 3909 | 3943 | table = ROM16(bios->data[record]); |
| 3910 | 3944 | if (!table) |
| 3911 | 3945 | continue; |
| 3912 | 3946 | entry = ROM32(bios->data[table]); |
| 3913 | 3947 | |
| 3948 | + if (match_link) { | |
| 3949 | + v = (entry & 0x00c00000) >> 22; | |
| 3950 | + if (!(v & dcbent->sorconf.link)) | |
| 3951 | + continue; | |
| 3952 | + } | |
| 3953 | + | |
| 3914 | 3954 | v = (entry & 0x000f0000) >> 16; |
| 3915 | 3955 | if (!(v & dcbent->or)) |
| 3916 | 3956 | continue; |
| @@ -3952,7 +3992,7 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, · 35 unmodified lines | ||
| 3952 | 3992 | *length = table[4]; |
| 3953 | 3993 | return bios_output_config_match(dev, dcbent, |
| 3954 | 3994 | bios->display.dp_table_ptr + table[1], |
| 3955 | − table[2], table[3]); | |
| 3995 | + table[2], table[3], table[0] >= 0x21); | |
| 3956 | 3996 | } |
| 3957 | 3997 | |
| 3958 | 3998 | int |
| @@ -4041,7 +4081,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, · 82 unmodified lines | ||
| 4041 | 4081 | dcbent->type, dcbent->location, dcbent->or); |
| 4042 | 4082 | otable = bios_output_config_match(dev, dcbent, table[1] + |
| 4043 | 4083 | bios->display.script_table_ptr, |
| 4044 | − table[2], table[3]); | |
| 4084 | + table[2], table[3], table[0] >= 0x21); | |
| 4045 | 4085 | if (!otable) { |
| 4046 | 4086 | NV_ERROR(dev, "Couldn't find matching output script table\n"); |
| 4047 | 4087 | return 1; |
| @@ -5533,12 +5573,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, · 1485 unmodified lines | ||
| 5533 | 5573 | entry->bus = (conn >> 16) & 0xf; |
| 5534 | 5574 | entry->location = (conn >> 20) & 0x3; |
| 5535 | 5575 | entry->or = (conn >> 24) & 0xf; |
| 5536 | − /* | |
| 5537 | − * Normal entries consist of a single bit, but dual link has the | |
| 5538 | − * next most significant bit set too | |
| 5539 | − */ | |
| 5540 | − entry->duallink_possible = | |
| 5541 | − ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); | |
| 5542 | 5576 | |
| 5543 | 5577 | switch (entry->type) { |
| 5544 | 5578 | case OUTPUT_ANALOG: |
| @@ -5622,6 +5656,16 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, · 77 unmodified lines | ||
| 5622 | 5656 | break; |
| 5623 | 5657 | } |
| 5624 | 5658 | |
| 5659 | + if (dcb->version < 0x40) { | |
| 5660 | + /* Normal entries consist of a single bit, but dual link has | |
| 5661 | + * the next most significant bit set too | |
| 5662 | + */ | |
| 5663 | + entry->duallink_possible = | |
| 5664 | + ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); | |
| 5665 | + } else { | |
| 5666 | + entry->duallink_possible = (entry->sorconf.link == 3); | |
| 5667 | + } | |
| 5668 | + | |
| 5625 | 5669 | /* unsure what DCB version introduces this, 3.0? */ |
| 5626 | 5670 | if (conf & 0x100000) |
| 5627 | 5671 | entry->i2c_upper_default = true; |
| @@ -6205,6 +6249,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev) · 577 unmodified lines | ||
| 6205 | 6249 | nouveau_i2c_fini(dev, entry); |
| 6206 | 6250 | } |
| 6207 | 6251 | |
| 6252 | +static bool | |
| 6253 | +nouveau_bios_posted(struct drm_device *dev) | |
| 6254 | +{ | |
| 6255 | + struct drm_nouveau_private *dev_priv = dev->dev_private; | |
| 6256 | + bool was_locked; | |
| 6257 | + unsigned htotal; | |
| 6258 | + | |
| 6259 | + if (dev_priv->chipset >= NV_50) { | |
| 6260 | + if (NVReadVgaCrtc(dev, 0, 0x00) == 0 && | |
| 6261 | + NVReadVgaCrtc(dev, 0, 0x1a) == 0) | |
| 6262 | + return false; | |
| 6263 | + return true; | |
| 6264 | + } | |
| 6265 | + | |
| 6266 | + was_locked = NVLockVgaCrtcs(dev, false); | |
| 6267 | + htotal = NVReadVgaCrtc(dev, 0, 0x06); | |
| 6268 | + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; | |
| 6269 | + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; | |
| 6270 | + htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; | |
| 6271 | + htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; | |
| 6272 | + NVLockVgaCrtcs(dev, was_locked); | |
| 6273 | + return (htotal != 0); | |
| 6274 | +} | |
| 6275 | + | |
| 6208 | 6276 | int |
| 6209 | 6277 | nouveau_bios_init(struct drm_device *dev) |
| 6210 | 6278 | { |
| @@ -6239,11 +6307,9 @@ nouveau_bios_init(struct drm_device *dev) · 28 unmodified lines | ||
| 6239 | 6307 | bios->execute = false; |
| 6240 | 6308 | |
| 6241 | 6309 | /* ... unless card isn't POSTed already */ |
| 6242 | − if (dev_priv->card_type >= NV_10 && | |
| 6243 | − NVReadVgaCrtc(dev, 0, 0x00) == 0 && | |
| 6244 | − NVReadVgaCrtc(dev, 0, 0x1a) == 0) { | |
| 6310 | + if (!nouveau_bios_posted(dev)) { | |
| 6245 | 6311 | NV_INFO(dev, "Adaptor not initialised\n"); |
| 6246 | − if (dev_priv->card_type < NV_50) { | |
| 6312 | + if (dev_priv->card_type < NV_40) { | |
| 6247 | 6313 | NV_ERROR(dev, "Unable to POST this chipset\n"); |
| 6248 | 6314 | return -ENODEV; |
| 6249 | 6315 | } |
| @@ -432,24 +432,27 @@ nouveau_connector_set_property(struct drm_connector *connector, · 431 unmodified lines | ||
| 432 | 432 | } |
| 433 | 433 | |
| 434 | 434 | static struct drm_display_mode * |
| 435 | −nouveau_connector_native_mode(struct nouveau_connector *connector) | |
| 435 | +nouveau_connector_native_mode(struct drm_connector *connector) | |
| 436 | 436 | { |
| 437 | − struct drm_device *dev = connector->base.dev; | |
| 437 | + struct drm_connector_helper_funcs *helper = connector->helper_private; | |
| 438 | + struct nouveau_connector *nv_connector = nouveau_connector(connector); | |
| 439 | + struct drm_device *dev = connector->dev; | |
| 438 | 440 | struct drm_display_mode *mode, *largest = NULL; |
| 439 | 441 | int high_w = 0, high_h = 0, high_v = 0; |
| 440 | 442 | |
| 441 | − /* Use preferred mode if there is one.. */ | |
| 442 | − list_for_each_entry(mode, &connector->base.probed_modes, head) { | |
| 443 | + list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { | |
| 444 | + if (helper->mode_valid(connector, mode) != MODE_OK) | |
| 445 | + continue; | |
| 446 | + | |
| 447 | + /* Use preferred mode if there is one.. */ | |
| 443 | 448 | if (mode->type & DRM_MODE_TYPE_PREFERRED) { |
| 444 | 449 | NV_DEBUG_KMS(dev, "native mode from preferred\n"); |
| 445 | 450 | return drm_mode_duplicate(dev, mode); |
| 446 | 451 | } |
| 447 | − } | |
| 448 | 452 | |
| 449 | − /* Otherwise, take the resolution with the largest width, then height, | |
| 450 | − * then vertical refresh | |
| 451 | − */ | |
| 452 | − list_for_each_entry(mode, &connector->base.probed_modes, head) { | |
| 453 | + /* Otherwise, take the resolution with the largest width, then | |
| 454 | + * height, then vertical refresh | |
| 455 | + */ | |
| 453 | 456 | if (mode->hdisplay < high_w) |
| 454 | 457 | continue; |
| 455 | 458 | |
| @@ -553,7 +556,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) · 97 unmodified lines | ||
| 553 | 556 | */ |
| 554 | 557 | if (!nv_connector->native_mode) |
| 555 | 558 | nv_connector->native_mode = |
| 556 | − nouveau_connector_native_mode(nv_connector); | |
| 559 | + nouveau_connector_native_mode(connector); | |
| 557 | 560 | if (ret == 0 && nv_connector->native_mode) { |
| 558 | 561 | struct drm_display_mode *mode; |
| 559 | 562 | |
| @@ -584,9 +587,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, · 24 unmodified lines | ||
| 584 | 587 | |
| 585 | 588 | switch (nv_encoder->dcb->type) { |
| 586 | 589 | case OUTPUT_LVDS: |
| 587 | − BUG_ON(!nv_connector->native_mode); | |
| 588 | − if (mode->hdisplay > nv_connector->native_mode->hdisplay || | |
| 589 | − mode->vdisplay > nv_connector->native_mode->vdisplay) | |
| 590 | + if (nv_connector->native_mode && | |
| 591 | + (mode->hdisplay > nv_connector->native_mode->hdisplay || | |
| 592 | + mode->vdisplay > nv_connector->native_mode->vdisplay)) | |
| 590 | 593 | return MODE_PANEL; |
| 591 | 594 | |
| 592 | 595 | min_clock = 0; |
| @@ -594,8 +597,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, · 1 unmodified line | ||
| 594 | 597 | break; |
| 595 | 598 | case OUTPUT_TMDS: |
| 596 | 599 | if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || |
| 597 | − (dev_priv->card_type < NV_50 && | |
| 598 | − !nv_encoder->dcb->duallink_possible)) | |
| 600 | + !nv_encoder->dcb->duallink_possible) | |
| 599 | 601 | max_clock = 165000; |
| 600 | 602 | else |
| 601 | 603 | max_clock = 330000; |
| @@ -729,7 +731,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, · 127 unmodified lines | ||
| 729 | 731 | if (ret == 0) |
| 730 | 732 | goto out; |
| 731 | 733 | nv_connector->detected_encoder = nv_encoder; |
| 732 | − nv_connector->native_mode = nouveau_connector_native_mode(nv_connector); | |
| 734 | + nv_connector->native_mode = nouveau_connector_native_mode(connector); | |
| 733 | 735 | list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) |
| 734 | 736 | drm_mode_remove(connector, mode); |
| 735 | 737 | |
| @@ -40,6 +40,8 @@ struct nouveau_crtc { · 39 unmodified lines | ||
| 40 | 40 | int sharpness; |
| 41 | 41 | int last_dpms; |
| 42 | 42 | |
| 43 | + int cursor_saved_x, cursor_saved_y; | |
| 44 | + | |
| 43 | 45 | struct { |
| 44 | 46 | int cpp; |
| 45 | 47 | bool blanked; |
| @@ -175,6 +175,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) · 174 unmodified lines | ||
| 175 | 175 | nouveau_bo_unpin(nouveau_fb->nvbo); |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 179 | + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | |
| 180 | + | |
| 181 | + nouveau_bo_unmap(nv_crtc->cursor.nvbo); | |
| 182 | + nouveau_bo_unpin(nv_crtc->cursor.nvbo); | |
| 183 | + } | |
| 184 | + | |
| 178 | 185 | NV_INFO(dev, "Evicting buffers...\n"); |
| 179 | 186 | ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); |
| 180 | 187 | |
| @@ -314,12 +321,34 @@ nouveau_pci_resume(struct pci_dev *pdev) · 133 unmodified lines | ||
| 314 | 321 | nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); |
| 315 | 322 | } |
| 316 | 323 | |
| 324 | + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 325 | + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | |
| 326 | + int ret; | |
| 327 | + | |
| 328 | + ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); | |
| 329 | + if (!ret) | |
| 330 | + ret = nouveau_bo_map(nv_crtc->cursor.nvbo); | |
| 331 | + if (ret) | |
| 332 | + NV_ERROR(dev, "Could not pin/map cursor.\n"); | |
| 333 | + } | |
| 334 | + | |
| 317 | 335 | if (dev_priv->card_type < NV_50) { |
| 318 | 336 | nv04_display_restore(dev); |
| 319 | 337 | NVLockVgaCrtcs(dev, false); |
| 320 | 338 | } else |
| 321 | 339 | nv50_display_init(dev); |
| 322 | 340 | |
| 341 | + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 342 | + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | |
| 343 | + | |
| 344 | + nv_crtc->cursor.set_offset(nv_crtc, | |
| 345 | + nv_crtc->cursor.nvbo->bo.offset - | |
| 346 | + dev_priv->vm_vram_base); | |
| 347 | + | |
| 348 | + nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, | |
| 349 | + nv_crtc->cursor_saved_y); | |
| 350 | + } | |
| 351 | + | |
| 323 | 352 | /* Force CLUT to get re-loaded during modeset */ |
| 324 | 353 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
| 325 | 354 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
| @@ -851,12 +851,17 @@ extern int nouveau_dma_init(struct nouveau_channel *); · 850 unmodified lines | ||
| 851 | 851 | extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); |
| 852 | 852 | |
| 853 | 853 | /* nouveau_acpi.c */ |
| 854 | +#define ROM_BIOS_PAGE 4096 | |
| 854 | 855 | #if defined(CONFIG_ACPI) |
| 855 | 856 | void nouveau_register_dsm_handler(void); |
| 856 | 857 | void nouveau_unregister_dsm_handler(void); |
| 858 | +int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); | |
| 859 | +bool nouveau_acpi_rom_supported(struct pci_dev *pdev); | |
| 857 | 860 | #else |
| 858 | 861 | static inline void nouveau_register_dsm_handler(void) {} |
| 859 | 862 | static inline void nouveau_unregister_dsm_handler(void) {} |
| 863 | +static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } | |
| 864 | +static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } | |
| 860 | 865 | #endif |
| 861 | 866 | |
| 862 | 867 | /* nouveau_backlight.c */ |
| @@ -377,6 +377,7 @@ int nouveau_fbcon_init(struct drm_device *dev) · 376 unmodified lines | ||
| 377 | 377 | { |
| 378 | 378 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 379 | 379 | struct nouveau_fbdev *nfbdev; |
| 380 | + int ret; | |
| 380 | 381 | |
| 381 | 382 | nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); |
| 382 | 383 | if (!nfbdev) |
| @@ -386,7 +387,12 @@ int nouveau_fbcon_init(struct drm_device *dev) · 3 unmodified lines | ||
| 386 | 387 | dev_priv->nfbdev = nfbdev; |
| 387 | 388 | nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; |
| 388 | 389 | |
| 389 | − drm_fb_helper_init(dev, &nfbdev->helper, 2, 4); | |
| 390 | + ret = drm_fb_helper_init(dev, &nfbdev->helper, 2, 4); | |
| 391 | + if (ret) { | |
| 392 | + kfree(nfbdev); | |
| 393 | + return ret; | |
| 394 | + } | |
| 395 | + | |
| 390 | 396 | drm_fb_helper_single_add_all_connectors(&nfbdev->helper); |
| 391 | 397 | drm_fb_helper_initial_config(&nfbdev->helper, 32); |
| 392 | 398 | return 0; |
| @@ -540,7 +540,8 @@ nouveau_mem_detect(struct drm_device *dev) · 539 unmodified lines | ||
| 540 | 540 | dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); |
| 541 | 541 | dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; |
| 542 | 542 | if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) |
| 543 | − dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; | |
| 543 | + dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); | |
| 544 | + dev_priv->vram_sys_base <<= 12; | |
| 544 | 545 | } |
| 545 | 546 | |
| 546 | 547 | NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); |
| @@ -376,12 +376,15 @@ out_err: · 375 unmodified lines | ||
| 376 | 376 | static void nouveau_switcheroo_set_state(struct pci_dev *pdev, |
| 377 | 377 | enum vga_switcheroo_state state) |
| 378 | 378 | { |
| 379 | + struct drm_device *dev = pci_get_drvdata(pdev); | |
| 379 | 380 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
| 380 | 381 | if (state == VGA_SWITCHEROO_ON) { |
| 381 | 382 | printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); |
| 382 | 383 | nouveau_pci_resume(pdev); |
| 384 | + drm_kms_helper_poll_enable(dev); | |
| 383 | 385 | } else { |
| 384 | 386 | printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); |
| 387 | + drm_kms_helper_poll_disable(dev); | |
| 385 | 388 | nouveau_pci_suspend(pdev, pmm); |
| 386 | 389 | } |
| 387 | 390 | } |
| @@ -776,29 +779,24 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) · 388 unmodified lines | ||
| 776 | 779 | return ret; |
| 777 | 780 | } |
| 778 | 781 | |
| 779 | − /* map larger RAMIN aperture on NV40 cards */ | |
| 780 | − dev_priv->ramin = NULL; | |
| 782 | + /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ | |
| 781 | 783 | if (dev_priv->card_type >= NV_40) { |
| 782 | 784 | int ramin_bar = 2; |
| 783 | 785 | if (pci_resource_len(dev->pdev, ramin_bar) == 0) |
| 784 | 786 | ramin_bar = 3; |
| 785 | 787 | |
| 786 | 788 | dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar); |
| 787 | − dev_priv->ramin = ioremap( | |
| 788 | − pci_resource_start(dev->pdev, ramin_bar), | |
| 789 | + dev_priv->ramin = | |
| 790 | + ioremap(pci_resource_start(dev->pdev, ramin_bar), | |
| 789 | 791 | dev_priv->ramin_size); |
| 790 | 792 | if (!dev_priv->ramin) { |
| 791 | − NV_ERROR(dev, "Failed to init RAMIN mapping, " | |
| 792 | − "limited instance memory available\n"); | |
| 793 | + NV_ERROR(dev, "Failed to PRAMIN BAR"); | |
| 794 | + return -ENOMEM; | |
| 793 | 795 | } |
| 794 | − } | |
| 795 | − | |
| 796 | − /* On older cards (or if the above failed), create a map covering | |
| 797 | − * the BAR0 PRAMIN aperture */ | |
| 798 | − if (!dev_priv->ramin) { | |
| 796 | + } else { | |
| 799 | 797 | dev_priv->ramin_size = 1 * 1024 * 1024; |
| 800 | 798 | dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN, |
| 801 | − dev_priv->ramin_size); | |
| 799 | + dev_priv->ramin_size); | |
| 802 | 800 | if (!dev_priv->ramin) { |
| 803 | 801 | NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); |
| 804 | 802 | return -ENOMEM; |
| @@ -913,6 +911,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, · 108 unmodified lines | ||
| 913 | 911 | case NOUVEAU_GETPARAM_VM_VRAM_BASE: |
| 914 | 912 | getparam->value = dev_priv->vm_vram_base; |
| 915 | 913 | break; |
| 914 | + case NOUVEAU_GETPARAM_PTIMER_TIME: | |
| 915 | + getparam->value = dev_priv->engine.timer.read(dev); | |
| 916 | + break; | |
| 916 | 917 | case NOUVEAU_GETPARAM_GRAPH_UNITS: |
| 917 | 918 | /* NV40 and NV50 versions are quite different, but register |
| 918 | 919 | * address is the same. User is supposed to know the card |
| @@ -20,6 +20,7 @@ nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) · 19 unmodified lines | ||
| 20 | 20 | static void |
| 21 | 21 | nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) |
| 22 | 22 | { |
| 23 | + nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y; | |
| 23 | 24 | NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index, |
| 24 | 25 | NV_PRAMDAC_CU_START_POS, |
| 25 | 26 | XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) | |
| @@ -107,6 +107,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) · 106 unmodified lines | ||
| 107 | 107 | { |
| 108 | 108 | struct drm_device *dev = nv_crtc->base.dev; |
| 109 | 109 | |
| 110 | + nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y; | |
| 110 | 111 | nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index), |
| 111 | 112 | ((y & 0xFFFF) << 16) | (x & 0xFFFF)); |
| 112 | 113 | /* Needed to make the cursor move. */ |
| @@ -6,10 +6,16 @@ · 5 unmodified lines | ||
| 6 | 6 | int |
| 7 | 7 | nv50_fb_init(struct drm_device *dev) |
| 8 | 8 | { |
| 9 | − /* This is needed to get meaningful information from 100c90 | |
| 10 | − * on traps. No idea what these values mean exactly. */ | |
| 11 | 9 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 12 | 10 | |
| 11 | + /* Not a clue what this is exactly. Without pointing it at a | |
| 12 | + * scratch page, VRAM->GART blits with M2MF (as in DDX DFS) | |
| 13 | + * cause IOMMU "read from address 0" errors (rh#561267) | |
| 14 | + */ | |
| 15 | + nv_wr32(dev, 0x100c08, dev_priv->gart_info.sg_dummy_bus >> 8); | |
| 16 | + | |
| 17 | + /* This is needed to get meaningful information from 100c90 | |
| 18 | + * on traps. No idea what these values mean exactly. */ | |
| 13 | 19 | switch (dev_priv->chipset) { |
| 14 | 20 | case 0x50: |
| 15 | 21 | nv_wr32(dev, 0x100c90, 0x0707ff); |
| @@ -31,7 +31,7 @@ nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift) · 30 unmodified lines | ||
| 31 | 31 | { |
| 32 | 32 | const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; |
| 33 | 33 | |
| 34 | − if (gpio->line > 32) | |
| 34 | + if (gpio->line >= 32) | |
| 35 | 35 | return -EINVAL; |
| 36 | 36 | |
| 37 | 37 | *reg = nv50_gpio_reg[gpio->line >> 3]; |
| @@ -274,7 +274,6 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { · 273 unmodified lines | ||
| 274 | 274 | int |
| 275 | 275 | nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) |
| 276 | 276 | { |
| 277 | − struct drm_nouveau_private *dev_priv = dev->dev_private; | |
| 278 | 277 | struct nouveau_encoder *nv_encoder = NULL; |
| 279 | 278 | struct drm_encoder *encoder; |
| 280 | 279 | bool dum; |
| @@ -324,11 +323,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) · 43 unmodified lines | ||
| 324 | 323 | int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1); |
| 325 | 324 | uint32_t tmp; |
| 326 | 325 | |
| 327 | − if (dev_priv->chipset < 0x90 || | |
| 328 | − dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) | |
| 329 | − tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or)); | |
| 330 | − else | |
| 331 | − tmp = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or)); | |
| 326 | + tmp = nv_rd32(dev, 0x61c700 + (or * 0x800)); | |
| 332 | 327 | |
| 333 | 328 | switch ((tmp & 0x00000f00) >> 8) { |
| 334 | 329 | case 8: |
| @@ -33,6 +33,9 @@ $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable · 32 unmodified lines | ||
| 33 | 33 | $(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable |
| 34 | 34 | $(call if_changed,mkregtable) |
| 35 | 35 | |
| 36 | +$(obj)/evergreen_reg_safe.h: $(src)/reg_srcs/evergreen $(obj)/mkregtable | |
| 37 | + $(call if_changed,mkregtable) | |
| 38 | + | |
| 36 | 39 | $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h |
| 37 | 40 | |
| 38 | 41 | $(obj)/r200.o: $(obj)/r200_reg_safe.h |
| @@ -47,6 +50,8 @@ $(obj)/rs600.o: $(obj)/rs600_reg_safe.h · 8 unmodified lines | ||
| 47 | 50 | |
| 48 | 51 | $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h |
| 49 | 52 | |
| 53 | +$(obj)/evergreen_cs.o: $(obj)/evergreen_reg_safe.h | |
| 54 | + | |
| 50 | 55 | radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ |
| 51 | 56 | radeon_irq.o r300_cmdbuf.o r600_cp.o |
| 52 | 57 | # add KMS driver |
| @@ -60,7 +65,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ · 7 unmodified lines | ||
| 60 | 65 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
| 61 | 66 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
| 62 | 67 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ |
| 63 | − evergreen.o | |
| 68 | + evergreen.o evergreen_cs.o | |
| 64 | 69 | |
| 65 | 70 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
| 66 | 71 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
| @@ -41,7 +41,18 @@ void evergreen_fini(struct radeon_device *rdev); · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | void evergreen_pm_misc(struct radeon_device *rdev) |
| 43 | 43 | { |
| 44 | − | |
| 44 | + int req_ps_idx = rdev->pm.requested_power_state_index; | |
| 45 | + int req_cm_idx = rdev->pm.requested_clock_mode_index; | |
| 46 | + struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; | |
| 47 | + struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | |
| 48 | + | |
| 49 | + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | |
| 50 | + if (voltage->voltage != rdev->pm.current_vddc) { | |
| 51 | + radeon_atom_set_voltage(rdev, voltage->voltage); | |
| 52 | + rdev->pm.current_vddc = voltage->voltage; | |
| 53 | + DRM_DEBUG("Setting: v: %d\n", voltage->voltage); | |
| 54 | + } | |
| 55 | + } | |
| 45 | 56 | } |
| 46 | 57 | |
| 47 | 58 | void evergreen_pm_prepare(struct radeon_device *rdev) |
| @@ -2148,7 +2159,7 @@ int evergreen_init(struct radeon_device *rdev) · 2100 unmodified lines | ||
| 2148 | 2159 | if (r) |
| 2149 | 2160 | return r; |
| 2150 | 2161 | |
| 2151 | − rdev->accel_working = false; | |
| 2162 | + rdev->accel_working = true; | |
| 2152 | 2163 | r = evergreen_startup(rdev); |
| 2153 | 2164 | if (r) { |
| 2154 | 2165 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
| @@ -0,0 +1,1356 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2010 Advanced Micro Devices, Inc. | |
| 3 | + * Copyright 2008 Red Hat Inc. | |
| 4 | + * Copyright 2009 Jerome Glisse. | |
| 5 | + * | |
| 6 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 | + * copy of this software and associated documentation files (the "Software"), | |
| 8 | + * to deal in the Software without restriction, including without limitation | |
| 9 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 10 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 11 | + * Software is furnished to do so, subject to the following conditions: | |
| 12 | + * | |
| 13 | + * The above copyright notice and this permission notice shall be included in | |
| 14 | + * all copies or substantial portions of the Software. | |
| 15 | + * | |
| 16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 19 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 20 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 21 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 22 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 23 | + * | |
| 24 | + * Authors: Dave Airlie | |
| 25 | + * Alex Deucher | |
| 26 | + * Jerome Glisse | |
| 27 | + */ | |
| 28 | +#include "drmP.h" | |
| 29 | +#include "radeon.h" | |
| 30 | +#include "evergreend.h" | |
| 31 | +#include "evergreen_reg_safe.h" | |
| 32 | + | |
| 33 | +static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, | |
| 34 | + struct radeon_cs_reloc **cs_reloc); | |
| 35 | + | |
| 36 | +struct evergreen_cs_track { | |
| 37 | + u32 group_size; | |
| 38 | + u32 nbanks; | |
| 39 | + u32 npipes; | |
| 40 | + /* value we track */ | |
| 41 | + u32 nsamples; | |
| 42 | + u32 cb_color_base_last[12]; | |
| 43 | + struct radeon_bo *cb_color_bo[12]; | |
| 44 | + u32 cb_color_bo_offset[12]; | |
| 45 | + struct radeon_bo *cb_color_fmask_bo[8]; | |
| 46 | + struct radeon_bo *cb_color_cmask_bo[8]; | |
| 47 | + u32 cb_color_info[12]; | |
| 48 | + u32 cb_color_view[12]; | |
| 49 | + u32 cb_color_pitch_idx[12]; | |
| 50 | + u32 cb_color_slice_idx[12]; | |
| 51 | + u32 cb_color_dim_idx[12]; | |
| 52 | + u32 cb_color_dim[12]; | |
| 53 | + u32 cb_color_pitch[12]; | |
| 54 | + u32 cb_color_slice[12]; | |
| 55 | + u32 cb_color_cmask_slice[8]; | |
| 56 | + u32 cb_color_fmask_slice[8]; | |
| 57 | + u32 cb_target_mask; | |
| 58 | + u32 cb_shader_mask; | |
| 59 | + u32 vgt_strmout_config; | |
| 60 | + u32 vgt_strmout_buffer_config; | |
| 61 | + u32 db_depth_control; | |
1295 more lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 476 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 209 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 275 lines aren’t shown here.
This diff is large: its 612 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 315 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 924 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 971 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 419 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 291 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 365 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 275 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 374 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 865 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 570 lines aren’t shown here.
This diff is large: its 251 lines aren’t shown here.
This diff is large: its 1123 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 447 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 291 lines aren’t shown here.
This diff is large: its 238 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 375 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 376 lines aren’t shown here.
This diff is large: its 321 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 893 lines aren’t shown here.
This diff is large: its 1742 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 378 lines aren’t shown here.
This diff is large: its 226 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 2240 lines aren’t shown here.
This diff is large: its 548 lines aren’t shown here.
This diff is large: its 1114 lines aren’t shown here.
This diff is large: its 696 lines aren’t shown here.
This diff is large: its 353 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 1260 lines aren’t shown here.
This diff is large: its 314 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 1687 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 562 lines aren’t shown here.
This diff is large: its 380 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 721 lines aren’t shown here.
This diff is large: its 1503 lines aren’t shown here.
This diff is large: its 348 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 2487 lines aren’t shown here.
This diff is large: its 829 lines aren’t shown here.
This diff is large: its 390 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 2355 lines aren’t shown here.
This diff is large: its 175 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 202 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 246 lines aren’t shown here.
This diff is large: its 324 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 296 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 597 lines aren’t shown here.
This diff is large: its 512 lines aren’t shown here.
This diff is large: its 1024 lines aren’t shown here.
This diff is large: its 3774 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 1018 lines aren’t shown here.
This diff is large: its 1371 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 3445 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10737 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 535 lines aren’t shown here.
This diff is large: its 4407 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 326 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 395 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 547 lines aren’t shown here.
This diff is large: its 455 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 658 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 1569 lines aren’t shown here.
This diff is large: its 618 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 352 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 312 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 442 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.