diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-24 15:50:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-24 15:50:56 -0500 |
commit | e2464688b59c6ae9928f385dabf5355e30cff298 (patch) | |
tree | 1039fa8c818e6ac16d6f1504c28e80bfe902b0f3 | |
parent | e1c10879ed59436cde537b723545430b04d4dec0 (diff) | |
parent | 07d17f09691e549fac0101333eebe0161a472b50 (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is the main pull request for MIPS for 4.5 plus some 4.4 fixes.
The executive summary:
- ATH79 platform improvments, use DT bindings for the ATH79 USB PHY.
- Avoid useless rebuilds for zboot.
- jz4780: Add NEMC, BCH and NAND device tree nodes
- Initial support for the MicroChip's DT platform. As all the device
drivers are missing this is still of limited use.
- Some Loongson3 cleanups.
- The unavoidable whitespace polishing.
- Reduce clock skew when synchronizing the CPU cycle counters on CPU
startup.
- Add MIPS R6 fixes.
- Lots of cleanups across arch/mips as fallout from KVM.
- Lots of minor fixes and changes for IEEE 754-2008 support to the
FPU emulator / fp-assist software.
- Minor Ralink, BCM47xx and bcm963xx platform support improvments.
- Support SMP on BCM63168"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (84 commits)
MIPS: zboot: Add support for serial debug using the PROM
MIPS: zboot: Avoid useless rebuilds
MIPS: BMIPS: Enable ARCH_WANT_OPTIONAL_GPIOLIB
MIPS: bcm63xx: nvram: Remove unused bcm63xx_nvram_get_psi_size() function
MIPS: bcm963xx: Update bcm_tag field image_sequence
MIPS: bcm963xx: Move extended flash address to bcm_tag header file
MIPS: bcm963xx: Move Broadcom BCM963xx image tag data structure
MIPS: bcm63xx: nvram: Use nvram structure definition from header file
MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
MAINTAINERS: Add KVM for MIPS entry
MIPS: KVM: Add missing newline to kvm_err()
MIPS: Move KVM specific opcodes into asm/inst.h
MIPS: KVM: Use cacheops.h definitions
MIPS: Break down cacheops.h definitions
MIPS: Use EXCCODE_ constants with set_except_vector()
MIPS: Update trap codes
MIPS: Move Cause.ExcCode trap codes to mipsregs.h
MIPS: KVM: Make kvm_mips_{init,exit}() static
MIPS: KVM: Refactor added offsetof()s
MIPS: KVM: Convert EXPORT_SYMBOL to _GPL
...
130 files changed, 4923 insertions, 676 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt b/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt new file mode 100644 index 000000000000..c3a1b37c4c35 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt | |||
@@ -0,0 +1,67 @@ | |||
1 | Microchip PIC32 Interrupt Controller | ||
2 | ==================================== | ||
3 | |||
4 | The Microchip PIC32 contains an Enhanced Vectored Interrupt Controller (EVIC). | ||
5 | It handles all internal and external interrupts. This controller exists outside | ||
6 | of the CPU and is the arbitrator of all interrupts (including interrupts from | ||
7 | the CPU itself) before they are presented to the CPU. | ||
8 | |||
9 | External interrupts have a software configurable edge polarity. Non external | ||
10 | interrupts have a type and polarity that is determined by the source of the | ||
11 | interrupt. | ||
12 | |||
13 | Required properties | ||
14 | ------------------- | ||
15 | |||
16 | - compatible: Should be "microchip,pic32mzda-evic" | ||
17 | - reg: Specifies physical base address and size of register range. | ||
18 | - interrupt-controller: Identifies the node as an interrupt controller. | ||
19 | - #interrupt cells: Specifies the number of cells used to encode an interrupt | ||
20 | source connected to this controller. The value shall be 2 and interrupt | ||
21 | descriptor shall have the following format: | ||
22 | |||
23 | <hw_irq irq_type> | ||
24 | |||
25 | hw_irq - represents the hardware interrupt number as in the data sheet. | ||
26 | irq_type - is used to describe the type and polarity of an interrupt. For | ||
27 | internal interrupts use IRQ_TYPE_EDGE_RISING for non persistent interrupts and | ||
28 | IRQ_TYPE_LEVEL_HIGH for persistent interrupts. For external interrupts use | ||
29 | IRQ_TYPE_EDGE_RISING or IRQ_TYPE_EDGE_FALLING to select the desired polarity. | ||
30 | |||
31 | Optional properties | ||
32 | ------------------- | ||
33 | - microchip,external-irqs: u32 array of external interrupts with software | ||
34 | polarity configuration. This array corresponds to the bits in the INTCON | ||
35 | SFR. | ||
36 | |||
37 | Example | ||
38 | ------- | ||
39 | |||
40 | evic: interrupt-controller@1f810000 { | ||
41 | compatible = "microchip,pic32mzda-evic"; | ||
42 | interrupt-controller; | ||
43 | #interrupt-cells = <2>; | ||
44 | reg = <0x1f810000 0x1000>; | ||
45 | microchip,external-irqs = <3 8 13 18 23>; | ||
46 | }; | ||
47 | |||
48 | Each device/peripheral must request its interrupt line with the associated type | ||
49 | and polarity. | ||
50 | |||
51 | Internal interrupt DTS snippet | ||
52 | ------------------------------ | ||
53 | |||
54 | device@1f800000 { | ||
55 | ... | ||
56 | interrupts = <113 IRQ_TYPE_LEVEL_HIGH>; | ||
57 | ... | ||
58 | }; | ||
59 | |||
60 | External interrupt DTS snippet | ||
61 | ------------------------------ | ||
62 | |||
63 | device@1f800000 { | ||
64 | ... | ||
65 | interrupts = <3 IRQ_TYPE_EDGE_RISING>; | ||
66 | ... | ||
67 | }; | ||
diff --git a/Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt b/Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt new file mode 100644 index 000000000000..1c8dbc45feec --- /dev/null +++ b/Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt | |||
@@ -0,0 +1,31 @@ | |||
1 | * Microchip PIC32MZDA Platforms | ||
2 | |||
3 | PIC32MZDA Starter Kit | ||
4 | Required root node properties: | ||
5 | - compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda" | ||
6 | |||
7 | CPU nodes: | ||
8 | ---------- | ||
9 | A "cpus" node is required. Required properties: | ||
10 | - #address-cells: Must be 1. | ||
11 | - #size-cells: Must be 0. | ||
12 | A CPU sub-node is also required. Required properties: | ||
13 | - device_type: Must be "cpu". | ||
14 | - compatible: Must be "mti,mips14KEc". | ||
15 | Example: | ||
16 | cpus { | ||
17 | #address-cells = <1>; | ||
18 | #size-cells = <0>; | ||
19 | |||
20 | cpu0: cpu@0 { | ||
21 | device_type = "cpu"; | ||
22 | compatible = "mti,mips14KEc"; | ||
23 | }; | ||
24 | }; | ||
25 | |||
26 | Boot protocol | ||
27 | -------------- | ||
28 | In accordance with Unified Hosting Interface Reference Manual (MD01069), the | ||
29 | bootloader must pass the following arguments to the kernel: | ||
30 | - $a0: -2. | ||
31 | - $a1: KSEG0 address of the flattened device-tree blob. | ||
diff --git a/Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt b/Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt new file mode 100644 index 000000000000..aa6313024176 --- /dev/null +++ b/Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | Mediatek Gigabit Switch | ||
2 | ======================= | ||
3 | |||
4 | The mediatek gigabit switch can be found on Mediatek SoCs (mt7620, mt7621). | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: Should be "mediatek,mt7620-gsw" or "mediatek,mt7621-gsw" | ||
8 | - reg: Address and length of the register set for the device | ||
9 | - interrupt-parent: Should be the phandle for the interrupt controller | ||
10 | that services interrupts for this device | ||
11 | - interrupts: Should contain the gigabit switches interrupt | ||
12 | - resets: Should contain the gigabit switches resets | ||
13 | - reset-names: Should contain the reset names "gsw" | ||
14 | |||
15 | Example: | ||
16 | |||
17 | gsw@10110000 { | ||
18 | compatible = "ralink,mt7620-gsw"; | ||
19 | reg = <0x10110000 8000>; | ||
20 | |||
21 | resets = <&rstctrl 23>; | ||
22 | reset-names = "gsw"; | ||
23 | |||
24 | interrupt-parent = <&intc>; | ||
25 | interrupts = <17>; | ||
26 | }; | ||
diff --git a/Documentation/devicetree/bindings/net/ralink,rt2880-net.txt b/Documentation/devicetree/bindings/net/ralink,rt2880-net.txt new file mode 100644 index 000000000000..88b095d1f13b --- /dev/null +++ b/Documentation/devicetree/bindings/net/ralink,rt2880-net.txt | |||
@@ -0,0 +1,61 @@ | |||
1 | Ralink Frame Engine Ethernet controller | ||
2 | ======================================= | ||
3 | |||
4 | The Ralink frame engine ethernet controller can be found on Ralink and | ||
5 | Mediatek SoCs (RT288x, RT3x5x, RT366x, RT388x, rt5350, mt7620, mt7621, mt76x8). | ||
6 | |||
7 | Depending on the SoC, there is a number of ports connected to the CPU port | ||
8 | directly and/or via a (gigabit-)switch. | ||
9 | |||
10 | * Ethernet controller node | ||
11 | |||
12 | Required properties: | ||
13 | - compatible: Should be one of "ralink,rt2880-eth", "ralink,rt3050-eth", | ||
14 | "ralink,rt3050-eth", "ralink,rt3883-eth", "ralink,rt5350-eth", | ||
15 | "mediatek,mt7620-eth", "mediatek,mt7621-eth" | ||
16 | - reg: Address and length of the register set for the device | ||
17 | - interrupt-parent: Should be the phandle for the interrupt controller | ||
18 | that services interrupts for this device | ||
19 | - interrupts: Should contain the frame engines interrupt | ||
20 | - resets: Should contain the frame engines resets | ||
21 | - reset-names: Should contain the reset names "fe". If a switch is present | ||
22 | "esw" is also required. | ||
23 | |||
24 | |||
25 | * Ethernet port node | ||
26 | |||
27 | Required properties: | ||
28 | - compatible: Should be "ralink,eth-port" | ||
29 | - reg: The number of the physical port | ||
30 | - phy-handle: reference to the node describing the phy | ||
31 | |||
32 | Example: | ||
33 | |||
34 | mdio-bus { | ||
35 | ... | ||
36 | phy0: ethernet-phy@0 { | ||
37 | phy-mode = "mii"; | ||
38 | reg = <0>; | ||
39 | }; | ||
40 | }; | ||
41 | |||
42 | ethernet@400000 { | ||
43 | compatible = "ralink,rt2880-eth"; | ||
44 | reg = <0x00400000 10000>; | ||
45 | |||
46 | #address-cells = <1>; | ||
47 | #size-cells = <0>; | ||
48 | |||
49 | resets = <&rstctrl 18>; | ||
50 | reset-names = "fe"; | ||
51 | |||
52 | interrupt-parent = <&cpuintc>; | ||
53 | interrupts = <5>; | ||
54 | |||
55 | port@0 { | ||
56 | compatible = "ralink,eth-port"; | ||
57 | reg = <0>; | ||
58 | phy-handle = <&phy0>; | ||
59 | }; | ||
60 | |||
61 | }; | ||
diff --git a/Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt b/Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt new file mode 100644 index 000000000000..2e79bd376c56 --- /dev/null +++ b/Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt | |||
@@ -0,0 +1,32 @@ | |||
1 | Ralink Fast Ethernet Embedded Switch | ||
2 | ==================================== | ||
3 | |||
4 | The ralink fast ethernet embedded switch can be found on Ralink and Mediatek | ||
5 | SoCs (RT3x5x, RT5350, MT76x8). | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: Should be "ralink,rt3050-esw" | ||
9 | - reg: Address and length of the register set for the device | ||
10 | - interrupt-parent: Should be the phandle for the interrupt controller | ||
11 | that services interrupts for this device | ||
12 | - interrupts: Should contain the embedded switches interrupt | ||
13 | - resets: Should contain the embedded switches resets | ||
14 | - reset-names: Should contain the reset names "esw" | ||
15 | |||
16 | Optional properties: | ||
17 | - ralink,portmap: can be used to choose if the default switch setup is | ||
18 | llllw or wllll | ||
19 | - ralink,led_polarity: override the active high/low settings of the leds | ||
20 | |||
21 | Example: | ||
22 | |||
23 | esw@10110000 { | ||
24 | compatible = "ralink,rt3050-esw"; | ||
25 | reg = <0x10110000 8000>; | ||
26 | |||
27 | resets = <&rstctrl 23>; | ||
28 | reset-names = "esw"; | ||
29 | |||
30 | interrupt-parent = <&intc>; | ||
31 | interrupts = <17>; | ||
32 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt b/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt new file mode 100644 index 000000000000..cafe2197dad9 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-ath79-usb.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * Atheros AR71XX/9XXX USB PHY | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "qca,ar7100-usb-phy" | ||
5 | - #phys-cells: should be 0 | ||
6 | - reset-names: "usb-phy"[, "usb-suspend-override"] | ||
7 | - resets: references to the reset controllers | ||
8 | |||
9 | Example: | ||
10 | |||
11 | usb-phy { | ||
12 | compatible = "qca,ar7100-usb-phy"; | ||
13 | |||
14 | reset-names = "usb-phy", "usb-suspend-override"; | ||
15 | resets = <&rst 4>, <&rst 3>; | ||
16 | |||
17 | #phy-cells = <0>; | ||
18 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cfb2c0f1a4a8..87d40a72f6a1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1454,6 +1454,41 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1454 | In such case C2/C3 won't be used again. | 1454 | In such case C2/C3 won't be used again. |
1455 | idle=nomwait: Disable mwait for CPU C-states | 1455 | idle=nomwait: Disable mwait for CPU C-states |
1456 | 1456 | ||
1457 | ieee754= [MIPS] Select IEEE Std 754 conformance mode | ||
1458 | Format: { strict | legacy | 2008 | relaxed } | ||
1459 | Default: strict | ||
1460 | |||
1461 | Choose which programs will be accepted for execution | ||
1462 | based on the IEEE 754 NaN encoding(s) supported by | ||
1463 | the FPU and the NaN encoding requested with the value | ||
1464 | of an ELF file header flag individually set by each | ||
1465 | binary. Hardware implementations are permitted to | ||
1466 | support either or both of the legacy and the 2008 NaN | ||
1467 | encoding mode. | ||
1468 | |||
1469 | Available settings are as follows: | ||
1470 | strict accept binaries that request a NaN encoding | ||
1471 | supported by the FPU | ||
1472 | legacy only accept legacy-NaN binaries, if supported | ||
1473 | by the FPU | ||
1474 | 2008 only accept 2008-NaN binaries, if supported | ||
1475 | by the FPU | ||
1476 | relaxed accept any binaries regardless of whether | ||
1477 | supported by the FPU | ||
1478 | |||
1479 | The FPU emulator is always able to support both NaN | ||
1480 | encodings, so if no FPU hardware is present or it has | ||
1481 | been disabled with 'nofpu', then the settings of | ||
1482 | 'legacy' and '2008' strap the emulator accordingly, | ||
1483 | 'relaxed' straps the emulator for both legacy-NaN and | ||
1484 | 2008-NaN, whereas 'strict' enables legacy-NaN only on | ||
1485 | legacy processors and both NaN encodings on MIPS32 or | ||
1486 | MIPS64 CPUs. | ||
1487 | |||
1488 | The setting for ABS.fmt/NEG.fmt instruction execution | ||
1489 | mode generally follows that for the NaN encoding, | ||
1490 | except where unsupported by hardware. | ||
1491 | |||
1457 | ignore_loglevel [KNL] | 1492 | ignore_loglevel [KNL] |
1458 | Ignore loglevel setting - this will print /all/ | 1493 | Ignore loglevel setting - this will print /all/ |
1459 | kernel messages to the console. Useful for debugging. | 1494 | kernel messages to the console. Useful for debugging. |
diff --git a/MAINTAINERS b/MAINTAINERS index 78f71f471bd6..30aca4aa5467 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2420,6 +2420,8 @@ F: arch/mips/kernel/*bmips* | |||
2420 | F: arch/mips/boot/dts/brcm/bcm*.dts* | 2420 | F: arch/mips/boot/dts/brcm/bcm*.dts* |
2421 | F: drivers/irqchip/irq-bcm7* | 2421 | F: drivers/irqchip/irq-bcm7* |
2422 | F: drivers/irqchip/irq-brcmstb* | 2422 | F: drivers/irqchip/irq-brcmstb* |
2423 | F: include/linux/bcm963xx_nvram.h | ||
2424 | F: include/linux/bcm963xx_tag.h | ||
2423 | 2425 | ||
2424 | BROADCOM TG3 GIGABIT ETHERNET DRIVER | 2426 | BROADCOM TG3 GIGABIT ETHERNET DRIVER |
2425 | M: Prashant Sreedharan <prashant@broadcom.com> | 2427 | M: Prashant Sreedharan <prashant@broadcom.com> |
@@ -6216,6 +6218,14 @@ F: arch/arm64/include/uapi/asm/kvm* | |||
6216 | F: arch/arm64/include/asm/kvm* | 6218 | F: arch/arm64/include/asm/kvm* |
6217 | F: arch/arm64/kvm/ | 6219 | F: arch/arm64/kvm/ |
6218 | 6220 | ||
6221 | KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips) | ||
6222 | M: James Hogan <james.hogan@imgtec.com> | ||
6223 | L: linux-mips@linux-mips.org | ||
6224 | S: Supported | ||
6225 | F: arch/mips/include/uapi/asm/kvm* | ||
6226 | F: arch/mips/include/asm/kvm* | ||
6227 | F: arch/mips/kvm/ | ||
6228 | |||
6219 | KEXEC | 6229 | KEXEC |
6220 | M: Eric Biederman <ebiederm@xmission.com> | 6230 | M: Eric Biederman <ebiederm@xmission.com> |
6221 | W: http://kernel.org/pub/linux/utils/kernel/kexec/ | 6231 | W: http://kernel.org/pub/linux/utils/kernel/kexec/ |
@@ -6313,6 +6323,12 @@ S: Maintained | |||
6313 | F: net/l3mdev | 6323 | F: net/l3mdev |
6314 | F: include/net/l3mdev.h | 6324 | F: include/net/l3mdev.h |
6315 | 6325 | ||
6326 | LANTIQ MIPS ARCHITECTURE | ||
6327 | M: John Crispin <blogic@openwrt.org> | ||
6328 | L: linux-mips@linux-mips.org | ||
6329 | S: Maintained | ||
6330 | F: arch/mips/lantiq | ||
6331 | |||
6316 | LAPB module | 6332 | LAPB module |
6317 | L: linux-x25@vger.kernel.org | 6333 | L: linux-x25@vger.kernel.org |
6318 | S: Orphan | 6334 | S: Orphan |
@@ -8997,6 +9013,12 @@ L: linux-fbdev@vger.kernel.org | |||
8997 | S: Maintained | 9013 | S: Maintained |
8998 | F: drivers/video/fbdev/aty/aty128fb.c | 9014 | F: drivers/video/fbdev/aty/aty128fb.c |
8999 | 9015 | ||
9016 | RALINK MIPS ARCHITECTURE | ||
9017 | M: John Crispin <blogic@openwrt.org> | ||
9018 | L: linux-mips@linux-mips.org | ||
9019 | S: Maintained | ||
9020 | F: arch/mips/ralink | ||
9021 | |||
9000 | RALINK RT2X00 WIRELESS LAN DRIVER | 9022 | RALINK RT2X00 WIRELESS LAN DRIVER |
9001 | P: rt2x00 project | 9023 | P: rt2x00 project |
9002 | M: Stanislaw Gruszka <sgruszka@redhat.com> | 9024 | M: Stanislaw Gruszka <sgruszka@redhat.com> |
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index a96c81d1d22e..c5cd63a4b6d5 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms | |||
@@ -21,6 +21,7 @@ platforms += mti-malta | |||
21 | platforms += mti-sead3 | 21 | platforms += mti-sead3 |
22 | platforms += netlogic | 22 | platforms += netlogic |
23 | platforms += paravirt | 23 | platforms += paravirt |
24 | platforms += pic32 | ||
24 | platforms += pistachio | 25 | platforms += pistachio |
25 | platforms += pmcs-msp71xx | 26 | platforms += pmcs-msp71xx |
26 | platforms += pnx833x | 27 | platforms += pnx833x |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index fbf3f6670b69..57a945e832f4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -169,6 +169,7 @@ config BMIPS_GENERIC | |||
169 | select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN | 169 | select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN |
170 | select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN | 170 | select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN |
171 | select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN | 171 | select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN |
172 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
172 | help | 173 | help |
173 | Build a generic DT-based kernel image that boots on select | 174 | Build a generic DT-based kernel image that boots on select |
174 | BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top | 175 | BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top |
@@ -480,6 +481,14 @@ config MIPS_MALTA | |||
480 | This enables support for the MIPS Technologies Malta evaluation | 481 | This enables support for the MIPS Technologies Malta evaluation |
481 | board. | 482 | board. |
482 | 483 | ||
484 | config MACH_PIC32 | ||
485 | bool "Microchip PIC32 Family" | ||
486 | help | ||
487 | This enables support for the Microchip PIC32 family of platforms. | ||
488 | |||
489 | Microchip PIC32 is a family of general-purpose 32 bit MIPS core | ||
490 | microcontrollers. | ||
491 | |||
483 | config MIPS_SEAD3 | 492 | config MIPS_SEAD3 |
484 | bool "MIPS SEAD3 board" | 493 | bool "MIPS SEAD3 board" |
485 | select BOOT_ELF32 | 494 | select BOOT_ELF32 |
@@ -979,6 +988,7 @@ source "arch/mips/jazz/Kconfig" | |||
979 | source "arch/mips/jz4740/Kconfig" | 988 | source "arch/mips/jz4740/Kconfig" |
980 | source "arch/mips/lantiq/Kconfig" | 989 | source "arch/mips/lantiq/Kconfig" |
981 | source "arch/mips/lasat/Kconfig" | 990 | source "arch/mips/lasat/Kconfig" |
991 | source "arch/mips/pic32/Kconfig" | ||
982 | source "arch/mips/pistachio/Kconfig" | 992 | source "arch/mips/pistachio/Kconfig" |
983 | source "arch/mips/pmcs-msp71xx/Kconfig" | 993 | source "arch/mips/pmcs-msp71xx/Kconfig" |
984 | source "arch/mips/ralink/Kconfig" | 994 | source "arch/mips/ralink/Kconfig" |
@@ -1755,6 +1765,10 @@ config SYS_SUPPORTS_ZBOOT_UART16550 | |||
1755 | bool | 1765 | bool |
1756 | select SYS_SUPPORTS_ZBOOT | 1766 | select SYS_SUPPORTS_ZBOOT |
1757 | 1767 | ||
1768 | config SYS_SUPPORTS_ZBOOT_UART_PROM | ||
1769 | bool | ||
1770 | select SYS_SUPPORTS_ZBOOT | ||
1771 | |||
1758 | config CPU_LOONGSON2 | 1772 | config CPU_LOONGSON2 |
1759 | bool | 1773 | bool |
1760 | select CPU_SUPPORTS_32BIT_KERNEL | 1774 | select CPU_SUPPORTS_32BIT_KERNEL |
@@ -2017,7 +2031,8 @@ config KVM_GUEST | |||
2017 | bool "KVM Guest Kernel" | 2031 | bool "KVM Guest Kernel" |
2018 | depends on BROKEN_ON_SMP | 2032 | depends on BROKEN_ON_SMP |
2019 | help | 2033 | help |
2020 | Select this option if building a guest kernel for KVM (Trap & Emulate) mode | 2034 | Select this option if building a guest kernel for KVM (Trap & Emulate) |
2035 | mode. | ||
2021 | 2036 | ||
2022 | config KVM_GUEST_TIMER_FREQ | 2037 | config KVM_GUEST_TIMER_FREQ |
2023 | int "Count/Compare Timer Frequency (MHz)" | 2038 | int "Count/Compare Timer Frequency (MHz)" |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 3f70ba54ae21..e78d60dbdffd 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -166,16 +166,6 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon | |||
166 | endif | 166 | endif |
167 | cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 | 167 | cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 |
168 | cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap | 168 | cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap |
169 | # | ||
170 | # binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a | ||
171 | # as MIPS64 R1; older versions as just R1. This leaves the possibility open | ||
172 | # that GCC might generate R2 code for -march=loongson3a which then is rejected | ||
173 | # by GAS. The cc-option can't probe for this behaviour so -march=loongson3a | ||
174 | # can't easily be used safely within the kbuild framework. | ||
175 | # | ||
176 | cflags-$(CONFIG_CPU_LOONGSON3) += \ | ||
177 | $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ | ||
178 | -Wa,-mips64r2 -Wa,--trap | ||
179 | 169 | ||
180 | cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) | 170 | cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) |
181 | cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) | 171 | cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) |
diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c index f9bc4f520440..84548f704035 100644 --- a/arch/mips/alchemy/common/gpiolib.c +++ b/arch/mips/alchemy/common/gpiolib.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | static int gpio2_get(struct gpio_chip *chip, unsigned offset) | 41 | static int gpio2_get(struct gpio_chip *chip, unsigned offset) |
42 | { | 42 | { |
43 | return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); | 43 | return !!alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); |
44 | } | 44 | } |
45 | 45 | ||
46 | static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value) | 46 | static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value) |
@@ -68,7 +68,7 @@ static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset) | |||
68 | 68 | ||
69 | static int gpio1_get(struct gpio_chip *chip, unsigned offset) | 69 | static int gpio1_get(struct gpio_chip *chip, unsigned offset) |
70 | { | 70 | { |
71 | return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE); | 71 | return !!alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE); |
72 | } | 72 | } |
73 | 73 | ||
74 | static void gpio1_set(struct gpio_chip *chip, | 74 | static void gpio1_set(struct gpio_chip *chip, |
@@ -119,7 +119,7 @@ struct gpio_chip alchemy_gpio_chip[] = { | |||
119 | 119 | ||
120 | static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off) | 120 | static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off) |
121 | { | 121 | { |
122 | return au1300_gpio_get_value(off + AU1300_GPIO_BASE); | 122 | return !!au1300_gpio_get_value(off + AU1300_GPIO_BASE); |
123 | } | 123 | } |
124 | 124 | ||
125 | static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v) | 125 | static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v) |
diff --git a/arch/mips/ar7/gpio.c b/arch/mips/ar7/gpio.c index f4930456eb8e..f969f583c68c 100644 --- a/arch/mips/ar7/gpio.c +++ b/arch/mips/ar7/gpio.c | |||
@@ -37,7 +37,7 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | |||
37 | container_of(chip, struct ar7_gpio_chip, chip); | 37 | container_of(chip, struct ar7_gpio_chip, chip); |
38 | void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT; | 38 | void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT; |
39 | 39 | ||
40 | return readl(gpio_in) & (1 << gpio); | 40 | return !!(readl(gpio_in) & (1 << gpio)); |
41 | } | 41 | } |
42 | 42 | ||
43 | static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | 43 | static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio) |
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h index ca7cc19adfea..870c6b2e97e8 100644 --- a/arch/mips/ath79/common.h +++ b/arch/mips/ath79/common.h | |||
@@ -23,7 +23,6 @@ void ath79_clocks_init(void); | |||
23 | unsigned long ath79_get_sys_clk_rate(const char *id); | 23 | unsigned long ath79_get_sys_clk_rate(const char *id); |
24 | 24 | ||
25 | void ath79_ddr_ctrl_init(void); | 25 | void ath79_ddr_ctrl_init(void); |
26 | void ath79_ddr_wb_flush(unsigned int reg); | ||
27 | 26 | ||
28 | void ath79_gpio_init(void); | 27 | void ath79_gpio_init(void); |
29 | 28 | ||
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index eeb3953ed8ac..511c06560dc1 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
@@ -26,9 +26,13 @@ | |||
26 | #include "common.h" | 26 | #include "common.h" |
27 | #include "machtypes.h" | 27 | #include "machtypes.h" |
28 | 28 | ||
29 | static void __init ath79_misc_intc_domain_init( | ||
30 | struct device_node *node, int irq); | ||
31 | |||
29 | static void ath79_misc_irq_handler(struct irq_desc *desc) | 32 | static void ath79_misc_irq_handler(struct irq_desc *desc) |
30 | { | 33 | { |
31 | void __iomem *base = ath79_reset_base; | 34 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
35 | void __iomem *base = domain->host_data; | ||
32 | u32 pending; | 36 | u32 pending; |
33 | 37 | ||
34 | pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & | 38 | pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & |
@@ -42,15 +46,15 @@ static void ath79_misc_irq_handler(struct irq_desc *desc) | |||
42 | while (pending) { | 46 | while (pending) { |
43 | int bit = __ffs(pending); | 47 | int bit = __ffs(pending); |
44 | 48 | ||
45 | generic_handle_irq(ATH79_MISC_IRQ(bit)); | 49 | generic_handle_irq(irq_linear_revmap(domain, bit)); |
46 | pending &= ~BIT(bit); | 50 | pending &= ~BIT(bit); |
47 | } | 51 | } |
48 | } | 52 | } |
49 | 53 | ||
50 | static void ar71xx_misc_irq_unmask(struct irq_data *d) | 54 | static void ar71xx_misc_irq_unmask(struct irq_data *d) |
51 | { | 55 | { |
52 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | 56 | void __iomem *base = irq_data_get_irq_chip_data(d); |
53 | void __iomem *base = ath79_reset_base; | 57 | unsigned int irq = d->hwirq; |
54 | u32 t; | 58 | u32 t; |
55 | 59 | ||
56 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 60 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
@@ -62,8 +66,8 @@ static void ar71xx_misc_irq_unmask(struct irq_data *d) | |||
62 | 66 | ||
63 | static void ar71xx_misc_irq_mask(struct irq_data *d) | 67 | static void ar71xx_misc_irq_mask(struct irq_data *d) |
64 | { | 68 | { |
65 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | 69 | void __iomem *base = irq_data_get_irq_chip_data(d); |
66 | void __iomem *base = ath79_reset_base; | 70 | unsigned int irq = d->hwirq; |
67 | u32 t; | 71 | u32 t; |
68 | 72 | ||
69 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 73 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
@@ -75,8 +79,8 @@ static void ar71xx_misc_irq_mask(struct irq_data *d) | |||
75 | 79 | ||
76 | static void ar724x_misc_irq_ack(struct irq_data *d) | 80 | static void ar724x_misc_irq_ack(struct irq_data *d) |
77 | { | 81 | { |
78 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | 82 | void __iomem *base = irq_data_get_irq_chip_data(d); |
79 | void __iomem *base = ath79_reset_base; | 83 | unsigned int irq = d->hwirq; |
80 | u32 t; | 84 | u32 t; |
81 | 85 | ||
82 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); | 86 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); |
@@ -94,12 +98,6 @@ static struct irq_chip ath79_misc_irq_chip = { | |||
94 | 98 | ||
95 | static void __init ath79_misc_irq_init(void) | 99 | static void __init ath79_misc_irq_init(void) |
96 | { | 100 | { |
97 | void __iomem *base = ath79_reset_base; | ||
98 | int i; | ||
99 | |||
100 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
101 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); | ||
102 | |||
103 | if (soc_is_ar71xx() || soc_is_ar913x()) | 101 | if (soc_is_ar71xx() || soc_is_ar913x()) |
104 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; | 102 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; |
105 | else if (soc_is_ar724x() || | 103 | else if (soc_is_ar724x() || |
@@ -110,13 +108,7 @@ static void __init ath79_misc_irq_init(void) | |||
110 | else | 108 | else |
111 | BUG(); | 109 | BUG(); |
112 | 110 | ||
113 | for (i = ATH79_MISC_IRQ_BASE; | 111 | ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6)); |
114 | i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) { | ||
115 | irq_set_chip_and_handler(i, &ath79_misc_irq_chip, | ||
116 | handle_level_irq); | ||
117 | } | ||
118 | |||
119 | irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler); | ||
120 | } | 112 | } |
121 | 113 | ||
122 | static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) | 114 | static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) |
@@ -256,10 +248,10 @@ asmlinkage void plat_irq_dispatch(void) | |||
256 | } | 248 | } |
257 | } | 249 | } |
258 | 250 | ||
259 | #ifdef CONFIG_IRQCHIP | ||
260 | static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | 251 | static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) |
261 | { | 252 | { |
262 | irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); | 253 | irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); |
254 | irq_set_chip_data(irq, d->host_data); | ||
263 | return 0; | 255 | return 0; |
264 | } | 256 | } |
265 | 257 | ||
@@ -268,19 +260,14 @@ static const struct irq_domain_ops misc_irq_domain_ops = { | |||
268 | .map = misc_map, | 260 | .map = misc_map, |
269 | }; | 261 | }; |
270 | 262 | ||
271 | static int __init ath79_misc_intc_of_init( | 263 | static void __init ath79_misc_intc_domain_init( |
272 | struct device_node *node, struct device_node *parent) | 264 | struct device_node *node, int irq) |
273 | { | 265 | { |
274 | void __iomem *base = ath79_reset_base; | 266 | void __iomem *base = ath79_reset_base; |
275 | struct irq_domain *domain; | 267 | struct irq_domain *domain; |
276 | int irq; | ||
277 | |||
278 | irq = irq_of_parse_and_map(node, 0); | ||
279 | if (!irq) | ||
280 | panic("Failed to get MISC IRQ"); | ||
281 | 268 | ||
282 | domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT, | 269 | domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT, |
283 | ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL); | 270 | ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base); |
284 | if (!domain) | 271 | if (!domain) |
285 | panic("Failed to add MISC irqdomain"); | 272 | panic("Failed to add MISC irqdomain"); |
286 | 273 | ||
@@ -288,9 +275,19 @@ static int __init ath79_misc_intc_of_init( | |||
288 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 275 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
289 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); | 276 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); |
290 | 277 | ||
278 | irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain); | ||
279 | } | ||
291 | 280 | ||
292 | irq_set_chained_handler(irq, ath79_misc_irq_handler); | 281 | static int __init ath79_misc_intc_of_init( |
282 | struct device_node *node, struct device_node *parent) | ||
283 | { | ||
284 | int irq; | ||
293 | 285 | ||
286 | irq = irq_of_parse_and_map(node, 0); | ||
287 | if (!irq) | ||
288 | panic("Failed to get MISC IRQ"); | ||
289 | |||
290 | ath79_misc_intc_domain_init(node, irq); | ||
294 | return 0; | 291 | return 0; |
295 | } | 292 | } |
296 | 293 | ||
@@ -349,8 +346,6 @@ static int __init ar79_cpu_intc_of_init( | |||
349 | IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc", | 346 | IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc", |
350 | ar79_cpu_intc_of_init); | 347 | ar79_cpu_intc_of_init); |
351 | 348 | ||
352 | #endif | ||
353 | |||
354 | void __init arch_init_irq(void) | 349 | void __init arch_init_irq(void) |
355 | { | 350 | { |
356 | if (mips_machtype == ATH79_MACH_GENERIC_OF) { | 351 | if (mips_machtype == ATH79_MACH_GENERIC_OF) { |
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 8755d618e116..be451ee4a5ea 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
@@ -36,10 +36,6 @@ | |||
36 | 36 | ||
37 | #define ATH79_SYS_TYPE_LEN 64 | 37 | #define ATH79_SYS_TYPE_LEN 64 |
38 | 38 | ||
39 | #define AR71XX_BASE_FREQ 40000000 | ||
40 | #define AR724X_BASE_FREQ 5000000 | ||
41 | #define AR913X_BASE_FREQ 5000000 | ||
42 | |||
43 | static char ath79_sys_type[ATH79_SYS_TYPE_LEN]; | 39 | static char ath79_sys_type[ATH79_SYS_TYPE_LEN]; |
44 | 40 | ||
45 | static void ath79_restart(char *command) | 41 | static void ath79_restart(char *command) |
@@ -272,15 +268,10 @@ void __init device_tree_init(void) | |||
272 | unflatten_and_copy_device_tree(); | 268 | unflatten_and_copy_device_tree(); |
273 | } | 269 | } |
274 | 270 | ||
275 | static void __init ath79_generic_init(void) | ||
276 | { | ||
277 | /* Nothing to do */ | ||
278 | } | ||
279 | |||
280 | MIPS_MACHINE(ATH79_MACH_GENERIC, | 271 | MIPS_MACHINE(ATH79_MACH_GENERIC, |
281 | "Generic", | 272 | "Generic", |
282 | "Generic AR71XX/AR724X/AR913X based board", | 273 | "Generic AR71XX/AR724X/AR913X based board", |
283 | ath79_generic_init); | 274 | NULL); |
284 | 275 | ||
285 | MIPS_MACHINE(ATH79_MACH_GENERIC_OF, | 276 | MIPS_MACHINE(ATH79_MACH_GENERIC_OF, |
286 | "DTB", | 277 | "DTB", |
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index a7e569c7968e..959c145a0a2c 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c | |||
@@ -666,9 +666,15 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | |||
666 | switch (bus->hosttype) { | 666 | switch (bus->hosttype) { |
667 | case BCMA_HOSTTYPE_PCI: | 667 | case BCMA_HOSTTYPE_PCI: |
668 | memset(out, 0, sizeof(struct ssb_sprom)); | 668 | memset(out, 0, sizeof(struct ssb_sprom)); |
669 | snprintf(buf, sizeof(buf), "pci/%u/%u/", | 669 | /* On BCM47XX all PCI buses share the same domain */ |
670 | bus->host_pci->bus->number + 1, | 670 | if (config_enabled(CONFIG_BCM47XX)) |
671 | PCI_SLOT(bus->host_pci->devfn)); | 671 | snprintf(buf, sizeof(buf), "pci/%u/%u/", |
672 | bus->host_pci->bus->number + 1, | ||
673 | PCI_SLOT(bus->host_pci->devfn)); | ||
674 | else | ||
675 | snprintf(buf, sizeof(buf), "pci/%u/%u/", | ||
676 | pci_domain_nr(bus->host_pci->bus) + 1, | ||
677 | bus->host_pci->bus->number); | ||
672 | bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf)); | 678 | bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf)); |
673 | prefix = buf; | 679 | prefix = buf; |
674 | break; | 680 | break; |
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 4b50d40f7451..5f2bc1e10eae 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #define pr_fmt(fmt) "bcm63xx_nvram: " fmt | 11 | #define pr_fmt(fmt) "bcm63xx_nvram: " fmt |
12 | 12 | ||
13 | #include <linux/bcm963xx_nvram.h> | ||
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
14 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
15 | #include <linux/export.h> | 16 | #include <linux/export.h> |
@@ -18,51 +19,19 @@ | |||
18 | 19 | ||
19 | #include <bcm63xx_nvram.h> | 20 | #include <bcm63xx_nvram.h> |
20 | 21 | ||
21 | /* | ||
22 | * nvram structure | ||
23 | */ | ||
24 | struct bcm963xx_nvram { | ||
25 | u32 version; | ||
26 | u8 reserved1[256]; | ||
27 | u8 name[16]; | ||
28 | u32 main_tp_number; | ||
29 | u32 psi_size; | ||
30 | u32 mac_addr_count; | ||
31 | u8 mac_addr_base[ETH_ALEN]; | ||
32 | u8 reserved2[2]; | ||
33 | u32 checksum_old; | ||
34 | u8 reserved3[720]; | ||
35 | u32 checksum_high; | ||
36 | }; | ||
37 | |||
38 | #define BCM63XX_DEFAULT_PSI_SIZE 64 | ||
39 | |||
40 | static struct bcm963xx_nvram nvram; | 22 | static struct bcm963xx_nvram nvram; |
41 | static int mac_addr_used; | 23 | static int mac_addr_used; |
42 | 24 | ||
43 | void __init bcm63xx_nvram_init(void *addr) | 25 | void __init bcm63xx_nvram_init(void *addr) |
44 | { | 26 | { |
45 | unsigned int check_len; | ||
46 | u32 crc, expected_crc; | 27 | u32 crc, expected_crc; |
47 | u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff }; | 28 | u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff }; |
48 | 29 | ||
49 | /* extract nvram data */ | 30 | /* extract nvram data */ |
50 | memcpy(&nvram, addr, sizeof(nvram)); | 31 | memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE); |
51 | 32 | ||
52 | /* check checksum before using data */ | 33 | /* check checksum before using data */ |
53 | if (nvram.version <= 4) { | 34 | if (bcm963xx_nvram_checksum(&nvram, &expected_crc, &crc)) |
54 | check_len = offsetof(struct bcm963xx_nvram, reserved3); | ||
55 | expected_crc = nvram.checksum_old; | ||
56 | nvram.checksum_old = 0; | ||
57 | } else { | ||
58 | check_len = sizeof(nvram); | ||
59 | expected_crc = nvram.checksum_high; | ||
60 | nvram.checksum_high = 0; | ||
61 | } | ||
62 | |||
63 | crc = crc32_le(~0, (u8 *)&nvram, check_len); | ||
64 | |||
65 | if (crc != expected_crc) | ||
66 | pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", | 35 | pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", |
67 | expected_crc, crc); | 36 | expected_crc, crc); |
68 | 37 | ||
@@ -116,12 +85,3 @@ int bcm63xx_nvram_get_mac_address(u8 *mac) | |||
116 | return 0; | 85 | return 0; |
117 | } | 86 | } |
118 | EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); | 87 | EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); |
119 | |||
120 | int bcm63xx_nvram_get_psi_size(void) | ||
121 | { | ||
122 | if (nvram.psi_size > 0) | ||
123 | return nvram.psi_size; | ||
124 | |||
125 | return BCM63XX_DEFAULT_PSI_SIZE; | ||
126 | } | ||
127 | EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); | ||
diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index 5b16d2955fbb..35535284b39e 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c | |||
@@ -105,6 +105,7 @@ static const struct bmips_quirk bmips_quirk_list[] = { | |||
105 | { "brcm,bcm33843-viper", &bcm3384_viper_quirks }, | 105 | { "brcm,bcm33843-viper", &bcm3384_viper_quirks }, |
106 | { "brcm,bcm6328", &bcm6328_quirks }, | 106 | { "brcm,bcm6328", &bcm6328_quirks }, |
107 | { "brcm,bcm6368", &bcm6368_quirks }, | 107 | { "brcm,bcm6368", &bcm6368_quirks }, |
108 | { "brcm,bcm63168", &bcm6368_quirks }, | ||
108 | { }, | 109 | { }, |
109 | }; | 110 | }; |
110 | 111 | ||
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index d5bdee115f22..4eff1ef02eff 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile | |||
@@ -29,20 +29,23 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ | |||
29 | -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ | 29 | -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ |
30 | -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS) | 30 | -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS) |
31 | 31 | ||
32 | targets := head.o decompress.o string.o dbg.o uart-16550.o uart-alchemy.o | ||
33 | |||
34 | # decompressor objects (linked with vmlinuz) | 32 | # decompressor objects (linked with vmlinuz) |
35 | vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o | 33 | vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o |
36 | 34 | ||
37 | ifdef CONFIG_DEBUG_ZBOOT | 35 | ifdef CONFIG_DEBUG_ZBOOT |
38 | vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o | 36 | vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o |
39 | vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o | 37 | vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o |
38 | vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o | ||
40 | vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o | 39 | vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o |
41 | endif | 40 | endif |
42 | 41 | ||
43 | ifdef CONFIG_KERNEL_XZ | 42 | vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o |
44 | vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o | 43 | |
45 | endif | 44 | $(obj)/ashldi3.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib |
45 | $(obj)/ashldi3.c: $(srctree)/arch/mips/lib/ashldi3.c | ||
46 | $(call cmd,shipped) | ||
47 | |||
48 | targets := $(notdir $(vmlinuzobjs-y)) | ||
46 | 49 | ||
47 | targets += vmlinux.bin | 50 | targets += vmlinux.bin |
48 | OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S | 51 | OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S |
@@ -60,7 +63,7 @@ targets += vmlinux.bin.z | |||
60 | $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE | 63 | $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE |
61 | $(call if_changed,$(tool_y)) | 64 | $(call if_changed,$(tool_y)) |
62 | 65 | ||
63 | targets += piggy.o | 66 | targets += piggy.o dummy.o |
64 | OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \ | 67 | OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \ |
65 | --set-section-flags=.image=contents,alloc,load,readonly,data | 68 | --set-section-flags=.image=contents,alloc,load,readonly,data |
66 | $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE | 69 | $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE |
diff --git a/arch/mips/boot/compressed/uart-prom.c b/arch/mips/boot/compressed/uart-prom.c new file mode 100644 index 000000000000..1c3d51bc90bb --- /dev/null +++ b/arch/mips/boot/compressed/uart-prom.c | |||
@@ -0,0 +1,7 @@ | |||
1 | |||
2 | extern void prom_putchar(unsigned char ch); | ||
3 | |||
4 | void putc(char c) | ||
5 | { | ||
6 | prom_putchar(c); | ||
7 | } | ||
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index a0bf516ec394..fc7a0a98e9bf 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile | |||
@@ -4,6 +4,7 @@ dts-dirs += ingenic | |||
4 | dts-dirs += lantiq | 4 | dts-dirs += lantiq |
5 | dts-dirs += mti | 5 | dts-dirs += mti |
6 | dts-dirs += netlogic | 6 | dts-dirs += netlogic |
7 | dts-dirs += pic32 | ||
7 | dts-dirs += qca | 8 | dts-dirs += qca |
8 | dts-dirs += ralink | 9 | dts-dirs += ralink |
9 | dts-dirs += xilfpga | 10 | dts-dirs += xilfpga |
diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi index d52ce3d07f16..459b9b252c3b 100644 --- a/arch/mips/boot/dts/brcm/bcm6328.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi | |||
@@ -31,6 +31,7 @@ | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | aliases { | 33 | aliases { |
34 | leds0 = &leds0; | ||
34 | uart0 = &uart0; | 35 | uart0 = &uart0; |
35 | }; | 36 | }; |
36 | 37 | ||
@@ -81,5 +82,13 @@ | |||
81 | offset = <0x28>; | 82 | offset = <0x28>; |
82 | mask = <0x1>; | 83 | mask = <0x1>; |
83 | }; | 84 | }; |
85 | |||
86 | leds0: led-controller@10000800 { | ||
87 | #address-cells = <1>; | ||
88 | #size-cells = <0>; | ||
89 | compatible = "brcm,bcm6328-leds"; | ||
90 | reg = <0x10000800 0x24>; | ||
91 | status = "disabled"; | ||
92 | }; | ||
84 | }; | 93 | }; |
85 | }; | 94 | }; |
diff --git a/arch/mips/boot/dts/brcm/bcm6368.dtsi b/arch/mips/boot/dts/brcm/bcm6368.dtsi index 45152bc22117..9c8d3fe28b31 100644 --- a/arch/mips/boot/dts/brcm/bcm6368.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6368.dtsi | |||
@@ -32,6 +32,7 @@ | |||
32 | }; | 32 | }; |
33 | 33 | ||
34 | aliases { | 34 | aliases { |
35 | leds0 = &leds0; | ||
35 | uart0 = &uart0; | 36 | uart0 = &uart0; |
36 | }; | 37 | }; |
37 | 38 | ||
@@ -50,6 +51,19 @@ | |||
50 | compatible = "simple-bus"; | 51 | compatible = "simple-bus"; |
51 | ranges; | 52 | ranges; |
52 | 53 | ||
54 | periph_cntl: syscon@10000000 { | ||
55 | compatible = "syscon"; | ||
56 | reg = <0x10000000 0x14>; | ||
57 | little-endian; | ||
58 | }; | ||
59 | |||
60 | reboot: syscon-reboot@10000008 { | ||
61 | compatible = "syscon-reboot"; | ||
62 | regmap = <&periph_cntl>; | ||
63 | offset = <0x8>; | ||
64 | mask = <0x1>; | ||
65 | }; | ||
66 | |||
53 | periph_intc: periph_intc@10000020 { | 67 | periph_intc: periph_intc@10000020 { |
54 | compatible = "brcm,bcm3380-l2-intc"; | 68 | compatible = "brcm,bcm3380-l2-intc"; |
55 | reg = <0x10000024 0x4 0x1000002c 0x4>, | 69 | reg = <0x10000024 0x4 0x1000002c 0x4>, |
@@ -62,6 +76,14 @@ | |||
62 | interrupts = <2>; | 76 | interrupts = <2>; |
63 | }; | 77 | }; |
64 | 78 | ||
79 | leds0: led-controller@100000d0 { | ||
80 | #address-cells = <1>; | ||
81 | #size-cells = <0>; | ||
82 | compatible = "brcm,bcm6358-leds"; | ||
83 | reg = <0x100000d0 0x8>; | ||
84 | status = "disabled"; | ||
85 | }; | ||
86 | |||
65 | uart0: serial@10000100 { | 87 | uart0: serial@10000100 { |
66 | compatible = "brcm,bcm6345-uart"; | 88 | compatible = "brcm,bcm6345-uart"; |
67 | reg = <0x10000100 0x18>; | 89 | reg = <0x10000100 0x18>; |
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index 9fcb9e7d1f57..1652d8d60b1e 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts | |||
@@ -42,3 +42,67 @@ | |||
42 | &uart4 { | 42 | &uart4 { |
43 | status = "okay"; | 43 | status = "okay"; |
44 | }; | 44 | }; |
45 | |||
46 | &nemc { | ||
47 | status = "okay"; | ||
48 | |||
49 | nandc: nand-controller@1 { | ||
50 | compatible = "ingenic,jz4780-nand"; | ||
51 | reg = <1 0 0x1000000>; | ||
52 | |||
53 | #address-cells = <1>; | ||
54 | #size-cells = <0>; | ||
55 | |||
56 | ingenic,bch-controller = <&bch>; | ||
57 | |||
58 | ingenic,nemc-tAS = <10>; | ||
59 | ingenic,nemc-tAH = <5>; | ||
60 | ingenic,nemc-tBP = <10>; | ||
61 | ingenic,nemc-tAW = <15>; | ||
62 | ingenic,nemc-tSTRV = <100>; | ||
63 | |||
64 | nand@1 { | ||
65 | reg = <1>; | ||
66 | |||
67 | nand-ecc-step-size = <1024>; | ||
68 | nand-ecc-strength = <24>; | ||
69 | nand-ecc-mode = "hw"; | ||
70 | nand-on-flash-bbt; | ||
71 | |||
72 | partitions { | ||
73 | compatible = "fixed-partitions"; | ||
74 | #address-cells = <2>; | ||
75 | #size-cells = <2>; | ||
76 | |||
77 | partition@0 { | ||
78 | label = "u-boot-spl"; | ||
79 | reg = <0x0 0x0 0x0 0x800000>; | ||
80 | }; | ||
81 | |||
82 | partition@0x800000 { | ||
83 | label = "u-boot"; | ||
84 | reg = <0x0 0x800000 0x0 0x200000>; | ||
85 | }; | ||
86 | |||
87 | partition@0xa00000 { | ||
88 | label = "u-boot-env"; | ||
89 | reg = <0x0 0xa00000 0x0 0x200000>; | ||
90 | }; | ||
91 | |||
92 | partition@0xc00000 { | ||
93 | label = "boot"; | ||
94 | reg = <0x0 0xc00000 0x0 0x4000000>; | ||
95 | }; | ||
96 | |||
97 | partition@0x8c00000 { | ||
98 | label = "system"; | ||
99 | reg = <0x0 0x4c00000 0x1 0xfb400000>; | ||
100 | }; | ||
101 | }; | ||
102 | }; | ||
103 | }; | ||
104 | }; | ||
105 | |||
106 | &bch { | ||
107 | status = "okay"; | ||
108 | }; | ||
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index 65389f602733..b868b429add2 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi | |||
@@ -108,4 +108,30 @@ | |||
108 | 108 | ||
109 | status = "disabled"; | 109 | status = "disabled"; |
110 | }; | 110 | }; |
111 | |||
112 | nemc: nemc@13410000 { | ||
113 | compatible = "ingenic,jz4780-nemc"; | ||
114 | reg = <0x13410000 0x10000>; | ||
115 | #address-cells = <2>; | ||
116 | #size-cells = <1>; | ||
117 | ranges = <1 0 0x1b000000 0x1000000 | ||
118 | 2 0 0x1a000000 0x1000000 | ||
119 | 3 0 0x19000000 0x1000000 | ||
120 | 4 0 0x18000000 0x1000000 | ||
121 | 5 0 0x17000000 0x1000000 | ||
122 | 6 0 0x16000000 0x1000000>; | ||
123 | |||
124 | clocks = <&cgu JZ4780_CLK_NEMC>; | ||
125 | |||
126 | status = "disabled"; | ||
127 | }; | ||
128 | |||
129 | bch: bch@134d0000 { | ||
130 | compatible = "ingenic,jz4780-bch"; | ||
131 | reg = <0x134d0000 0x10000>; | ||
132 | |||
133 | clocks = <&cgu JZ4780_CLK_BCH>; | ||
134 | |||
135 | status = "disabled"; | ||
136 | }; | ||
111 | }; | 137 | }; |
diff --git a/arch/mips/boot/dts/pic32/Makefile b/arch/mips/boot/dts/pic32/Makefile new file mode 100644 index 000000000000..7ac790551ec9 --- /dev/null +++ b/arch/mips/boot/dts/pic32/Makefile | |||
@@ -0,0 +1,12 @@ | |||
1 | dtb-$(CONFIG_DTB_PIC32_MZDA_SK) += pic32mzda_sk.dtb | ||
2 | |||
3 | dtb-$(CONFIG_DTB_PIC32_NONE) += \ | ||
4 | pic32mzda_sk.dtb | ||
5 | |||
6 | obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) | ||
7 | |||
8 | # Force kbuild to make empty built-in.o if necessary | ||
9 | obj- += dummy.o | ||
10 | |||
11 | always := $(dtb-y) | ||
12 | clean-files := *.dtb *.dtb.S | ||
diff --git a/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi new file mode 100644 index 000000000000..ef1335012f43 --- /dev/null +++ b/arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi | |||
@@ -0,0 +1,236 @@ | |||
1 | /* | ||
2 | * Device Tree Source for PIC32MZDA clock data | ||
3 | * | ||
4 | * Purna Chandra Mandal <purna.mandal@microchip.com> | ||
5 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
6 | * | ||
7 | * Licensed under GPLv2 or later. | ||
8 | */ | ||
9 | |||
10 | /* all fixed rate clocks */ | ||
11 | |||
12 | / { | ||
13 | POSC:posc_clk { /* On-chip primary oscillator */ | ||
14 | #clock-cells = <0>; | ||
15 | compatible = "fixed-clock"; | ||
16 | clock-frequency = <24000000>; | ||
17 | }; | ||
18 | |||
19 | FRC:frc_clk { /* internal FRC oscillator */ | ||
20 | #clock-cells = <0>; | ||
21 | compatible = "fixed-clock"; | ||
22 | clock-frequency = <8000000>; | ||
23 | }; | ||
24 | |||
25 | BFRC:bfrc_clk { /* internal backup FRC oscillator */ | ||
26 | #clock-cells = <0>; | ||
27 | compatible = "fixed-clock"; | ||
28 | clock-frequency = <8000000>; | ||
29 | }; | ||
30 | |||
31 | LPRC:lprc_clk { /* internal low-power FRC oscillator */ | ||
32 | #clock-cells = <0>; | ||
33 | compatible = "fixed-clock"; | ||
34 | clock-frequency = <32000>; | ||
35 | }; | ||
36 | |||
37 | /* UPLL provides clock to USBCORE */ | ||
38 | UPLL:usb_phy_clk { | ||
39 | #clock-cells = <0>; | ||
40 | compatible = "fixed-clock"; | ||
41 | clock-frequency = <24000000>; | ||
42 | clock-output-names = "usbphy_clk"; | ||
43 | }; | ||
44 | |||
45 | TxCKI:txcki_clk { /* external clock input on TxCLKI pin */ | ||
46 | #clock-cells = <0>; | ||
47 | compatible = "fixed-clock"; | ||
48 | clock-frequency = <4000000>; | ||
49 | status = "disabled"; | ||
50 | }; | ||
51 | |||
52 | /* external clock input on REFCLKIx pin */ | ||
53 | REFIx:refix_clk { | ||
54 | #clock-cells = <0>; | ||
55 | compatible = "fixed-clock"; | ||
56 | clock-frequency = <24000000>; | ||
57 | status = "disabled"; | ||
58 | }; | ||
59 | |||
60 | /* PIC32 specific clks */ | ||
61 | pic32_clktree { | ||
62 | #address-cells = <1>; | ||
63 | #size-cells = <1>; | ||
64 | reg = <0x1f801200 0x200>; | ||
65 | compatible = "microchip,pic32mzda-clk"; | ||
66 | ranges = <0 0x1f801200 0x200>; | ||
67 | |||
68 | /* secondary oscillator; external input on SOSCI pin */ | ||
69 | SOSC:sosc_clk@0 { | ||
70 | #clock-cells = <0>; | ||
71 | compatible = "microchip,pic32mzda-sosc"; | ||
72 | clock-frequency = <32768>; | ||
73 | reg = <0x000 0x10>, /* enable reg */ | ||
74 | <0x1d0 0x10>; /* status reg */ | ||
75 | microchip,bit-mask = <0x02>; /* enable mask */ | ||
76 | microchip,status-bit-mask = <0x10>; /* status-mask*/ | ||
77 | }; | ||
78 | |||
79 | FRCDIV:frcdiv_clk { | ||
80 | #clock-cells = <0>; | ||
81 | compatible = "microchip,pic32mzda-frcdivclk"; | ||
82 | clocks = <&FRC>; | ||
83 | clock-output-names = "frcdiv_clk"; | ||
84 | }; | ||
85 | |||
86 | /* System PLL clock */ | ||
87 | SYSPLL:spll_clk@020 { | ||
88 | #clock-cells = <0>; | ||
89 | compatible = "microchip,pic32mzda-syspll"; | ||
90 | reg = <0x020 0x10>, /* SPLL register */ | ||
91 | <0x1d0 0x10>; /* CLKSTAT register */ | ||
92 | clocks = <&POSC>, <&FRC>; | ||
93 | clock-output-names = "sys_pll"; | ||
94 | microchip,status-bit-mask = <0x80>; /* SPLLRDY */ | ||
95 | }; | ||
96 | |||
97 | /* system clock; mux with postdiv & slew */ | ||
98 | SYSCLK:sys_clk@1c0 { | ||
99 | #clock-cells = <0>; | ||
100 | compatible = "microchip,pic32mzda-sysclk-v2"; | ||
101 | reg = <0x1c0 0x04>; /* SLEWCON */ | ||
102 | clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>, | ||
103 | <&LPRC>, <&FRCDIV>; | ||
104 | microchip,clock-indices = <0>, <1>, <2>, <4>, | ||
105 | <5>, <7>; | ||
106 | clock-output-names = "sys_clk"; | ||
107 | }; | ||
108 | |||
109 | /* Peripheral bus1 clock */ | ||
110 | PBCLK1:pb1_clk@140 { | ||
111 | reg = <0x140 0x10>; | ||
112 | #clock-cells = <0>; | ||
113 | compatible = "microchip,pic32mzda-pbclk"; | ||
114 | clocks = <&SYSCLK>; | ||
115 | clock-output-names = "pb1_clk"; | ||
116 | /* used by system modules, not gateable */ | ||
117 | microchip,ignore-unused; | ||
118 | }; | ||
119 | |||
120 | /* Peripheral bus2 clock */ | ||
121 | PBCLK2:pb2_clk@150 { | ||
122 | reg = <0x150 0x10>; | ||
123 | #clock-cells = <0>; | ||
124 | compatible = "microchip,pic32mzda-pbclk"; | ||
125 | clocks = <&SYSCLK>; | ||
126 | clock-output-names = "pb2_clk"; | ||
127 | /* avoid gating even if unused */ | ||
128 | microchip,ignore-unused; | ||
129 | }; | ||
130 | |||
131 | /* Peripheral bus3 clock */ | ||
132 | PBCLK3:pb3_clk@160 { | ||
133 | reg = <0x160 0x10>; | ||
134 | #clock-cells = <0>; | ||
135 | compatible = "microchip,pic32mzda-pbclk"; | ||
136 | clocks = <&SYSCLK>; | ||
137 | clock-output-names = "pb3_clk"; | ||
138 | }; | ||
139 | |||
140 | /* Peripheral bus4 clock(I/O ports, GPIO) */ | ||
141 | PBCLK4:pb4_clk@170 { | ||
142 | reg = <0x170 0x10>; | ||
143 | #clock-cells = <0>; | ||
144 | compatible = "microchip,pic32mzda-pbclk"; | ||
145 | clocks = <&SYSCLK>; | ||
146 | clock-output-names = "pb4_clk"; | ||
147 | }; | ||
148 | |||
149 | /* Peripheral bus clock */ | ||
150 | PBCLK5:pb5_clk@180 { | ||
151 | reg = <0x180 0x10>; | ||
152 | #clock-cells = <0>; | ||
153 | compatible = "microchip,pic32mzda-pbclk"; | ||
154 | clocks = <&SYSCLK>; | ||
155 | clock-output-names = "pb5_clk"; | ||
156 | }; | ||
157 | |||
158 | /* Peripheral Bus6 clock; */ | ||
159 | PBCLK6:pb6_clk@190 { | ||
160 | reg = <0x190 0x10>; | ||
161 | compatible = "microchip,pic32mzda-pbclk"; | ||
162 | clocks = <&SYSCLK>; | ||
163 | #clock-cells = <0>; | ||
164 | }; | ||
165 | |||
166 | /* Peripheral bus7 clock */ | ||
167 | PBCLK7:pb7_clk@1a0 { | ||
168 | reg = <0x1a0 0x10>; | ||
169 | #clock-cells = <0>; | ||
170 | compatible = "microchip,pic32mzda-pbclk"; | ||
171 | /* CPU is driven by this clock; so named */ | ||
172 | clock-output-names = "cpu_clk"; | ||
173 | clocks = <&SYSCLK>; | ||
174 | }; | ||
175 | |||
176 | /* Reference Oscillator clock for SPI/I2S */ | ||
177 | REFCLKO1:refo1_clk@80 { | ||
178 | reg = <0x080 0x20>; | ||
179 | #clock-cells = <0>; | ||
180 | compatible = "microchip,pic32mzda-refoclk"; | ||
181 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
182 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
183 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
184 | <5>, <7>, <8>, <9>; | ||
185 | clock-output-names = "refo1_clk"; | ||
186 | }; | ||
187 | |||
188 | /* Reference Oscillator clock for SQI */ | ||
189 | REFCLKO2:refo2_clk@a0 { | ||
190 | reg = <0x0a0 0x20>; | ||
191 | #clock-cells = <0>; | ||
192 | compatible = "microchip,pic32mzda-refoclk"; | ||
193 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
194 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
195 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
196 | <5>, <7>, <8>, <9>; | ||
197 | clock-output-names = "refo2_clk"; | ||
198 | }; | ||
199 | |||
200 | /* Reference Oscillator clock, ADC */ | ||
201 | REFCLKO3:refo3_clk@c0 { | ||
202 | reg = <0x0c0 0x20>; | ||
203 | compatible = "microchip,pic32mzda-refoclk"; | ||
204 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
205 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
206 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
207 | <5>, <7>, <8>, <9>; | ||
208 | #clock-cells = <0>; | ||
209 | clock-output-names = "refo3_clk"; | ||
210 | }; | ||
211 | |||
212 | /* Reference Oscillator clock */ | ||
213 | REFCLKO4:refo4_clk@e0 { | ||
214 | reg = <0x0e0 0x20>; | ||
215 | compatible = "microchip,pic32mzda-refoclk"; | ||
216 | clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>, | ||
217 | <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>; | ||
218 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
219 | <5>, <7>, <8>, <9>; | ||
220 | #clock-cells = <0>; | ||
221 | clock-output-names = "refo4_clk"; | ||
222 | }; | ||
223 | |||
224 | /* Reference Oscillator clock, LCD */ | ||
225 | REFCLKO5:refo5_clk@100 { | ||
226 | reg = <0x100 0x20>; | ||
227 | compatible = "microchip,pic32mzda-refoclk"; | ||
228 | clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>, | ||
229 | <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>; | ||
230 | microchip,clock-indices = <0>, <1>, <2>, <3>, <4>, | ||
231 | <5>, <7>, <8>, <9>; | ||
232 | #clock-cells = <0>; | ||
233 | clock-output-names = "refo5_clk"; | ||
234 | }; | ||
235 | }; | ||
236 | }; | ||
diff --git a/arch/mips/boot/dts/pic32/pic32mzda.dtsi b/arch/mips/boot/dts/pic32/pic32mzda.dtsi new file mode 100644 index 000000000000..ad9e3318c2ce --- /dev/null +++ b/arch/mips/boot/dts/pic32/pic32mzda.dtsi | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <dt-bindings/interrupt-controller/irq.h> | ||
11 | |||
12 | #include "pic32mzda-clk.dtsi" | ||
13 | |||
14 | / { | ||
15 | #address-cells = <1>; | ||
16 | #size-cells = <1>; | ||
17 | interrupt-parent = <&evic>; | ||
18 | |||
19 | aliases { | ||
20 | gpio0 = &gpio0; | ||
21 | gpio1 = &gpio1; | ||
22 | gpio2 = &gpio2; | ||
23 | gpio3 = &gpio3; | ||
24 | gpio4 = &gpio4; | ||
25 | gpio5 = &gpio5; | ||
26 | gpio6 = &gpio6; | ||
27 | gpio7 = &gpio7; | ||
28 | gpio8 = &gpio8; | ||
29 | gpio9 = &gpio9; | ||
30 | serial0 = &uart1; | ||
31 | serial1 = &uart2; | ||
32 | serial2 = &uart3; | ||
33 | serial3 = &uart4; | ||
34 | serial4 = &uart5; | ||
35 | serial5 = &uart6; | ||
36 | }; | ||
37 | |||
38 | cpus { | ||
39 | #address-cells = <1>; | ||
40 | #size-cells = <0>; | ||
41 | |||
42 | cpu@0 { | ||
43 | compatible = "mti,mips14KEc"; | ||
44 | device_type = "cpu"; | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | soc { | ||
49 | compatible = "microchip,pic32mzda-infra"; | ||
50 | interrupts = <0 IRQ_TYPE_EDGE_RISING>; | ||
51 | }; | ||
52 | |||
53 | evic: interrupt-controller@1f810000 { | ||
54 | compatible = "microchip,pic32mzda-evic"; | ||
55 | interrupt-controller; | ||
56 | #interrupt-cells = <2>; | ||
57 | reg = <0x1f810000 0x1000>; | ||
58 | microchip,external-irqs = <3 8 13 18 23>; | ||
59 | }; | ||
60 | |||
61 | pic32_pinctrl: pinctrl@1f801400{ | ||
62 | #address-cells = <1>; | ||
63 | #size-cells = <1>; | ||
64 | compatible = "microchip,pic32mzda-pinctrl"; | ||
65 | reg = <0x1f801400 0x400>; | ||
66 | clocks = <&PBCLK1>; | ||
67 | }; | ||
68 | |||
69 | /* PORTA */ | ||
70 | gpio0: gpio0@1f860000 { | ||
71 | compatible = "microchip,pic32mzda-gpio"; | ||
72 | reg = <0x1f860000 0x100>; | ||
73 | interrupts = <118 IRQ_TYPE_LEVEL_HIGH>; | ||
74 | #gpio-cells = <2>; | ||
75 | gpio-controller; | ||
76 | interrupt-controller; | ||
77 | #interrupt-cells = <2>; | ||
78 | clocks = <&PBCLK4>; | ||
79 | microchip,gpio-bank = <0>; | ||
80 | gpio-ranges = <&pic32_pinctrl 0 0 16>; | ||
81 | }; | ||
82 | |||
83 | /* PORTB */ | ||
84 | gpio1: gpio1@1f860100 { | ||
85 | compatible = "microchip,pic32mzda-gpio"; | ||
86 | reg = <0x1f860100 0x100>; | ||
87 | interrupts = <119 IRQ_TYPE_LEVEL_HIGH>; | ||
88 | #gpio-cells = <2>; | ||
89 | gpio-controller; | ||
90 | interrupt-controller; | ||
91 | #interrupt-cells = <2>; | ||
92 | clocks = <&PBCLK4>; | ||
93 | microchip,gpio-bank = <1>; | ||
94 | gpio-ranges = <&pic32_pinctrl 0 16 16>; | ||
95 | }; | ||
96 | |||
97 | /* PORTC */ | ||
98 | gpio2: gpio2@1f860200 { | ||
99 | compatible = "microchip,pic32mzda-gpio"; | ||
100 | reg = <0x1f860200 0x100>; | ||
101 | interrupts = <120 IRQ_TYPE_LEVEL_HIGH>; | ||
102 | #gpio-cells = <2>; | ||
103 | gpio-controller; | ||
104 | interrupt-controller; | ||
105 | #interrupt-cells = <2>; | ||
106 | clocks = <&PBCLK4>; | ||
107 | microchip,gpio-bank = <2>; | ||
108 | gpio-ranges = <&pic32_pinctrl 0 32 16>; | ||
109 | }; | ||
110 | |||
111 | /* PORTD */ | ||
112 | gpio3: gpio3@1f860300 { | ||
113 | compatible = "microchip,pic32mzda-gpio"; | ||
114 | reg = <0x1f860300 0x100>; | ||
115 | interrupts = <121 IRQ_TYPE_LEVEL_HIGH>; | ||
116 | #gpio-cells = <2>; | ||
117 | gpio-controller; | ||
118 | interrupt-controller; | ||
119 | #interrupt-cells = <2>; | ||
120 | clocks = <&PBCLK4>; | ||
121 | microchip,gpio-bank = <3>; | ||
122 | gpio-ranges = <&pic32_pinctrl 0 48 16>; | ||
123 | }; | ||
124 | |||
125 | /* PORTE */ | ||
126 | gpio4: gpio4@1f860400 { | ||
127 | compatible = "microchip,pic32mzda-gpio"; | ||
128 | reg = <0x1f860400 0x100>; | ||
129 | interrupts = <122 IRQ_TYPE_LEVEL_HIGH>; | ||
130 | #gpio-cells = <2>; | ||
131 | gpio-controller; | ||
132 | interrupt-controller; | ||
133 | #interrupt-cells = <2>; | ||
134 | clocks = <&PBCLK4>; | ||
135 | microchip,gpio-bank = <4>; | ||
136 | gpio-ranges = <&pic32_pinctrl 0 64 16>; | ||
137 | }; | ||
138 | |||
139 | /* PORTF */ | ||
140 | gpio5: gpio5@1f860500 { | ||
141 | compatible = "microchip,pic32mzda-gpio"; | ||
142 | reg = <0x1f860500 0x100>; | ||
143 | interrupts = <123 IRQ_TYPE_LEVEL_HIGH>; | ||
144 | #gpio-cells = <2>; | ||
145 | gpio-controller; | ||
146 | interrupt-controller; | ||
147 | #interrupt-cells = <2>; | ||
148 | clocks = <&PBCLK4>; | ||
149 | microchip,gpio-bank = <5>; | ||
150 | gpio-ranges = <&pic32_pinctrl 0 80 16>; | ||
151 | }; | ||
152 | |||
153 | /* PORTG */ | ||
154 | gpio6: gpio6@1f860600 { | ||
155 | compatible = "microchip,pic32mzda-gpio"; | ||
156 | reg = <0x1f860600 0x100>; | ||
157 | interrupts = <124 IRQ_TYPE_LEVEL_HIGH>; | ||
158 | #gpio-cells = <2>; | ||
159 | gpio-controller; | ||
160 | interrupt-controller; | ||
161 | #interrupt-cells = <2>; | ||
162 | clocks = <&PBCLK4>; | ||
163 | microchip,gpio-bank = <6>; | ||
164 | gpio-ranges = <&pic32_pinctrl 0 96 16>; | ||
165 | }; | ||
166 | |||
167 | /* PORTH */ | ||
168 | gpio7: gpio7@1f860700 { | ||
169 | compatible = "microchip,pic32mzda-gpio"; | ||
170 | reg = <0x1f860700 0x100>; | ||
171 | interrupts = <125 IRQ_TYPE_LEVEL_HIGH>; | ||
172 | #gpio-cells = <2>; | ||
173 | gpio-controller; | ||
174 | interrupt-controller; | ||
175 | #interrupt-cells = <2>; | ||
176 | clocks = <&PBCLK4>; | ||
177 | microchip,gpio-bank = <7>; | ||
178 | gpio-ranges = <&pic32_pinctrl 0 112 16>; | ||
179 | }; | ||
180 | |||
181 | /* PORTI does not exist */ | ||
182 | |||
183 | /* PORTJ */ | ||
184 | gpio8: gpio8@1f860800 { | ||
185 | compatible = "microchip,pic32mzda-gpio"; | ||
186 | reg = <0x1f860800 0x100>; | ||
187 | interrupts = <126 IRQ_TYPE_LEVEL_HIGH>; | ||
188 | #gpio-cells = <2>; | ||
189 | gpio-controller; | ||
190 | interrupt-controller; | ||
191 | #interrupt-cells = <2>; | ||
192 | clocks = <&PBCLK4>; | ||
193 | microchip,gpio-bank = <8>; | ||
194 | gpio-ranges = <&pic32_pinctrl 0 128 16>; | ||
195 | }; | ||
196 | |||
197 | /* PORTK */ | ||
198 | gpio9: gpio9@1f860900 { | ||
199 | compatible = "microchip,pic32mzda-gpio"; | ||
200 | reg = <0x1f860900 0x100>; | ||
201 | interrupts = <127 IRQ_TYPE_LEVEL_HIGH>; | ||
202 | #gpio-cells = <2>; | ||
203 | gpio-controller; | ||
204 | interrupt-controller; | ||
205 | #interrupt-cells = <2>; | ||
206 | clocks = <&PBCLK4>; | ||
207 | microchip,gpio-bank = <9>; | ||
208 | gpio-ranges = <&pic32_pinctrl 0 144 16>; | ||
209 | }; | ||
210 | |||
211 | sdhci: sdhci@1f8ec000 { | ||
212 | compatible = "microchip,pic32mzda-sdhci"; | ||
213 | reg = <0x1f8ec000 0x100>; | ||
214 | interrupts = <191 IRQ_TYPE_LEVEL_HIGH>; | ||
215 | clocks = <&REFCLKO4>, <&PBCLK5>; | ||
216 | clock-names = "base_clk", "sys_clk"; | ||
217 | bus-width = <4>; | ||
218 | cap-sd-highspeed; | ||
219 | status = "disabled"; | ||
220 | }; | ||
221 | |||
222 | uart1: serial@1f822000 { | ||
223 | compatible = "microchip,pic32mzda-uart"; | ||
224 | reg = <0x1f822000 0x50>; | ||
225 | interrupts = <112 IRQ_TYPE_LEVEL_HIGH>, | ||
226 | <113 IRQ_TYPE_LEVEL_HIGH>, | ||
227 | <114 IRQ_TYPE_LEVEL_HIGH>; | ||
228 | clocks = <&PBCLK2>; | ||
229 | status = "disabled"; | ||
230 | }; | ||
231 | |||
232 | uart2: serial@1f822200 { | ||
233 | compatible = "microchip,pic32mzda-uart"; | ||
234 | reg = <0x1f822200 0x50>; | ||
235 | interrupts = <145 IRQ_TYPE_LEVEL_HIGH>, | ||
236 | <146 IRQ_TYPE_LEVEL_HIGH>, | ||
237 | <147 IRQ_TYPE_LEVEL_HIGH>; | ||
238 | clocks = <&PBCLK2>; | ||
239 | status = "disabled"; | ||
240 | }; | ||
241 | |||
242 | uart3: serial@1f822400 { | ||
243 | compatible = "microchip,pic32mzda-uart"; | ||
244 | reg = <0x1f822400 0x50>; | ||
245 | interrupts = <157 IRQ_TYPE_LEVEL_HIGH>, | ||
246 | <158 IRQ_TYPE_LEVEL_HIGH>, | ||
247 | <159 IRQ_TYPE_LEVEL_HIGH>; | ||
248 | clocks = <&PBCLK2>; | ||
249 | status = "disabled"; | ||
250 | }; | ||
251 | |||
252 | uart4: serial@1f822600 { | ||
253 | compatible = "microchip,pic32mzda-uart"; | ||
254 | reg = <0x1f822600 0x50>; | ||
255 | interrupts = <170 IRQ_TYPE_LEVEL_HIGH>, | ||
256 | <171 IRQ_TYPE_LEVEL_HIGH>, | ||
257 | <172 IRQ_TYPE_LEVEL_HIGH>; | ||
258 | clocks = <&PBCLK2>; | ||
259 | status = "disabled"; | ||
260 | }; | ||
261 | |||
262 | uart5: serial@1f822800 { | ||
263 | compatible = "microchip,pic32mzda-uart"; | ||
264 | reg = <0x1f822800 0x50>; | ||
265 | interrupts = <179 IRQ_TYPE_LEVEL_HIGH>, | ||
266 | <180 IRQ_TYPE_LEVEL_HIGH>, | ||
267 | <181 IRQ_TYPE_LEVEL_HIGH>; | ||
268 | clocks = <&PBCLK2>; | ||
269 | status = "disabled"; | ||
270 | }; | ||
271 | |||
272 | uart6: serial@1f822A00 { | ||
273 | compatible = "microchip,pic32mzda-uart"; | ||
274 | reg = <0x1f822A00 0x50>; | ||
275 | interrupts = <188 IRQ_TYPE_LEVEL_HIGH>, | ||
276 | <189 IRQ_TYPE_LEVEL_HIGH>, | ||
277 | <190 IRQ_TYPE_LEVEL_HIGH>; | ||
278 | clocks = <&PBCLK2>; | ||
279 | status = "disabled"; | ||
280 | }; | ||
281 | }; | ||
diff --git a/arch/mips/boot/dts/pic32/pic32mzda_sk.dts b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts new file mode 100644 index 000000000000..5d434a50e85b --- /dev/null +++ b/arch/mips/boot/dts/pic32/pic32mzda_sk.dts | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /dts-v1/; | ||
11 | |||
12 | #include <dt-bindings/gpio/gpio.h> | ||
13 | #include <dt-bindings/interrupt-controller/irq.h> | ||
14 | |||
15 | #include "pic32mzda.dtsi" | ||
16 | |||
17 | / { | ||
18 | compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda"; | ||
19 | model = "Microchip PIC32MZDA Starter Kit"; | ||
20 | |||
21 | memory { | ||
22 | device_type = "memory"; | ||
23 | reg = <0x08000000 0x08000000>; | ||
24 | }; | ||
25 | |||
26 | chosen { | ||
27 | bootargs = "earlyprintk=ttyPIC1,115200n8r console=ttyPIC1,115200n8"; | ||
28 | }; | ||
29 | |||
30 | leds0 { | ||
31 | compatible = "gpio-leds"; | ||
32 | pinctrl-names = "default"; | ||
33 | pinctrl-0 = <&user_leds_s0>; | ||
34 | |||
35 | led@1 { | ||
36 | label = "pic32mzda_sk:red:led1"; | ||
37 | gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>; | ||
38 | linux,default-trigger = "heartbeat"; | ||
39 | }; | ||
40 | |||
41 | led@2 { | ||
42 | label = "pic32mzda_sk:yellow:led2"; | ||
43 | gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; | ||
44 | linux,default-trigger = "mmc0"; | ||
45 | }; | ||
46 | |||
47 | led@3 { | ||
48 | label = "pic32mzda_sk:green:led3"; | ||
49 | gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>; | ||
50 | default-state = "on"; | ||
51 | }; | ||
52 | }; | ||
53 | |||
54 | keys0 { | ||
55 | compatible = "gpio-keys"; | ||
56 | pinctrl-0 = <&user_buttons_s0>; | ||
57 | pinctrl-names = "default"; | ||
58 | |||
59 | #address-cells = <1>; | ||
60 | #size-cells = <0>; | ||
61 | |||
62 | button@sw1 { | ||
63 | label = "ESC"; | ||
64 | linux,code = <1>; | ||
65 | gpios = <&gpio1 12 0>; | ||
66 | }; | ||
67 | |||
68 | button@sw2 { | ||
69 | label = "Home"; | ||
70 | linux,code = <102>; | ||
71 | gpios = <&gpio1 13 0>; | ||
72 | }; | ||
73 | |||
74 | button@sw3 { | ||
75 | label = "Menu"; | ||
76 | linux,code = <139>; | ||
77 | gpios = <&gpio1 14 0>; | ||
78 | }; | ||
79 | }; | ||
80 | }; | ||
81 | |||
82 | &uart2 { | ||
83 | pinctrl-names = "default"; | ||
84 | pinctrl-0 = <&pinctrl_uart2>; | ||
85 | status = "okay"; | ||
86 | }; | ||
87 | |||
88 | &uart4 { | ||
89 | pinctrl-names = "default"; | ||
90 | pinctrl-0 = <&pinctrl_uart4>; | ||
91 | status = "okay"; | ||
92 | }; | ||
93 | |||
94 | &sdhci { | ||
95 | pinctrl-names = "default"; | ||
96 | pinctrl-0 = <&pinctrl_sdhc1>; | ||
97 | status = "okay"; | ||
98 | assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>; | ||
99 | assigned-clock-rates = <50000000>,<25000000>,<40000000>; | ||
100 | }; | ||
101 | |||
102 | &pic32_pinctrl { | ||
103 | |||
104 | pinctrl_sdhc1: sdhc1_pins0 { | ||
105 | pins = "A6", "D4", "G13", "G12", "G14", "A7", "A0"; | ||
106 | microchip,digital; | ||
107 | }; | ||
108 | |||
109 | user_leds_s0: user_leds_s0 { | ||
110 | pins = "H0", "H1", "H2"; | ||
111 | output-low; | ||
112 | microchip,digital; | ||
113 | }; | ||
114 | |||
115 | user_buttons_s0: user_buttons_s0 { | ||
116 | pins = "B12", "B13", "B14"; | ||
117 | microchip,digital; | ||
118 | input-enable; | ||
119 | bias-pull-up; | ||
120 | }; | ||
121 | |||
122 | pinctrl_uart2: pinctrl_uart2 { | ||
123 | uart2-tx { | ||
124 | pins = "G9"; | ||
125 | function = "U2TX"; | ||
126 | microchip,digital; | ||
127 | output-high; | ||
128 | }; | ||
129 | uart2-rx { | ||
130 | pins = "B0"; | ||
131 | function = "U2RX"; | ||
132 | microchip,digital; | ||
133 | input-enable; | ||
134 | }; | ||
135 | }; | ||
136 | |||
137 | pinctrl_uart4: uart4-0 { | ||
138 | uart4-tx { | ||
139 | pins = "C3"; | ||
140 | function = "U4TX"; | ||
141 | microchip,digital; | ||
142 | output-high; | ||
143 | }; | ||
144 | uart4-rx { | ||
145 | pins = "E8"; | ||
146 | function = "U4RX"; | ||
147 | microchip,digital; | ||
148 | input-enable; | ||
149 | }; | ||
150 | }; | ||
151 | }; | ||
diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi index 13d0439496a9..3ad4ba9b12fd 100644 --- a/arch/mips/boot/dts/qca/ar9132.dtsi +++ b/arch/mips/boot/dts/qca/ar9132.dtsi | |||
@@ -125,6 +125,21 @@ | |||
125 | }; | 125 | }; |
126 | }; | 126 | }; |
127 | 127 | ||
128 | usb@1b000100 { | ||
129 | compatible = "qca,ar7100-ehci", "generic-ehci"; | ||
130 | reg = <0x1b000100 0x100>; | ||
131 | |||
132 | interrupts = <3>; | ||
133 | resets = <&rst 5>; | ||
134 | |||
135 | has-transaction-translator; | ||
136 | |||
137 | phy-names = "usb"; | ||
138 | phys = <&usb_phy>; | ||
139 | |||
140 | status = "disabled"; | ||
141 | }; | ||
142 | |||
128 | spi@1f000000 { | 143 | spi@1f000000 { |
129 | compatible = "qca,ar9132-spi", "qca,ar7100-spi"; | 144 | compatible = "qca,ar9132-spi", "qca,ar7100-spi"; |
130 | reg = <0x1f000000 0x10>; | 145 | reg = <0x1f000000 0x10>; |
@@ -138,4 +153,15 @@ | |||
138 | #size-cells = <0>; | 153 | #size-cells = <0>; |
139 | }; | 154 | }; |
140 | }; | 155 | }; |
156 | |||
157 | usb_phy: usb-phy { | ||
158 | compatible = "qca,ar7100-usb-phy"; | ||
159 | |||
160 | reset-names = "usb-phy", "usb-suspend-override"; | ||
161 | resets = <&rst 4>, <&rst 3>; | ||
162 | |||
163 | #phy-cells = <0>; | ||
164 | |||
165 | status = "disabled"; | ||
166 | }; | ||
141 | }; | 167 | }; |
diff --git a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts index 003015ab34e7..e535ee3c26a4 100644 --- a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts +++ b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts | |||
@@ -35,6 +35,10 @@ | |||
35 | }; | 35 | }; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | usb@1b000100 { | ||
39 | status = "okay"; | ||
40 | }; | ||
41 | |||
38 | spi@1f000000 { | 42 | spi@1f000000 { |
39 | status = "okay"; | 43 | status = "okay"; |
40 | num-cs = <1>; | 44 | num-cs = <1>; |
@@ -65,6 +69,10 @@ | |||
65 | }; | 69 | }; |
66 | }; | 70 | }; |
67 | 71 | ||
72 | usb-phy { | ||
73 | status = "okay"; | ||
74 | }; | ||
75 | |||
68 | gpio-keys { | 76 | gpio-keys { |
69 | compatible = "gpio-keys-polled"; | 77 | compatible = "gpio-keys-polled"; |
70 | #address-cells = <1>; | 78 | #address-cells = <1>; |
diff --git a/arch/mips/configs/pic32mzda_defconfig b/arch/mips/configs/pic32mzda_defconfig new file mode 100644 index 000000000000..52192c632ae8 --- /dev/null +++ b/arch/mips/configs/pic32mzda_defconfig | |||
@@ -0,0 +1,89 @@ | |||
1 | CONFIG_MACH_PIC32=y | ||
2 | CONFIG_DTB_PIC32_MZDA_SK=y | ||
3 | CONFIG_HZ_100=y | ||
4 | CONFIG_PREEMPT_VOLUNTARY=y | ||
5 | # CONFIG_SECCOMP is not set | ||
6 | CONFIG_SYSVIPC=y | ||
7 | CONFIG_NO_HZ=y | ||
8 | CONFIG_HIGH_RES_TIMERS=y | ||
9 | CONFIG_IKCONFIG=y | ||
10 | CONFIG_IKCONFIG_PROC=y | ||
11 | CONFIG_LOG_BUF_SHIFT=14 | ||
12 | CONFIG_RELAY=y | ||
13 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
14 | CONFIG_EMBEDDED=y | ||
15 | # CONFIG_COMPAT_BRK is not set | ||
16 | CONFIG_SLAB=y | ||
17 | CONFIG_JUMP_LABEL=y | ||
18 | CONFIG_MODULES=y | ||
19 | CONFIG_MODULE_UNLOAD=y | ||
20 | CONFIG_MODVERSIONS=y | ||
21 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
22 | CONFIG_BLK_DEV_BSGLIB=y | ||
23 | CONFIG_PARTITION_ADVANCED=y | ||
24 | CONFIG_SGI_PARTITION=y | ||
25 | CONFIG_BINFMT_MISC=m | ||
26 | # CONFIG_SUSPEND is not set | ||
27 | CONFIG_DEVTMPFS=y | ||
28 | CONFIG_DEVTMPFS_MOUNT=y | ||
29 | # CONFIG_FIRMWARE_IN_KERNEL is not set | ||
30 | # CONFIG_ALLOW_DEV_COREDUMP is not set | ||
31 | CONFIG_BLK_DEV_LOOP=m | ||
32 | CONFIG_SCSI=y | ||
33 | CONFIG_BLK_DEV_SD=y | ||
34 | CONFIG_SCSI_CONSTANTS=y | ||
35 | CONFIG_SCSI_SCAN_ASYNC=y | ||
36 | # CONFIG_SCSI_LOWLEVEL is not set | ||
37 | CONFIG_INPUT_LEDS=m | ||
38 | CONFIG_INPUT_POLLDEV=y | ||
39 | CONFIG_INPUT_MOUSEDEV=m | ||
40 | CONFIG_INPUT_EVDEV=y | ||
41 | CONFIG_INPUT_EVBUG=m | ||
42 | # CONFIG_KEYBOARD_ATKBD is not set | ||
43 | CONFIG_KEYBOARD_GPIO=m | ||
44 | CONFIG_KEYBOARD_GPIO_POLLED=m | ||
45 | # CONFIG_MOUSE_PS2 is not set | ||
46 | # CONFIG_SERIO is not set | ||
47 | CONFIG_SERIAL_PIC32=y | ||
48 | CONFIG_SERIAL_PIC32_CONSOLE=y | ||
49 | CONFIG_HW_RANDOM=y | ||
50 | CONFIG_RAW_DRIVER=m | ||
51 | CONFIG_GPIO_SYSFS=y | ||
52 | # CONFIG_HWMON is not set | ||
53 | CONFIG_HIDRAW=y | ||
54 | # CONFIG_USB_SUPPORT is not set | ||
55 | CONFIG_MMC=y | ||
56 | CONFIG_MMC_SDHCI=y | ||
57 | CONFIG_MMC_SDHCI_PLTFM=y | ||
58 | CONFIG_MMC_SDHCI_MICROCHIP_PIC32=y | ||
59 | CONFIG_NEW_LEDS=y | ||
60 | CONFIG_LEDS_CLASS=y | ||
61 | CONFIG_LEDS_GPIO=y | ||
62 | CONFIG_LEDS_TRIGGERS=y | ||
63 | CONFIG_LEDS_TRIGGER_TIMER=m | ||
64 | CONFIG_LEDS_TRIGGER_ONESHOT=m | ||
65 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
66 | CONFIG_LEDS_TRIGGER_GPIO=m | ||
67 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
68 | # CONFIG_MIPS_PLATFORM_DEVICES is not set | ||
69 | # CONFIG_IOMMU_SUPPORT is not set | ||
70 | CONFIG_EXT4_FS=y | ||
71 | CONFIG_EXT4_FS_POSIX_ACL=y | ||
72 | CONFIG_EXT4_FS_SECURITY=y | ||
73 | CONFIG_AUTOFS4_FS=m | ||
74 | CONFIG_FUSE_FS=m | ||
75 | CONFIG_FSCACHE=m | ||
76 | CONFIG_ISO9660_FS=m | ||
77 | CONFIG_JOLIET=y | ||
78 | CONFIG_ZISOFS=y | ||
79 | CONFIG_UDF_FS=m | ||
80 | CONFIG_MSDOS_FS=m | ||
81 | CONFIG_VFAT_FS=m | ||
82 | CONFIG_PROC_KCORE=y | ||
83 | CONFIG_TMPFS=y | ||
84 | CONFIG_TMPFS_POSIX_ACL=y | ||
85 | CONFIG_SQUASHFS=m | ||
86 | CONFIG_SQUASHFS_XATTR=y | ||
87 | CONFIG_SQUASHFS_LZ4=y | ||
88 | CONFIG_SQUASHFS_LZO=y | ||
89 | CONFIG_SQUASHFS_XZ=y | ||
diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index 06b9bc7ea14b..c3212ff26723 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h | |||
@@ -12,54 +12,76 @@ | |||
12 | #define __ASM_CACHEOPS_H | 12 | #define __ASM_CACHEOPS_H |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Most cache ops are split into a 2 bit field identifying the cache, and a 3 | ||
16 | * bit field identifying the cache operation. | ||
17 | */ | ||
18 | #define CacheOp_Cache 0x03 | ||
19 | #define CacheOp_Op 0x1c | ||
20 | |||
21 | #define Cache_I 0x00 | ||
22 | #define Cache_D 0x01 | ||
23 | #define Cache_T 0x02 | ||
24 | #define Cache_S 0x03 | ||
25 | |||
26 | #define Index_Writeback_Inv 0x00 | ||
27 | #define Index_Load_Tag 0x04 | ||
28 | #define Index_Store_Tag 0x08 | ||
29 | #define Hit_Invalidate 0x10 | ||
30 | #define Hit_Writeback_Inv 0x14 /* not with Cache_I though */ | ||
31 | #define Hit_Writeback 0x18 | ||
32 | |||
33 | /* | ||
15 | * Cache Operations available on all MIPS processors with R4000-style caches | 34 | * Cache Operations available on all MIPS processors with R4000-style caches |
16 | */ | 35 | */ |
17 | #define Index_Invalidate_I 0x00 | 36 | #define Index_Invalidate_I (Cache_I | Index_Writeback_Inv) |
18 | #define Index_Writeback_Inv_D 0x01 | 37 | #define Index_Writeback_Inv_D (Cache_D | Index_Writeback_Inv) |
19 | #define Index_Load_Tag_I 0x04 | 38 | #define Index_Load_Tag_I (Cache_I | Index_Load_Tag) |
20 | #define Index_Load_Tag_D 0x05 | 39 | #define Index_Load_Tag_D (Cache_D | Index_Load_Tag) |
21 | #define Index_Store_Tag_I 0x08 | 40 | #define Index_Store_Tag_I (Cache_I | Index_Store_Tag) |
22 | #define Index_Store_Tag_D 0x09 | 41 | #define Index_Store_Tag_D (Cache_D | Index_Store_Tag) |
23 | #define Hit_Invalidate_I 0x10 | 42 | #define Hit_Invalidate_I (Cache_I | Hit_Invalidate) |
24 | #define Hit_Invalidate_D 0x11 | 43 | #define Hit_Invalidate_D (Cache_D | Hit_Invalidate) |
25 | #define Hit_Writeback_Inv_D 0x15 | 44 | #define Hit_Writeback_Inv_D (Cache_D | Hit_Writeback_Inv) |
26 | 45 | ||
27 | /* | 46 | /* |
28 | * R4000-specific cacheops | 47 | * R4000-specific cacheops |
29 | */ | 48 | */ |
30 | #define Create_Dirty_Excl_D 0x0d | 49 | #define Create_Dirty_Excl_D (Cache_D | 0x0c) |
31 | #define Fill 0x14 | 50 | #define Fill (Cache_I | 0x14) |
32 | #define Hit_Writeback_I 0x18 | 51 | #define Hit_Writeback_I (Cache_I | Hit_Writeback) |
33 | #define Hit_Writeback_D 0x19 | 52 | #define Hit_Writeback_D (Cache_D | Hit_Writeback) |
34 | 53 | ||
35 | /* | 54 | /* |
36 | * R4000SC and R4400SC-specific cacheops | 55 | * R4000SC and R4400SC-specific cacheops |
37 | */ | 56 | */ |
38 | #define Index_Invalidate_SI 0x02 | 57 | #define Cache_SI 0x02 |
39 | #define Index_Writeback_Inv_SD 0x03 | 58 | #define Cache_SD 0x03 |
40 | #define Index_Load_Tag_SI 0x06 | 59 | |
41 | #define Index_Load_Tag_SD 0x07 | 60 | #define Index_Invalidate_SI (Cache_SI | Index_Writeback_Inv) |
42 | #define Index_Store_Tag_SI 0x0A | 61 | #define Index_Writeback_Inv_SD (Cache_SD | Index_Writeback_Inv) |
43 | #define Index_Store_Tag_SD 0x0B | 62 | #define Index_Load_Tag_SI (Cache_SI | Index_Load_Tag) |
44 | #define Create_Dirty_Excl_SD 0x0f | 63 | #define Index_Load_Tag_SD (Cache_SD | Index_Load_Tag) |
45 | #define Hit_Invalidate_SI 0x12 | 64 | #define Index_Store_Tag_SI (Cache_SI | Index_Store_Tag) |
46 | #define Hit_Invalidate_SD 0x13 | 65 | #define Index_Store_Tag_SD (Cache_SD | Index_Store_Tag) |
47 | #define Hit_Writeback_Inv_SD 0x17 | 66 | #define Create_Dirty_Excl_SD (Cache_SD | 0x0c) |
48 | #define Hit_Writeback_SD 0x1b | 67 | #define Hit_Invalidate_SI (Cache_SI | Hit_Invalidate) |
49 | #define Hit_Set_Virtual_SI 0x1e | 68 | #define Hit_Invalidate_SD (Cache_SD | Hit_Invalidate) |
50 | #define Hit_Set_Virtual_SD 0x1f | 69 | #define Hit_Writeback_Inv_SD (Cache_SD | Hit_Writeback_Inv) |
70 | #define Hit_Writeback_SD (Cache_SD | Hit_Writeback) | ||
71 | #define Hit_Set_Virtual_SI (Cache_SI | 0x1c) | ||
72 | #define Hit_Set_Virtual_SD (Cache_SD | 0x1c) | ||
51 | 73 | ||
52 | /* | 74 | /* |
53 | * R5000-specific cacheops | 75 | * R5000-specific cacheops |
54 | */ | 76 | */ |
55 | #define R5K_Page_Invalidate_S 0x17 | 77 | #define R5K_Page_Invalidate_S (Cache_S | 0x14) |
56 | 78 | ||
57 | /* | 79 | /* |
58 | * RM7000-specific cacheops | 80 | * RM7000-specific cacheops |
59 | */ | 81 | */ |
60 | #define Page_Invalidate_T 0x16 | 82 | #define Page_Invalidate_T (Cache_T | 0x14) |
61 | #define Index_Store_Tag_T 0x0a | 83 | #define Index_Store_Tag_T (Cache_T | Index_Store_Tag) |
62 | #define Index_Load_Tag_T 0x06 | 84 | #define Index_Load_Tag_T (Cache_T | Index_Load_Tag) |
63 | 85 | ||
64 | /* | 86 | /* |
65 | * R10000-specific cacheops | 87 | * R10000-specific cacheops |
@@ -67,22 +89,22 @@ | |||
67 | * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. | 89 | * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. |
68 | * Most of the _S cacheops are identical to the R4000SC _SD cacheops. | 90 | * Most of the _S cacheops are identical to the R4000SC _SD cacheops. |
69 | */ | 91 | */ |
70 | #define Index_Writeback_Inv_S 0x03 | 92 | #define Index_Writeback_Inv_S (Cache_S | Index_Writeback_Inv) |
71 | #define Index_Load_Tag_S 0x07 | 93 | #define Index_Load_Tag_S (Cache_S | Index_Load_Tag) |
72 | #define Index_Store_Tag_S 0x0B | 94 | #define Index_Store_Tag_S (Cache_S | Index_Store_Tag) |
73 | #define Hit_Invalidate_S 0x13 | 95 | #define Hit_Invalidate_S (Cache_S | Hit_Invalidate) |
74 | #define Cache_Barrier 0x14 | 96 | #define Cache_Barrier 0x14 |
75 | #define Hit_Writeback_Inv_S 0x17 | 97 | #define Hit_Writeback_Inv_S (Cache_S | Hit_Writeback_Inv) |
76 | #define Index_Load_Data_I 0x18 | 98 | #define Index_Load_Data_I (Cache_I | 0x18) |
77 | #define Index_Load_Data_D 0x19 | 99 | #define Index_Load_Data_D (Cache_D | 0x18) |
78 | #define Index_Load_Data_S 0x1b | 100 | #define Index_Load_Data_S (Cache_S | 0x18) |
79 | #define Index_Store_Data_I 0x1c | 101 | #define Index_Store_Data_I (Cache_I | 0x1c) |
80 | #define Index_Store_Data_D 0x1d | 102 | #define Index_Store_Data_D (Cache_D | 0x1c) |
81 | #define Index_Store_Data_S 0x1f | 103 | #define Index_Store_Data_S (Cache_S | 0x1c) |
82 | 104 | ||
83 | /* | 105 | /* |
84 | * Loongson2-specific cacheops | 106 | * Loongson2-specific cacheops |
85 | */ | 107 | */ |
86 | #define Hit_Invalidate_I_Loongson2 0x00 | 108 | #define Hit_Invalidate_I_Loongson2 (Cache_I | 0x00) |
87 | 109 | ||
88 | #endif /* __ASM_CACHEOPS_H */ | 110 | #endif /* __ASM_CACHEOPS_H */ |
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index d1e04c943f5f..eeec8c8e2da2 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
@@ -414,4 +414,11 @@ | |||
414 | # define cpu_has_small_pages (cpu_data[0].options & MIPS_CPU_SP) | 414 | # define cpu_has_small_pages (cpu_data[0].options & MIPS_CPU_SP) |
415 | #endif | 415 | #endif |
416 | 416 | ||
417 | #ifndef cpu_has_nan_legacy | ||
418 | #define cpu_has_nan_legacy (cpu_data[0].options & MIPS_CPU_NAN_LEGACY) | ||
419 | #endif | ||
420 | #ifndef cpu_has_nan_2008 | ||
421 | #define cpu_has_nan_2008 (cpu_data[0].options & MIPS_CPU_NAN_2008) | ||
422 | #endif | ||
423 | |||
417 | #endif /* __ASM_CPU_FEATURES_H */ | 424 | #endif /* __ASM_CPU_FEATURES_H */ |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 82ad15f11049..a97ca97285ec 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -386,6 +386,8 @@ enum cpu_type_enum { | |||
386 | #define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */ | 386 | #define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */ |
387 | #define MIPS_CPU_SP 0x10000000000ull /* Small (1KB) page support */ | 387 | #define MIPS_CPU_SP 0x10000000000ull /* Small (1KB) page support */ |
388 | #define MIPS_CPU_FTLB 0x20000000000ull /* CPU has Fixed-page-size TLB */ | 388 | #define MIPS_CPU_FTLB 0x20000000000ull /* CPU has Fixed-page-size TLB */ |
389 | #define MIPS_CPU_NAN_LEGACY 0x40000000000ull /* Legacy NaN implemented */ | ||
390 | #define MIPS_CPU_NAN_2008 0x80000000000ull /* 2008 NaN implemented */ | ||
389 | 391 | ||
390 | /* | 392 | /* |
391 | * CPU ASE encodings | 393 | * CPU ASE encodings |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index b01a6ff468e0..cefb7a596878 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
13 | #include <uapi/linux/elf.h> | 13 | #include <uapi/linux/elf.h> |
14 | 14 | ||
15 | #include <asm/cpu-info.h> | ||
16 | #include <asm/current.h> | 15 | #include <asm/current.h> |
17 | 16 | ||
18 | /* ELF header e_flags defines. */ | 17 | /* ELF header e_flags defines. */ |
@@ -44,6 +43,7 @@ | |||
44 | #define EF_MIPS_OPTIONS_FIRST 0x00000080 | 43 | #define EF_MIPS_OPTIONS_FIRST 0x00000080 |
45 | #define EF_MIPS_32BITMODE 0x00000100 | 44 | #define EF_MIPS_32BITMODE 0x00000100 |
46 | #define EF_MIPS_FP64 0x00000200 | 45 | #define EF_MIPS_FP64 0x00000200 |
46 | #define EF_MIPS_NAN2008 0x00000400 | ||
47 | #define EF_MIPS_ABI 0x0000f000 | 47 | #define EF_MIPS_ABI 0x0000f000 |
48 | #define EF_MIPS_ARCH 0xf0000000 | 48 | #define EF_MIPS_ARCH 0xf0000000 |
49 | 49 | ||
@@ -305,7 +305,7 @@ do { \ | |||
305 | \ | 305 | \ |
306 | current->thread.abi = &mips_abi; \ | 306 | current->thread.abi = &mips_abi; \ |
307 | \ | 307 | \ |
308 | current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \ | 308 | mips_set_personality_nan(state); \ |
309 | } while (0) | 309 | } while (0) |
310 | 310 | ||
311 | #endif /* CONFIG_32BIT */ | 311 | #endif /* CONFIG_32BIT */ |
@@ -367,7 +367,7 @@ do { \ | |||
367 | else \ | 367 | else \ |
368 | current->thread.abi = &mips_abi; \ | 368 | current->thread.abi = &mips_abi; \ |
369 | \ | 369 | \ |
370 | current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \ | 370 | mips_set_personality_nan(state); \ |
371 | \ | 371 | \ |
372 | p = personality(current->personality); \ | 372 | p = personality(current->personality); \ |
373 | if (p != PER_LINUX32 && p != PER_LINUX) \ | 373 | if (p != PER_LINUX32 && p != PER_LINUX) \ |
@@ -432,6 +432,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, | |||
432 | int uses_interp); | 432 | int uses_interp); |
433 | 433 | ||
434 | struct arch_elf_state { | 434 | struct arch_elf_state { |
435 | int nan_2008; | ||
435 | int fp_abi; | 436 | int fp_abi; |
436 | int interp_fp_abi; | 437 | int interp_fp_abi; |
437 | int overall_fp_mode; | 438 | int overall_fp_mode; |
@@ -440,17 +441,23 @@ struct arch_elf_state { | |||
440 | #define MIPS_ABI_FP_UNKNOWN (-1) /* Unknown FP ABI (kernel internal) */ | 441 | #define MIPS_ABI_FP_UNKNOWN (-1) /* Unknown FP ABI (kernel internal) */ |
441 | 442 | ||
442 | #define INIT_ARCH_ELF_STATE { \ | 443 | #define INIT_ARCH_ELF_STATE { \ |
444 | .nan_2008 = -1, \ | ||
443 | .fp_abi = MIPS_ABI_FP_UNKNOWN, \ | 445 | .fp_abi = MIPS_ABI_FP_UNKNOWN, \ |
444 | .interp_fp_abi = MIPS_ABI_FP_UNKNOWN, \ | 446 | .interp_fp_abi = MIPS_ABI_FP_UNKNOWN, \ |
445 | .overall_fp_mode = -1, \ | 447 | .overall_fp_mode = -1, \ |
446 | } | 448 | } |
447 | 449 | ||
450 | /* Whether to accept legacy-NaN and 2008-NaN user binaries. */ | ||
451 | extern bool mips_use_nan_legacy; | ||
452 | extern bool mips_use_nan_2008; | ||
453 | |||
448 | extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, | 454 | extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, |
449 | bool is_interp, struct arch_elf_state *state); | 455 | bool is_interp, struct arch_elf_state *state); |
450 | 456 | ||
451 | extern int arch_check_elf(void *ehdr, bool has_interpreter, | 457 | extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr, |
452 | struct arch_elf_state *state); | 458 | struct arch_elf_state *state); |
453 | 459 | ||
460 | extern void mips_set_personality_nan(struct arch_elf_state *state); | ||
454 | extern void mips_set_personality_fp(struct arch_elf_state *state); | 461 | extern void mips_set_personality_fp(struct arch_elf_state *state); |
455 | 462 | ||
456 | #endif /* _ASM_ELF_H */ | 463 | #endif /* _ASM_ELF_H */ |
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index 2f021cdfba4f..3225c3c0724b 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h | |||
@@ -79,7 +79,7 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, | |||
79 | /* | 79 | /* |
80 | * Break instruction with special math emu break code set | 80 | * Break instruction with special math emu break code set |
81 | */ | 81 | */ |
82 | #define BREAK_MATH (0x0000000d | (BRK_MEMU << 16)) | 82 | #define BREAK_MATH(micromips) (((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16)) |
83 | 83 | ||
84 | #define SIGNALLING_NAN 0x7ff800007ff80000LL | 84 | #define SIGNALLING_NAN 0x7ff800007ff80000LL |
85 | 85 | ||
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index d10fd80dbb7e..2b4dc7ad53b8 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
@@ -275,6 +275,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si | |||
275 | */ | 275 | */ |
276 | #define ioremap_cachable(offset, size) \ | 276 | #define ioremap_cachable(offset, size) \ |
277 | __ioremap_mode((offset), (size), _page_cachable_default) | 277 | __ioremap_mode((offset), (size), _page_cachable_default) |
278 | #define ioremap_cache ioremap_cachable | ||
278 | 279 | ||
279 | /* | 280 | /* |
280 | * These two are MIPS specific ioremap variant. ioremap_cacheable_cow | 281 | * These two are MIPS specific ioremap variant. ioremap_cacheable_cow |
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index e7b138b4b3d3..65c351e328cc 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h | |||
@@ -84,41 +84,11 @@ static inline void arch_local_irq_restore(unsigned long flags) | |||
84 | : "memory"); | 84 | : "memory"); |
85 | } | 85 | } |
86 | 86 | ||
87 | static inline void __arch_local_irq_restore(unsigned long flags) | ||
88 | { | ||
89 | __asm__ __volatile__( | ||
90 | " .set push \n" | ||
91 | " .set noreorder \n" | ||
92 | " .set noat \n" | ||
93 | #if defined(CONFIG_IRQ_MIPS_CPU) | ||
94 | /* | ||
95 | * Slow, but doesn't suffer from a relatively unlikely race | ||
96 | * condition we're having since days 1. | ||
97 | */ | ||
98 | " beqz %[flags], 1f \n" | ||
99 | " di \n" | ||
100 | " ei \n" | ||
101 | "1: \n" | ||
102 | #else | ||
103 | /* | ||
104 | * Fast, dangerous. Life is fun, life is good. | ||
105 | */ | ||
106 | " mfc0 $1, $12 \n" | ||
107 | " ins $1, %[flags], 0, 1 \n" | ||
108 | " mtc0 $1, $12 \n" | ||
109 | #endif | ||
110 | " " __stringify(__irq_disable_hazard) " \n" | ||
111 | " .set pop \n" | ||
112 | : [flags] "=r" (flags) | ||
113 | : "0" (flags) | ||
114 | : "memory"); | ||
115 | } | ||
116 | #else | 87 | #else |
117 | /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ | 88 | /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ |
118 | void arch_local_irq_disable(void); | 89 | void arch_local_irq_disable(void); |
119 | unsigned long arch_local_irq_save(void); | 90 | unsigned long arch_local_irq_save(void); |
120 | void arch_local_irq_restore(unsigned long flags); | 91 | void arch_local_irq_restore(unsigned long flags); |
121 | void __arch_local_irq_restore(unsigned long flags); | ||
122 | #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ | 92 | #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ |
123 | 93 | ||
124 | static inline void arch_local_irq_enable(void) | 94 | static inline void arch_local_irq_enable(void) |
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 7c191443c7ea..f6b12790716c 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h | |||
@@ -58,7 +58,7 @@ | |||
58 | #define KVM_MAX_VCPUS 1 | 58 | #define KVM_MAX_VCPUS 1 |
59 | #define KVM_USER_MEM_SLOTS 8 | 59 | #define KVM_USER_MEM_SLOTS 8 |
60 | /* memory slots that does not exposed to userspace */ | 60 | /* memory slots that does not exposed to userspace */ |
61 | #define KVM_PRIVATE_MEM_SLOTS 0 | 61 | #define KVM_PRIVATE_MEM_SLOTS 0 |
62 | 62 | ||
63 | #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 | 63 | #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 |
64 | #define KVM_HALT_POLL_NS_DEFAULT 500000 | 64 | #define KVM_HALT_POLL_NS_DEFAULT 500000 |
@@ -92,14 +92,6 @@ | |||
92 | #define KVM_INVALID_INST 0xdeadbeef | 92 | #define KVM_INVALID_INST 0xdeadbeef |
93 | #define KVM_INVALID_ADDR 0xdeadbeef | 93 | #define KVM_INVALID_ADDR 0xdeadbeef |
94 | 94 | ||
95 | #define KVM_MALTA_GUEST_RTC_ADDR 0xb8000070UL | ||
96 | |||
97 | #define GUEST_TICKS_PER_JIFFY (40000000/HZ) | ||
98 | #define MS_TO_NS(x) (x * 1E6L) | ||
99 | |||
100 | #define CAUSEB_DC 27 | ||
101 | #define CAUSEF_DC (_ULCAST_(1) << 27) | ||
102 | |||
103 | extern atomic_t kvm_mips_instance; | 95 | extern atomic_t kvm_mips_instance; |
104 | extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn); | 96 | extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn); |
105 | extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn); | 97 | extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn); |
@@ -289,34 +281,6 @@ enum mips_mmu_types { | |||
289 | MMU_TYPE_R8000 | 281 | MMU_TYPE_R8000 |
290 | }; | 282 | }; |
291 | 283 | ||
292 | /* | ||
293 | * Trap codes | ||
294 | */ | ||
295 | #define T_INT 0 /* Interrupt pending */ | ||
296 | #define T_TLB_MOD 1 /* TLB modified fault */ | ||
297 | #define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */ | ||
298 | #define T_TLB_ST_MISS 3 /* TLB miss on a store */ | ||
299 | #define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */ | ||
300 | #define T_ADDR_ERR_ST 5 /* Address error on a store */ | ||
301 | #define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */ | ||
302 | #define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */ | ||
303 | #define T_SYSCALL 8 /* System call */ | ||
304 | #define T_BREAK 9 /* Breakpoint */ | ||
305 | #define T_RES_INST 10 /* Reserved instruction exception */ | ||
306 | #define T_COP_UNUSABLE 11 /* Coprocessor unusable */ | ||
307 | #define T_OVFLOW 12 /* Arithmetic overflow */ | ||
308 | |||
309 | /* | ||
310 | * Trap definitions added for r4000 port. | ||
311 | */ | ||
312 | #define T_TRAP 13 /* Trap instruction */ | ||
313 | #define T_VCEI 14 /* Virtual coherency exception */ | ||
314 | #define T_MSAFPE 14 /* MSA floating point exception */ | ||
315 | #define T_FPE 15 /* Floating point exception */ | ||
316 | #define T_MSADIS 21 /* MSA disabled exception */ | ||
317 | #define T_WATCH 23 /* Watch address reference */ | ||
318 | #define T_VCED 31 /* Virtual coherency data */ | ||
319 | |||
320 | /* Resume Flags */ | 284 | /* Resume Flags */ |
321 | #define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */ | 285 | #define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */ |
322 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ | 286 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
@@ -686,7 +650,6 @@ extern void kvm_mips_dump_host_tlbs(void); | |||
686 | extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu); | 650 | extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu); |
687 | extern void kvm_mips_flush_host_tlb(int skip_kseg0); | 651 | extern void kvm_mips_flush_host_tlb(int skip_kseg0); |
688 | extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi); | 652 | extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi); |
689 | extern int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index); | ||
690 | 653 | ||
691 | extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, | 654 | extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, |
692 | unsigned long entryhi); | 655 | unsigned long entryhi); |
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h index 4eee221b0cf0..2b3487213d1e 100644 --- a/arch/mips/include/asm/mach-ath79/ath79.h +++ b/arch/mips/include/asm/mach-ath79/ath79.h | |||
@@ -115,6 +115,7 @@ static inline int soc_is_qca955x(void) | |||
115 | return soc_is_qca9556() || soc_is_qca9558(); | 115 | return soc_is_qca9556() || soc_is_qca9558(); |
116 | } | 116 | } |
117 | 117 | ||
118 | void ath79_ddr_wb_flush(unsigned int reg); | ||
118 | void ath79_ddr_set_pci_windows(void); | 119 | void ath79_ddr_set_pci_windows(void); |
119 | 120 | ||
120 | extern void __iomem *ath79_pll_base; | 121 | extern void __iomem *ath79_pll_base; |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 348df49dcc9f..4e0b6bc1165e 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | |||
@@ -30,6 +30,4 @@ u8 *bcm63xx_nvram_get_name(void); | |||
30 | */ | 30 | */ |
31 | int bcm63xx_nvram_get_mac_address(u8 *mac); | 31 | int bcm63xx_nvram_get_mac_address(u8 *mac); |
32 | 32 | ||
33 | int bcm63xx_nvram_get_psi_size(void); | ||
34 | |||
35 | #endif /* BCM63XX_NVRAM_H */ | 33 | #endif /* BCM63XX_NVRAM_H */ |
diff --git a/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h b/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h new file mode 100644 index 000000000000..468230834e2f --- /dev/null +++ b/arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | #ifndef __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H | ||
10 | #define __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H | ||
11 | |||
12 | /* | ||
13 | * CPU feature overrides for PIC32 boards | ||
14 | */ | ||
15 | #ifdef CONFIG_CPU_MIPS32 | ||
16 | #define cpu_has_vint 1 | ||
17 | #define cpu_has_veic 0 | ||
18 | #define cpu_has_tlb 1 | ||
19 | #define cpu_has_4kex 1 | ||
20 | #define cpu_has_4k_cache 1 | ||
21 | #define cpu_has_fpu 0 | ||
22 | #define cpu_has_counter 1 | ||
23 | #define cpu_has_llsc 1 | ||
24 | #define cpu_has_nofpuex 0 | ||
25 | #define cpu_icache_snoops_remote_store 1 | ||
26 | #endif | ||
27 | |||
28 | #ifdef CONFIG_CPU_MIPS64 | ||
29 | #error This platform does not support 64bit. | ||
30 | #endif | ||
31 | |||
32 | #endif /* __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/arch/mips/include/asm/mach-pic32/irq.h b/arch/mips/include/asm/mach-pic32/irq.h new file mode 100644 index 000000000000..864330ce8838 --- /dev/null +++ b/arch/mips/include/asm/mach-pic32/irq.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #ifndef __ASM_MACH_PIC32_IRQ_H | ||
15 | #define __ASM_MACH_PIC32_IRQ_H | ||
16 | |||
17 | #define NR_IRQS 256 | ||
18 | #define MIPS_CPU_IRQ_BASE 0 | ||
19 | |||
20 | #include_next <irq.h> | ||
21 | |||
22 | #endif /* __ASM_MACH_PIC32_IRQ_H */ | ||
diff --git a/arch/mips/include/asm/mach-pic32/pic32.h b/arch/mips/include/asm/mach-pic32/pic32.h new file mode 100644 index 000000000000..ce52e918daae --- /dev/null +++ b/arch/mips/include/asm/mach-pic32/pic32.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #ifndef _ASM_MACH_PIC32_H | ||
15 | #define _ASM_MACH_PIC32_H | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | |||
19 | /* | ||
20 | * PIC32 register offsets for SET/CLR/INV where supported. | ||
21 | */ | ||
22 | #define PIC32_CLR(_reg) ((_reg) + 0x04) | ||
23 | #define PIC32_SET(_reg) ((_reg) + 0x08) | ||
24 | #define PIC32_INV(_reg) ((_reg) + 0x0C) | ||
25 | |||
26 | /* | ||
27 | * PIC32 Base Register Offsets | ||
28 | */ | ||
29 | #define PIC32_BASE_CONFIG 0x1f800000 | ||
30 | #define PIC32_BASE_OSC 0x1f801200 | ||
31 | #define PIC32_BASE_RESET 0x1f801240 | ||
32 | #define PIC32_BASE_PPS 0x1f801400 | ||
33 | #define PIC32_BASE_UART 0x1f822000 | ||
34 | #define PIC32_BASE_PORT 0x1f860000 | ||
35 | #define PIC32_BASE_DEVCFG2 0x1fc4ff44 | ||
36 | |||
37 | /* | ||
38 | * Register unlock sequence required for some register access. | ||
39 | */ | ||
40 | void pic32_syskey_unlock_debug(const char *fn, const ulong ln); | ||
41 | #define pic32_syskey_unlock() \ | ||
42 | pic32_syskey_unlock_debug(__func__, __LINE__) | ||
43 | |||
44 | #endif /* _ASM_MACH_PIC32_H */ | ||
diff --git a/arch/mips/include/asm/mach-pic32/spaces.h b/arch/mips/include/asm/mach-pic32/spaces.h new file mode 100644 index 000000000000..046a0a9aa8b3 --- /dev/null +++ b/arch/mips/include/asm/mach-pic32/spaces.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #ifndef _ASM_MACH_PIC32_SPACES_H | ||
15 | #define _ASM_MACH_PIC32_SPACES_H | ||
16 | |||
17 | #ifdef CONFIG_PIC32MZDA | ||
18 | #define PHYS_OFFSET _AC(0x08000000, UL) | ||
19 | #define UNCAC_BASE _AC(0xa8000000, UL) | ||
20 | #endif | ||
21 | |||
22 | #include <asm/mach-generic/spaces.h> | ||
23 | |||
24 | #endif /* __ASM_MACH_PIC32_SPACES_H */ | ||
diff --git a/arch/mips/include/asm/mach-ralink/irq.h b/arch/mips/include/asm/mach-ralink/irq.h new file mode 100644 index 000000000000..4321865e04b9 --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/irq.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef __ASM_MACH_RALINK_IRQ_H | ||
2 | #define __ASM_MACH_RALINK_IRQ_H | ||
3 | |||
4 | #define GIC_NUM_INTRS 64 | ||
5 | #define NR_IRQS 256 | ||
6 | |||
7 | #include_next <irq.h> | ||
8 | |||
9 | #endif | ||
diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h new file mode 100644 index 000000000000..610b61e3f9df --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/mt7621.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _MT7621_REGS_H_ | ||
10 | #define _MT7621_REGS_H_ | ||
11 | |||
12 | #define MT7621_PALMBUS_BASE 0x1C000000 | ||
13 | #define MT7621_PALMBUS_SIZE 0x03FFFFFF | ||
14 | |||
15 | #define MT7621_SYSC_BASE 0x1E000000 | ||
16 | |||
17 | #define SYSC_REG_CHIP_NAME0 0x00 | ||
18 | #define SYSC_REG_CHIP_NAME1 0x04 | ||
19 | #define SYSC_REG_CHIP_REV 0x0c | ||
20 | #define SYSC_REG_SYSTEM_CONFIG0 0x10 | ||
21 | #define SYSC_REG_SYSTEM_CONFIG1 0x14 | ||
22 | |||
23 | #define CHIP_REV_PKG_MASK 0x1 | ||
24 | #define CHIP_REV_PKG_SHIFT 16 | ||
25 | #define CHIP_REV_VER_MASK 0xf | ||
26 | #define CHIP_REV_VER_SHIFT 8 | ||
27 | #define CHIP_REV_ECO_MASK 0xf | ||
28 | |||
29 | #define MT7621_DRAM_BASE 0x0 | ||
30 | #define MT7621_DDR2_SIZE_MIN 32 | ||
31 | #define MT7621_DDR2_SIZE_MAX 256 | ||
32 | |||
33 | #define MT7621_CHIP_NAME0 0x3637544D | ||
34 | #define MT7621_CHIP_NAME1 0x20203132 | ||
35 | |||
36 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
37 | |||
38 | #endif | ||
diff --git a/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h new file mode 100644 index 000000000000..15db1b330fe8 --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Ralink MT7621 specific CPU feature overrides | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
6 | * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org> | ||
7 | * | ||
8 | * This file was derived from: include/asm-mips/cpu-features.h | ||
9 | * Copyright (C) 2003, 2004 Ralf Baechle | ||
10 | * Copyright (C) 2004 Maciej W. Rozycki | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License version 2 as published | ||
14 | * by the Free Software Foundation. | ||
15 | * | ||
16 | */ | ||
17 | #ifndef _MT7621_CPU_FEATURE_OVERRIDES_H | ||
18 | #define _MT7621_CPU_FEATURE_OVERRIDES_H | ||
19 | |||
20 | #define cpu_has_tlb 1 | ||
21 | #define cpu_has_4kex 1 | ||
22 | #define cpu_has_3k_cache 0 | ||
23 | #define cpu_has_4k_cache 1 | ||
24 | #define cpu_has_tx39_cache 0 | ||
25 | #define cpu_has_sb1_cache 0 | ||
26 | #define cpu_has_fpu 0 | ||
27 | #define cpu_has_32fpr 0 | ||
28 | #define cpu_has_counter 1 | ||
29 | #define cpu_has_watch 1 | ||
30 | #define cpu_has_divec 1 | ||
31 | |||
32 | #define cpu_has_prefetch 1 | ||
33 | #define cpu_has_ejtag 1 | ||
34 | #define cpu_has_llsc 1 | ||
35 | |||
36 | #define cpu_has_mips16 1 | ||
37 | #define cpu_has_mdmx 0 | ||
38 | #define cpu_has_mips3d 0 | ||
39 | #define cpu_has_smartmips 0 | ||
40 | |||
41 | #define cpu_has_mips32r1 1 | ||
42 | #define cpu_has_mips32r2 1 | ||
43 | #define cpu_has_mips64r1 0 | ||
44 | #define cpu_has_mips64r2 0 | ||
45 | |||
46 | #define cpu_has_dsp 1 | ||
47 | #define cpu_has_dsp2 0 | ||
48 | #define cpu_has_mipsmt 1 | ||
49 | |||
50 | #define cpu_has_64bits 0 | ||
51 | #define cpu_has_64bit_zero_reg 0 | ||
52 | #define cpu_has_64bit_gp_regs 0 | ||
53 | #define cpu_has_64bit_addresses 0 | ||
54 | |||
55 | #define cpu_dcache_line_size() 32 | ||
56 | #define cpu_icache_line_size() 32 | ||
57 | |||
58 | #define cpu_has_dc_aliases 0 | ||
59 | #define cpu_has_vtag_icache 0 | ||
60 | |||
61 | #define cpu_has_rixi 0 | ||
62 | #define cpu_has_tlbinv 0 | ||
63 | #define cpu_has_userlocal 1 | ||
64 | |||
65 | #endif /* _MT7621_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 6516e9da5133..b196825a1de9 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h | |||
@@ -243,6 +243,10 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) | |||
243 | #define CM_GCR_BASE_CMDEFTGT_IOCU0 2 | 243 | #define CM_GCR_BASE_CMDEFTGT_IOCU0 2 |
244 | #define CM_GCR_BASE_CMDEFTGT_IOCU1 3 | 244 | #define CM_GCR_BASE_CMDEFTGT_IOCU1 3 |
245 | 245 | ||
246 | /* GCR_RESET_EXT_BASE register fields */ | ||
247 | #define CM_GCR_RESET_EXT_BASE_EVARESET BIT(31) | ||
248 | #define CM_GCR_RESET_EXT_BASE_UEB BIT(30) | ||
249 | |||
246 | /* GCR_ACCESS register fields */ | 250 | /* GCR_ACCESS register fields */ |
247 | #define CM_GCR_ACCESS_ACCESSEN_SHF 0 | 251 | #define CM_GCR_ACCESS_ACCESSEN_SHF 0 |
248 | #define CM_GCR_ACCESS_ACCESSEN_MSK (_ULCAST_(0xff) << 0) | 252 | #define CM_GCR_ACCESS_ACCESSEN_MSK (_ULCAST_(0xff) << 0) |
diff --git a/arch/mips/include/asm/mips-r2-to-r6-emul.h b/arch/mips/include/asm/mips-r2-to-r6-emul.h index 4b89f28047f7..1f6ea8352ca9 100644 --- a/arch/mips/include/asm/mips-r2-to-r6-emul.h +++ b/arch/mips/include/asm/mips-r2-to-r6-emul.h | |||
@@ -52,7 +52,7 @@ do { \ | |||
52 | __this_cpu_inc(mipsr2emustats.M); \ | 52 | __this_cpu_inc(mipsr2emustats.M); \ |
53 | err = __get_user(nir, (u32 __user *)regs->cp0_epc); \ | 53 | err = __get_user(nir, (u32 __user *)regs->cp0_epc); \ |
54 | if (!err) { \ | 54 | if (!err) { \ |
55 | if (nir == BREAK_MATH) \ | 55 | if (nir == BREAK_MATH(0)) \ |
56 | __this_cpu_inc(mipsr2bdemustats.M); \ | 56 | __this_cpu_inc(mipsr2bdemustats.M); \ |
57 | } \ | 57 | } \ |
58 | preempt_enable(); \ | 58 | preempt_enable(); \ |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index e43aca183c99..3ad19ad04d8a 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -394,6 +394,8 @@ | |||
394 | #define CAUSEF_IV (_ULCAST_(1) << 23) | 394 | #define CAUSEF_IV (_ULCAST_(1) << 23) |
395 | #define CAUSEB_PCI 26 | 395 | #define CAUSEB_PCI 26 |
396 | #define CAUSEF_PCI (_ULCAST_(1) << 26) | 396 | #define CAUSEF_PCI (_ULCAST_(1) << 26) |
397 | #define CAUSEB_DC 27 | ||
398 | #define CAUSEF_DC (_ULCAST_(1) << 27) | ||
397 | #define CAUSEB_CE 28 | 399 | #define CAUSEB_CE 28 |
398 | #define CAUSEF_CE (_ULCAST_(3) << 28) | 400 | #define CAUSEF_CE (_ULCAST_(3) << 28) |
399 | #define CAUSEB_TI 30 | 401 | #define CAUSEB_TI 30 |
@@ -402,6 +404,38 @@ | |||
402 | #define CAUSEF_BD (_ULCAST_(1) << 31) | 404 | #define CAUSEF_BD (_ULCAST_(1) << 31) |
403 | 405 | ||
404 | /* | 406 | /* |
407 | * Cause.ExcCode trap codes. | ||
408 | */ | ||
409 | #define EXCCODE_INT 0 /* Interrupt pending */ | ||
410 | #define EXCCODE_MOD 1 /* TLB modified fault */ | ||
411 | #define EXCCODE_TLBL 2 /* TLB miss on load or ifetch */ | ||
412 | #define EXCCODE_TLBS 3 /* TLB miss on a store */ | ||
413 | #define EXCCODE_ADEL 4 /* Address error on a load or ifetch */ | ||
414 | #define EXCCODE_ADES 5 /* Address error on a store */ | ||
415 | #define EXCCODE_IBE 6 /* Bus error on an ifetch */ | ||
416 | #define EXCCODE_DBE 7 /* Bus error on a load or store */ | ||
417 | #define EXCCODE_SYS 8 /* System call */ | ||
418 | #define EXCCODE_BP 9 /* Breakpoint */ | ||
419 | #define EXCCODE_RI 10 /* Reserved instruction exception */ | ||
420 | #define EXCCODE_CPU 11 /* Coprocessor unusable */ | ||
421 | #define EXCCODE_OV 12 /* Arithmetic overflow */ | ||
422 | #define EXCCODE_TR 13 /* Trap instruction */ | ||
423 | #define EXCCODE_MSAFPE 14 /* MSA floating point exception */ | ||
424 | #define EXCCODE_FPE 15 /* Floating point exception */ | ||
425 | #define EXCCODE_TLBRI 19 /* TLB Read-Inhibit exception */ | ||
426 | #define EXCCODE_TLBXI 20 /* TLB Execution-Inhibit exception */ | ||
427 | #define EXCCODE_MSADIS 21 /* MSA disabled exception */ | ||
428 | #define EXCCODE_MDMX 22 /* MDMX unusable exception */ | ||
429 | #define EXCCODE_WATCH 23 /* Watch address reference */ | ||
430 | #define EXCCODE_MCHECK 24 /* Machine check */ | ||
431 | #define EXCCODE_THREAD 25 /* Thread exceptions (MT) */ | ||
432 | #define EXCCODE_DSPDIS 26 /* DSP disabled exception */ | ||
433 | #define EXCCODE_GE 27 /* Virtualized guest exception (VZ) */ | ||
434 | |||
435 | /* Implementation specific trap codes used by MIPS cores */ | ||
436 | #define MIPS_EXCCODE_TLBPAR 16 /* TLB parity error exception */ | ||
437 | |||
438 | /* | ||
405 | * Bits in the coprocessor 0 config register. | 439 | * Bits in the coprocessor 0 config register. |
406 | */ | 440 | */ |
407 | /* Generic bits. */ | 441 | /* Generic bits. */ |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 2046c0230224..21ed7150fec3 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -33,7 +33,7 @@ | |||
33 | #define PAGE_SHIFT 16 | 33 | #define PAGE_SHIFT 16 |
34 | #endif | 34 | #endif |
35 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) | 35 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) |
36 | #define PAGE_MASK (~(PAGE_SIZE - 1)) | 36 | #define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * This is used for calculating the real page sizes | 39 | * This is used for calculating the real page sizes |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 6995b4a02e23..9a4fe0133ff1 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -353,7 +353,7 @@ static inline pte_t pte_mkdirty(pte_t pte) | |||
353 | static inline pte_t pte_mkyoung(pte_t pte) | 353 | static inline pte_t pte_mkyoung(pte_t pte) |
354 | { | 354 | { |
355 | pte_val(pte) |= _PAGE_ACCESSED; | 355 | pte_val(pte) |= _PAGE_ACCESSED; |
356 | #ifdef CONFIG_CPU_MIPSR2 | 356 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
357 | if (!(pte_val(pte) & _PAGE_NO_READ)) | 357 | if (!(pte_val(pte) & _PAGE_NO_READ)) |
358 | pte_val(pte) |= _PAGE_SILENT_READ; | 358 | pte_val(pte) |= _PAGE_SILENT_READ; |
359 | else | 359 | else |
@@ -542,7 +542,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) | |||
542 | { | 542 | { |
543 | pmd_val(pmd) |= _PAGE_ACCESSED; | 543 | pmd_val(pmd) |= _PAGE_ACCESSED; |
544 | 544 | ||
545 | #ifdef CONFIG_CPU_MIPSR2 | 545 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
546 | if (!(pmd_val(pmd) & _PAGE_NO_READ)) | 546 | if (!(pmd_val(pmd) & _PAGE_NO_READ)) |
547 | pmd_val(pmd) |= _PAGE_SILENT_READ; | 547 | pmd_val(pmd) |= _PAGE_SILENT_READ; |
548 | else | 548 | else |
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index 9b44d5a816fa..ddea53e3a9bb 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h | |||
@@ -116,7 +116,8 @@ enum cop_op { | |||
116 | dmtc_op = 0x05, ctc_op = 0x06, | 116 | dmtc_op = 0x05, ctc_op = 0x06, |
117 | mthc0_op = 0x06, mthc_op = 0x07, | 117 | mthc0_op = 0x06, mthc_op = 0x07, |
118 | bc_op = 0x08, bc1eqz_op = 0x09, | 118 | bc_op = 0x08, bc1eqz_op = 0x09, |
119 | bc1nez_op = 0x0d, cop_op = 0x10, | 119 | mfmc0_op = 0x0b, bc1nez_op = 0x0d, |
120 | wrpgpr_op = 0x0e, cop_op = 0x10, | ||
120 | copm_op = 0x18 | 121 | copm_op = 0x18 |
121 | }; | 122 | }; |
122 | 123 | ||
@@ -529,7 +530,7 @@ enum MIPS6e_i8_func { | |||
529 | }; | 530 | }; |
530 | 531 | ||
531 | /* | 532 | /* |
532 | * (microMIPS & MIPS16e) NOP instruction. | 533 | * (microMIPS) NOP instruction. |
533 | */ | 534 | */ |
534 | #define MM_NOP16 0x0c00 | 535 | #define MM_NOP16 0x0c00 |
535 | 536 | ||
@@ -679,7 +680,7 @@ struct fp0_format { /* FPU multiply and add format (MIPS32) */ | |||
679 | ;)))))) | 680 | ;)))))) |
680 | }; | 681 | }; |
681 | 682 | ||
682 | struct mm_fp0_format { /* FPU multipy and add format (microMIPS) */ | 683 | struct mm_fp0_format { /* FPU multiply and add format (microMIPS) */ |
683 | __BITFIELD_FIELD(unsigned int opcode : 6, | 684 | __BITFIELD_FIELD(unsigned int opcode : 6, |
684 | __BITFIELD_FIELD(unsigned int ft : 5, | 685 | __BITFIELD_FIELD(unsigned int ft : 5, |
685 | __BITFIELD_FIELD(unsigned int fs : 5, | 686 | __BITFIELD_FIELD(unsigned int fs : 5, |
@@ -799,6 +800,13 @@ struct mm_x_format { /* Scaled indexed load format (microMIPS) */ | |||
799 | ;))))) | 800 | ;))))) |
800 | }; | 801 | }; |
801 | 802 | ||
803 | struct mm_a_format { /* ADDIUPC format (microMIPS) */ | ||
804 | __BITFIELD_FIELD(unsigned int opcode : 6, | ||
805 | __BITFIELD_FIELD(unsigned int rs : 3, | ||
806 | __BITFIELD_FIELD(signed int simmediate : 23, | ||
807 | ;))) | ||
808 | }; | ||
809 | |||
802 | /* | 810 | /* |
803 | * microMIPS instruction formats (16-bit length) | 811 | * microMIPS instruction formats (16-bit length) |
804 | */ | 812 | */ |
@@ -940,6 +948,7 @@ union mips_instruction { | |||
940 | struct mm_i_format mm_i_format; | 948 | struct mm_i_format mm_i_format; |
941 | struct mm_m_format mm_m_format; | 949 | struct mm_m_format mm_m_format; |
942 | struct mm_x_format mm_x_format; | 950 | struct mm_x_format mm_x_format; |
951 | struct mm_a_format mm_a_format; | ||
943 | struct mm_b0_format mm_b0_format; | 952 | struct mm_b0_format mm_b0_format; |
944 | struct mm_b1_format mm_b1_format; | 953 | struct mm_b1_format mm_b1_format; |
945 | struct mm16_m_format mm16_m_format ; | 954 | struct mm16_m_format mm16_m_format ; |
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 09f4034f239f..6392dbe504fb 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c | |||
@@ -190,7 +190,7 @@ static inline void check_daddi(void) | |||
190 | printk("Checking for the daddi bug... "); | 190 | printk("Checking for the daddi bug... "); |
191 | 191 | ||
192 | local_irq_save(flags); | 192 | local_irq_save(flags); |
193 | handler = set_except_vector(12, handle_daddi_ov); | 193 | handler = set_except_vector(EXCCODE_OV, handle_daddi_ov); |
194 | /* | 194 | /* |
195 | * The following code fails to trigger an overflow exception | 195 | * The following code fails to trigger an overflow exception |
196 | * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or | 196 | * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or |
@@ -214,7 +214,7 @@ static inline void check_daddi(void) | |||
214 | ".set pop" | 214 | ".set pop" |
215 | : "=r" (v), "=&r" (tmp) | 215 | : "=r" (v), "=&r" (tmp) |
216 | : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); | 216 | : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); |
217 | set_except_vector(12, handler); | 217 | set_except_vector(EXCCODE_OV, handler); |
218 | local_irq_restore(flags); | 218 | local_irq_restore(flags); |
219 | 219 | ||
220 | if (daddi_ov) { | 220 | if (daddi_ov) { |
@@ -225,14 +225,14 @@ static inline void check_daddi(void) | |||
225 | printk("yes, workaround... "); | 225 | printk("yes, workaround... "); |
226 | 226 | ||
227 | local_irq_save(flags); | 227 | local_irq_save(flags); |
228 | handler = set_except_vector(12, handle_daddi_ov); | 228 | handler = set_except_vector(EXCCODE_OV, handle_daddi_ov); |
229 | asm volatile( | 229 | asm volatile( |
230 | "addiu %1, $0, %2\n\t" | 230 | "addiu %1, $0, %2\n\t" |
231 | "dsrl %1, %1, 1\n\t" | 231 | "dsrl %1, %1, 1\n\t" |
232 | "daddi %0, %1, %3" | 232 | "daddi %0, %1, %3" |
233 | : "=r" (v), "=&r" (tmp) | 233 | : "=r" (v), "=&r" (tmp) |
234 | : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); | 234 | : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); |
235 | set_except_vector(12, handler); | 235 | set_except_vector(EXCCODE_OV, handler); |
236 | local_irq_restore(flags); | 236 | local_irq_restore(flags); |
237 | 237 | ||
238 | if (daddi_ov) { | 238 | if (daddi_ov) { |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 6b9064499bd3..b725b713b9f8 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -99,6 +99,161 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes | ||
103 | * supported by FPU hardware. | ||
104 | */ | ||
105 | static void cpu_set_fpu_2008(struct cpuinfo_mips *c) | ||
106 | { | ||
107 | if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | | ||
108 | MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | | ||
109 | MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { | ||
110 | unsigned long sr, fir, fcsr, fcsr0, fcsr1; | ||
111 | |||
112 | sr = read_c0_status(); | ||
113 | __enable_fpu(FPU_AS_IS); | ||
114 | |||
115 | fir = read_32bit_cp1_register(CP1_REVISION); | ||
116 | if (fir & MIPS_FPIR_HAS2008) { | ||
117 | fcsr = read_32bit_cp1_register(CP1_STATUS); | ||
118 | |||
119 | fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008); | ||
120 | write_32bit_cp1_register(CP1_STATUS, fcsr0); | ||
121 | fcsr0 = read_32bit_cp1_register(CP1_STATUS); | ||
122 | |||
123 | fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008; | ||
124 | write_32bit_cp1_register(CP1_STATUS, fcsr1); | ||
125 | fcsr1 = read_32bit_cp1_register(CP1_STATUS); | ||
126 | |||
127 | write_32bit_cp1_register(CP1_STATUS, fcsr); | ||
128 | |||
129 | if (!(fcsr0 & FPU_CSR_NAN2008)) | ||
130 | c->options |= MIPS_CPU_NAN_LEGACY; | ||
131 | if (fcsr1 & FPU_CSR_NAN2008) | ||
132 | c->options |= MIPS_CPU_NAN_2008; | ||
133 | |||
134 | if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008) | ||
135 | c->fpu_msk31 &= ~FPU_CSR_ABS2008; | ||
136 | else | ||
137 | c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008; | ||
138 | |||
139 | if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008) | ||
140 | c->fpu_msk31 &= ~FPU_CSR_NAN2008; | ||
141 | else | ||
142 | c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008; | ||
143 | } else { | ||
144 | c->options |= MIPS_CPU_NAN_LEGACY; | ||
145 | } | ||
146 | |||
147 | write_c0_status(sr); | ||
148 | } else { | ||
149 | c->options |= MIPS_CPU_NAN_LEGACY; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * IEEE 754 conformance mode to use. Affects the NaN encoding and the | ||
155 | * ABS.fmt/NEG.fmt execution mode. | ||
156 | */ | ||
157 | static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT; | ||
158 | |||
159 | /* | ||
160 | * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes | ||
161 | * to support by the FPU emulator according to the IEEE 754 conformance | ||
162 | * mode selected. Note that "relaxed" straps the emulator so that it | ||
163 | * allows 2008-NaN binaries even for legacy processors. | ||
164 | */ | ||
165 | static void cpu_set_nofpu_2008(struct cpuinfo_mips *c) | ||
166 | { | ||
167 | c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY); | ||
168 | c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008); | ||
169 | c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008); | ||
170 | |||
171 | switch (ieee754) { | ||
172 | case STRICT: | ||
173 | if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | | ||
174 | MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | | ||
175 | MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { | ||
176 | c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY; | ||
177 | } else { | ||
178 | c->options |= MIPS_CPU_NAN_LEGACY; | ||
179 | c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; | ||
180 | } | ||
181 | break; | ||
182 | case LEGACY: | ||
183 | c->options |= MIPS_CPU_NAN_LEGACY; | ||
184 | c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; | ||
185 | break; | ||
186 | case STD2008: | ||
187 | c->options |= MIPS_CPU_NAN_2008; | ||
188 | c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; | ||
189 | c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; | ||
190 | break; | ||
191 | case RELAXED: | ||
192 | c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY; | ||
193 | break; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode | ||
199 | * according to the "ieee754=" parameter. | ||
200 | */ | ||
201 | static void cpu_set_nan_2008(struct cpuinfo_mips *c) | ||
202 | { | ||
203 | switch (ieee754) { | ||
204 | case STRICT: | ||
205 | mips_use_nan_legacy = !!cpu_has_nan_legacy; | ||
206 | mips_use_nan_2008 = !!cpu_has_nan_2008; | ||
207 | break; | ||
208 | case LEGACY: | ||
209 | mips_use_nan_legacy = !!cpu_has_nan_legacy; | ||
210 | mips_use_nan_2008 = !cpu_has_nan_legacy; | ||
211 | break; | ||
212 | case STD2008: | ||
213 | mips_use_nan_legacy = !cpu_has_nan_2008; | ||
214 | mips_use_nan_2008 = !!cpu_has_nan_2008; | ||
215 | break; | ||
216 | case RELAXED: | ||
217 | mips_use_nan_legacy = true; | ||
218 | mips_use_nan_2008 = true; | ||
219 | break; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override | ||
225 | * settings: | ||
226 | * | ||
227 | * strict: accept binaries that request a NaN encoding supported by the FPU | ||
228 | * legacy: only accept legacy-NaN binaries | ||
229 | * 2008: only accept 2008-NaN binaries | ||
230 | * relaxed: accept any binaries regardless of whether supported by the FPU | ||
231 | */ | ||
232 | static int __init ieee754_setup(char *s) | ||
233 | { | ||
234 | if (!s) | ||
235 | return -1; | ||
236 | else if (!strcmp(s, "strict")) | ||
237 | ieee754 = STRICT; | ||
238 | else if (!strcmp(s, "legacy")) | ||
239 | ieee754 = LEGACY; | ||
240 | else if (!strcmp(s, "2008")) | ||
241 | ieee754 = STD2008; | ||
242 | else if (!strcmp(s, "relaxed")) | ||
243 | ieee754 = RELAXED; | ||
244 | else | ||
245 | return -1; | ||
246 | |||
247 | if (!(boot_cpu_data.options & MIPS_CPU_FPU)) | ||
248 | cpu_set_nofpu_2008(&boot_cpu_data); | ||
249 | cpu_set_nan_2008(&boot_cpu_data); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | early_param("ieee754", ieee754_setup); | ||
255 | |||
256 | /* | ||
102 | * Set the FIR feature flags for the FPU emulator. | 257 | * Set the FIR feature flags for the FPU emulator. |
103 | */ | 258 | */ |
104 | static void cpu_set_nofpu_id(struct cpuinfo_mips *c) | 259 | static void cpu_set_nofpu_id(struct cpuinfo_mips *c) |
@@ -113,6 +268,8 @@ static void cpu_set_nofpu_id(struct cpuinfo_mips *c) | |||
113 | if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | | 268 | if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | |
114 | MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) | 269 | MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) |
115 | value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W; | 270 | value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W; |
271 | if (c->options & MIPS_CPU_NAN_2008) | ||
272 | value |= MIPS_FPIR_HAS2008; | ||
116 | c->fpu_id = value; | 273 | c->fpu_id = value; |
117 | } | 274 | } |
118 | 275 | ||
@@ -137,6 +294,8 @@ static void cpu_set_fpu_opts(struct cpuinfo_mips *c) | |||
137 | } | 294 | } |
138 | 295 | ||
139 | cpu_set_fpu_fcsr_mask(c); | 296 | cpu_set_fpu_fcsr_mask(c); |
297 | cpu_set_fpu_2008(c); | ||
298 | cpu_set_nan_2008(c); | ||
140 | } | 299 | } |
141 | 300 | ||
142 | /* | 301 | /* |
@@ -147,6 +306,8 @@ static void cpu_set_nofpu_opts(struct cpuinfo_mips *c) | |||
147 | c->options &= ~MIPS_CPU_FPU; | 306 | c->options &= ~MIPS_CPU_FPU; |
148 | c->fpu_msk31 = mips_nofpu_msk31; | 307 | c->fpu_msk31 = mips_nofpu_msk31; |
149 | 308 | ||
309 | cpu_set_nofpu_2008(c); | ||
310 | cpu_set_nan_2008(c); | ||
150 | cpu_set_nofpu_id(c); | 311 | cpu_set_nofpu_id(c); |
151 | } | 312 | } |
152 | 313 | ||
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 4a4d9e067c89..c3c234dc0c07 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c | |||
@@ -11,6 +11,12 @@ | |||
11 | #include <linux/elf.h> | 11 | #include <linux/elf.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | 13 | ||
14 | #include <asm/cpu-info.h> | ||
15 | |||
16 | /* Whether to accept legacy-NaN and 2008-NaN user binaries. */ | ||
17 | bool mips_use_nan_legacy; | ||
18 | bool mips_use_nan_2008; | ||
19 | |||
14 | /* FPU modes */ | 20 | /* FPU modes */ |
15 | enum { | 21 | enum { |
16 | FP_FRE, | 22 | FP_FRE, |
@@ -68,15 +74,23 @@ static struct mode_req none_req = { true, true, false, true, true }; | |||
68 | int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, | 74 | int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, |
69 | bool is_interp, struct arch_elf_state *state) | 75 | bool is_interp, struct arch_elf_state *state) |
70 | { | 76 | { |
71 | struct elf32_hdr *ehdr32 = _ehdr; | 77 | union { |
78 | struct elf32_hdr e32; | ||
79 | struct elf64_hdr e64; | ||
80 | } *ehdr = _ehdr; | ||
72 | struct elf32_phdr *phdr32 = _phdr; | 81 | struct elf32_phdr *phdr32 = _phdr; |
73 | struct elf64_phdr *phdr64 = _phdr; | 82 | struct elf64_phdr *phdr64 = _phdr; |
74 | struct mips_elf_abiflags_v0 abiflags; | 83 | struct mips_elf_abiflags_v0 abiflags; |
84 | bool elf32; | ||
85 | u32 flags; | ||
75 | int ret; | 86 | int ret; |
76 | 87 | ||
88 | elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32; | ||
89 | flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags; | ||
90 | |||
77 | /* Lets see if this is an O32 ELF */ | 91 | /* Lets see if this is an O32 ELF */ |
78 | if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) { | 92 | if (elf32) { |
79 | if (ehdr32->e_flags & EF_MIPS_FP64) { | 93 | if (flags & EF_MIPS_FP64) { |
80 | /* | 94 | /* |
81 | * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it | 95 | * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it |
82 | * later if needed | 96 | * later if needed |
@@ -120,13 +134,50 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, | |||
120 | return 0; | 134 | return 0; |
121 | } | 135 | } |
122 | 136 | ||
123 | int arch_check_elf(void *_ehdr, bool has_interpreter, | 137 | int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, |
124 | struct arch_elf_state *state) | 138 | struct arch_elf_state *state) |
125 | { | 139 | { |
126 | struct elf32_hdr *ehdr = _ehdr; | 140 | union { |
141 | struct elf32_hdr e32; | ||
142 | struct elf64_hdr e64; | ||
143 | } *ehdr = _ehdr; | ||
144 | union { | ||
145 | struct elf32_hdr e32; | ||
146 | struct elf64_hdr e64; | ||
147 | } *iehdr = _interp_ehdr; | ||
127 | struct mode_req prog_req, interp_req; | 148 | struct mode_req prog_req, interp_req; |
128 | int fp_abi, interp_fp_abi, abi0, abi1, max_abi; | 149 | int fp_abi, interp_fp_abi, abi0, abi1, max_abi; |
129 | bool is_mips64; | 150 | bool elf32; |
151 | u32 flags; | ||
152 | |||
153 | elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32; | ||
154 | flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags; | ||
155 | |||
156 | /* | ||
157 | * Determine the NaN personality, reject the binary if not allowed. | ||
158 | * Also ensure that any interpreter matches the executable. | ||
159 | */ | ||
160 | if (flags & EF_MIPS_NAN2008) { | ||
161 | if (mips_use_nan_2008) | ||
162 | state->nan_2008 = 1; | ||
163 | else | ||
164 | return -ENOEXEC; | ||
165 | } else { | ||
166 | if (mips_use_nan_legacy) | ||
167 | state->nan_2008 = 0; | ||
168 | else | ||
169 | return -ENOEXEC; | ||
170 | } | ||
171 | if (has_interpreter) { | ||
172 | bool ielf32; | ||
173 | u32 iflags; | ||
174 | |||
175 | ielf32 = iehdr->e32.e_ident[EI_CLASS] == ELFCLASS32; | ||
176 | iflags = ielf32 ? iehdr->e32.e_flags : iehdr->e64.e_flags; | ||
177 | |||
178 | if ((flags ^ iflags) & EF_MIPS_NAN2008) | ||
179 | return -ELIBBAD; | ||
180 | } | ||
130 | 181 | ||
131 | if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) | 182 | if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) |
132 | return 0; | 183 | return 0; |
@@ -142,21 +193,18 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, | |||
142 | abi0 = abi1 = fp_abi; | 193 | abi0 = abi1 = fp_abi; |
143 | } | 194 | } |
144 | 195 | ||
145 | is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) || | 196 | if (elf32 && !(flags & EF_MIPS_ABI2)) { |
146 | (ehdr->e_flags & EF_MIPS_ABI2); | 197 | /* Default to a mode capable of running code expecting FR=0 */ |
198 | state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0; | ||
147 | 199 | ||
148 | if (is_mips64) { | 200 | /* Allow all ABIs we know about */ |
201 | max_abi = MIPS_ABI_FP_64A; | ||
202 | } else { | ||
149 | /* MIPS64 code always uses FR=1, thus the default is easy */ | 203 | /* MIPS64 code always uses FR=1, thus the default is easy */ |
150 | state->overall_fp_mode = FP_FR1; | 204 | state->overall_fp_mode = FP_FR1; |
151 | 205 | ||
152 | /* Disallow access to the various FPXX & FP64 ABIs */ | 206 | /* Disallow access to the various FPXX & FP64 ABIs */ |
153 | max_abi = MIPS_ABI_FP_SOFT; | 207 | max_abi = MIPS_ABI_FP_SOFT; |
154 | } else { | ||
155 | /* Default to a mode capable of running code expecting FR=0 */ | ||
156 | state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0; | ||
157 | |||
158 | /* Allow all ABIs we know about */ | ||
159 | max_abi = MIPS_ABI_FP_64A; | ||
160 | } | 208 | } |
161 | 209 | ||
162 | if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) || | 210 | if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) || |
@@ -254,3 +302,27 @@ void mips_set_personality_fp(struct arch_elf_state *state) | |||
254 | BUG(); | 302 | BUG(); |
255 | } | 303 | } |
256 | } | 304 | } |
305 | |||
306 | /* | ||
307 | * Select the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode | ||
308 | * in FCSR according to the ELF NaN personality. | ||
309 | */ | ||
310 | void mips_set_personality_nan(struct arch_elf_state *state) | ||
311 | { | ||
312 | struct cpuinfo_mips *c = &boot_cpu_data; | ||
313 | struct task_struct *t = current; | ||
314 | |||
315 | t->thread.fpu.fcr31 = c->fpu_csr31; | ||
316 | switch (state->nan_2008) { | ||
317 | case 0: | ||
318 | break; | ||
319 | case 1: | ||
320 | if (!(c->fpu_msk31 & FPU_CSR_NAN2008)) | ||
321 | t->thread.fpu.fcr31 |= FPU_CSR_NAN2008; | ||
322 | if (!(c->fpu_msk31 & FPU_CSR_ABS2008)) | ||
323 | t->thread.fpu.fcr31 |= FPU_CSR_ABS2008; | ||
324 | break; | ||
325 | default: | ||
326 | BUG(); | ||
327 | } | ||
328 | } | ||
diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c index c6854d9df926..705be43c3533 100644 --- a/arch/mips/kernel/gpio_txx9.c +++ b/arch/mips/kernel/gpio_txx9.c | |||
@@ -21,7 +21,7 @@ static struct txx9_pio_reg __iomem *txx9_pioptr; | |||
21 | 21 | ||
22 | static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset) | 22 | static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset) |
23 | { | 23 | { |
24 | return __raw_readl(&txx9_pioptr->din) & (1 << offset); | 24 | return !!(__raw_readl(&txx9_pioptr->din) & (1 << offset)); |
25 | } | 25 | } |
26 | 26 | ||
27 | static void txx9_gpio_set_raw(unsigned int offset, int value) | 27 | static void txx9_gpio_set_raw(unsigned int offset, int value) |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 4f0ac78d17f1..a5279b2f3198 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -548,9 +548,6 @@ static const struct pt_regs_offset regoffset_table[] = { | |||
548 | REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr), | 548 | REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr), |
549 | REG_OFFSET_NAME(c0_cause, cp0_cause), | 549 | REG_OFFSET_NAME(c0_cause, cp0_cause), |
550 | REG_OFFSET_NAME(c0_epc, cp0_epc), | 550 | REG_OFFSET_NAME(c0_epc, cp0_epc), |
551 | #ifdef CONFIG_MIPS_MT_SMTC | ||
552 | REG_OFFSET_NAME(c0_tcstatus, cp0_tcstatus), | ||
553 | #endif | ||
554 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | 551 | #ifdef CONFIG_CPU_CAVIUM_OCTEON |
555 | REG_OFFSET_NAME(mpl0, mpl[0]), | 552 | REG_OFFSET_NAME(mpl0, mpl[0]), |
556 | REG_OFFSET_NAME(mpl1, mpl[1]), | 553 | REG_OFFSET_NAME(mpl1, mpl[1]), |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 66aac55df349..569a7d5242dd 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -623,7 +623,7 @@ static void __init request_crashkernel(struct resource *res) | |||
623 | 623 | ||
624 | #define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) | 624 | #define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) |
625 | #define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) | 625 | #define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) |
626 | #define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND) | 626 | #define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) |
627 | 627 | ||
628 | static void __init arch_mem_init(char **cmdline_p) | 628 | static void __init arch_mem_init(char **cmdline_p) |
629 | { | 629 | { |
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index e04c8057b882..2ad4e4c96d61 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c | |||
@@ -202,6 +202,9 @@ static void boot_core(unsigned core) | |||
202 | /* Ensure its coherency is disabled */ | 202 | /* Ensure its coherency is disabled */ |
203 | write_gcr_co_coherence(0); | 203 | write_gcr_co_coherence(0); |
204 | 204 | ||
205 | /* Start it with the legacy memory map and exception base */ | ||
206 | write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB); | ||
207 | |||
205 | /* Ensure the core can access the GCRs */ | 208 | /* Ensure the core can access the GCRs */ |
206 | access = read_gcr_access(); | 209 | access = read_gcr_access(); |
207 | access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core); | 210 | access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core); |
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 2242bdd4370e..4472a7f98577 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c | |||
@@ -17,35 +17,23 @@ | |||
17 | #include <asm/barrier.h> | 17 | #include <asm/barrier.h> |
18 | #include <asm/mipsregs.h> | 18 | #include <asm/mipsregs.h> |
19 | 19 | ||
20 | static atomic_t count_start_flag = ATOMIC_INIT(0); | 20 | static unsigned int initcount = 0; |
21 | static atomic_t count_count_start = ATOMIC_INIT(0); | 21 | static atomic_t count_count_start = ATOMIC_INIT(0); |
22 | static atomic_t count_count_stop = ATOMIC_INIT(0); | 22 | static atomic_t count_count_stop = ATOMIC_INIT(0); |
23 | static atomic_t count_reference = ATOMIC_INIT(0); | ||
24 | 23 | ||
25 | #define COUNTON 100 | 24 | #define COUNTON 100 |
26 | #define NR_LOOPS 5 | 25 | #define NR_LOOPS 3 |
27 | 26 | ||
28 | void synchronise_count_master(int cpu) | 27 | void synchronise_count_master(int cpu) |
29 | { | 28 | { |
30 | int i; | 29 | int i; |
31 | unsigned long flags; | 30 | unsigned long flags; |
32 | unsigned int initcount; | ||
33 | 31 | ||
34 | printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu); | 32 | printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu); |
35 | 33 | ||
36 | local_irq_save(flags); | 34 | local_irq_save(flags); |
37 | 35 | ||
38 | /* | 36 | /* |
39 | * Notify the slaves that it's time to start | ||
40 | */ | ||
41 | atomic_set(&count_reference, read_c0_count()); | ||
42 | atomic_set(&count_start_flag, cpu); | ||
43 | smp_wmb(); | ||
44 | |||
45 | /* Count will be initialised to current timer for all CPU's */ | ||
46 | initcount = read_c0_count(); | ||
47 | |||
48 | /* | ||
49 | * We loop a few times to get a primed instruction cache, | 37 | * We loop a few times to get a primed instruction cache, |
50 | * then the last pass is more or less synchronised and | 38 | * then the last pass is more or less synchronised and |
51 | * the master and slaves each set their cycle counters to a known | 39 | * the master and slaves each set their cycle counters to a known |
@@ -63,9 +51,13 @@ void synchronise_count_master(int cpu) | |||
63 | atomic_set(&count_count_stop, 0); | 51 | atomic_set(&count_count_stop, 0); |
64 | smp_wmb(); | 52 | smp_wmb(); |
65 | 53 | ||
66 | /* this lets the slaves write their count register */ | 54 | /* Let the slave writes its count register */ |
67 | atomic_inc(&count_count_start); | 55 | atomic_inc(&count_count_start); |
68 | 56 | ||
57 | /* Count will be initialised to current timer */ | ||
58 | if (i == 1) | ||
59 | initcount = read_c0_count(); | ||
60 | |||
69 | /* | 61 | /* |
70 | * Everyone initialises count in the last loop: | 62 | * Everyone initialises count in the last loop: |
71 | */ | 63 | */ |
@@ -73,7 +65,7 @@ void synchronise_count_master(int cpu) | |||
73 | write_c0_count(initcount); | 65 | write_c0_count(initcount); |
74 | 66 | ||
75 | /* | 67 | /* |
76 | * Wait for all slaves to leave the synchronization point: | 68 | * Wait for slave to leave the synchronization point: |
77 | */ | 69 | */ |
78 | while (atomic_read(&count_count_stop) != 1) | 70 | while (atomic_read(&count_count_stop) != 1) |
79 | mb(); | 71 | mb(); |
@@ -83,7 +75,6 @@ void synchronise_count_master(int cpu) | |||
83 | } | 75 | } |
84 | /* Arrange for an interrupt in a short while */ | 76 | /* Arrange for an interrupt in a short while */ |
85 | write_c0_compare(read_c0_count() + COUNTON); | 77 | write_c0_compare(read_c0_count() + COUNTON); |
86 | atomic_set(&count_start_flag, 0); | ||
87 | 78 | ||
88 | local_irq_restore(flags); | 79 | local_irq_restore(flags); |
89 | 80 | ||
@@ -98,19 +89,12 @@ void synchronise_count_master(int cpu) | |||
98 | void synchronise_count_slave(int cpu) | 89 | void synchronise_count_slave(int cpu) |
99 | { | 90 | { |
100 | int i; | 91 | int i; |
101 | unsigned int initcount; | ||
102 | 92 | ||
103 | /* | 93 | /* |
104 | * Not every cpu is online at the time this gets called, | 94 | * Not every cpu is online at the time this gets called, |
105 | * so we first wait for the master to say everyone is ready | 95 | * so we first wait for the master to say everyone is ready |
106 | */ | 96 | */ |
107 | 97 | ||
108 | while (atomic_read(&count_start_flag) != cpu) | ||
109 | mb(); | ||
110 | |||
111 | /* Count will be initialised to next expire for all CPU's */ | ||
112 | initcount = atomic_read(&count_reference); | ||
113 | |||
114 | for (i = 0; i < NR_LOOPS; i++) { | 98 | for (i = 0; i < NR_LOOPS; i++) { |
115 | atomic_inc(&count_count_start); | 99 | atomic_inc(&count_count_start); |
116 | while (atomic_read(&count_count_start) != 2) | 100 | while (atomic_read(&count_count_start) != 2) |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 886cb1976e90..bafcb7ad5c85 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -2250,7 +2250,7 @@ void __init trap_init(void) | |||
2250 | * Only some CPUs have the watch exceptions. | 2250 | * Only some CPUs have the watch exceptions. |
2251 | */ | 2251 | */ |
2252 | if (cpu_has_watch) | 2252 | if (cpu_has_watch) |
2253 | set_except_vector(23, handle_watch); | 2253 | set_except_vector(EXCCODE_WATCH, handle_watch); |
2254 | 2254 | ||
2255 | /* | 2255 | /* |
2256 | * Initialise interrupt handlers | 2256 | * Initialise interrupt handlers |
@@ -2277,27 +2277,27 @@ void __init trap_init(void) | |||
2277 | if (board_be_init) | 2277 | if (board_be_init) |
2278 | board_be_init(); | 2278 | board_be_init(); |
2279 | 2279 | ||
2280 | set_except_vector(0, using_rollback_handler() ? rollback_handle_int | 2280 | set_except_vector(EXCCODE_INT, using_rollback_handler() ? |
2281 | : handle_int); | 2281 | rollback_handle_int : handle_int); |
2282 | set_except_vector(1, handle_tlbm); | 2282 | set_except_vector(EXCCODE_MOD, handle_tlbm); |
2283 | set_except_vector(2, handle_tlbl); | 2283 | set_except_vector(EXCCODE_TLBL, handle_tlbl); |
2284 | set_except_vector(3, handle_tlbs); | 2284 | set_except_vector(EXCCODE_TLBS, handle_tlbs); |
2285 | 2285 | ||
2286 | set_except_vector(4, handle_adel); | 2286 | set_except_vector(EXCCODE_ADEL, handle_adel); |
2287 | set_except_vector(5, handle_ades); | 2287 | set_except_vector(EXCCODE_ADES, handle_ades); |
2288 | 2288 | ||
2289 | set_except_vector(6, handle_ibe); | 2289 | set_except_vector(EXCCODE_IBE, handle_ibe); |
2290 | set_except_vector(7, handle_dbe); | 2290 | set_except_vector(EXCCODE_DBE, handle_dbe); |
2291 | 2291 | ||
2292 | set_except_vector(8, handle_sys); | 2292 | set_except_vector(EXCCODE_SYS, handle_sys); |
2293 | set_except_vector(9, handle_bp); | 2293 | set_except_vector(EXCCODE_BP, handle_bp); |
2294 | set_except_vector(10, rdhwr_noopt ? handle_ri : | 2294 | set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri : |
2295 | (cpu_has_vtag_icache ? | 2295 | (cpu_has_vtag_icache ? |
2296 | handle_ri_rdhwr_vivt : handle_ri_rdhwr)); | 2296 | handle_ri_rdhwr_vivt : handle_ri_rdhwr)); |
2297 | set_except_vector(11, handle_cpu); | 2297 | set_except_vector(EXCCODE_CPU, handle_cpu); |
2298 | set_except_vector(12, handle_ov); | 2298 | set_except_vector(EXCCODE_OV, handle_ov); |
2299 | set_except_vector(13, handle_tr); | 2299 | set_except_vector(EXCCODE_TR, handle_tr); |
2300 | set_except_vector(14, handle_msa_fpe); | 2300 | set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe); |
2301 | 2301 | ||
2302 | if (current_cpu_type() == CPU_R6000 || | 2302 | if (current_cpu_type() == CPU_R6000 || |
2303 | current_cpu_type() == CPU_R6000A) { | 2303 | current_cpu_type() == CPU_R6000A) { |
@@ -2318,25 +2318,25 @@ void __init trap_init(void) | |||
2318 | board_nmi_handler_setup(); | 2318 | board_nmi_handler_setup(); |
2319 | 2319 | ||
2320 | if (cpu_has_fpu && !cpu_has_nofpuex) | 2320 | if (cpu_has_fpu && !cpu_has_nofpuex) |
2321 | set_except_vector(15, handle_fpe); | 2321 | set_except_vector(EXCCODE_FPE, handle_fpe); |
2322 | 2322 | ||
2323 | set_except_vector(16, handle_ftlb); | 2323 | set_except_vector(MIPS_EXCCODE_TLBPAR, handle_ftlb); |
2324 | 2324 | ||
2325 | if (cpu_has_rixiex) { | 2325 | if (cpu_has_rixiex) { |
2326 | set_except_vector(19, tlb_do_page_fault_0); | 2326 | set_except_vector(EXCCODE_TLBRI, tlb_do_page_fault_0); |
2327 | set_except_vector(20, tlb_do_page_fault_0); | 2327 | set_except_vector(EXCCODE_TLBXI, tlb_do_page_fault_0); |
2328 | } | 2328 | } |
2329 | 2329 | ||
2330 | set_except_vector(21, handle_msa); | 2330 | set_except_vector(EXCCODE_MSADIS, handle_msa); |
2331 | set_except_vector(22, handle_mdmx); | 2331 | set_except_vector(EXCCODE_MDMX, handle_mdmx); |
2332 | 2332 | ||
2333 | if (cpu_has_mcheck) | 2333 | if (cpu_has_mcheck) |
2334 | set_except_vector(24, handle_mcheck); | 2334 | set_except_vector(EXCCODE_MCHECK, handle_mcheck); |
2335 | 2335 | ||
2336 | if (cpu_has_mipsmt) | 2336 | if (cpu_has_mipsmt) |
2337 | set_except_vector(25, handle_mt); | 2337 | set_except_vector(EXCCODE_THREAD, handle_mt); |
2338 | 2338 | ||
2339 | set_except_vector(26, handle_dsp); | 2339 | set_except_vector(EXCCODE_DSPDIS, handle_dsp); |
2340 | 2340 | ||
2341 | if (board_cache_error_setup) | 2341 | if (board_cache_error_setup) |
2342 | board_cache_error_setup(); | 2342 | board_cache_error_setup(); |
diff --git a/arch/mips/kvm/callback.c b/arch/mips/kvm/callback.c index 313c2e37b978..d88aa2173fb0 100644 --- a/arch/mips/kvm/callback.c +++ b/arch/mips/kvm/callback.c | |||
@@ -11,4 +11,4 @@ | |||
11 | #include <linux/kvm_host.h> | 11 | #include <linux/kvm_host.h> |
12 | 12 | ||
13 | struct kvm_mips_callbacks *kvm_mips_callbacks; | 13 | struct kvm_mips_callbacks *kvm_mips_callbacks; |
14 | EXPORT_SYMBOL(kvm_mips_callbacks); | 14 | EXPORT_SYMBOL_GPL(kvm_mips_callbacks); |
diff --git a/arch/mips/kvm/dyntrans.c b/arch/mips/kvm/dyntrans.c index 521121bdebff..f1527a465c1b 100644 --- a/arch/mips/kvm/dyntrans.c +++ b/arch/mips/kvm/dyntrans.c | |||
@@ -86,10 +86,8 @@ int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) | |||
86 | } else { | 86 | } else { |
87 | mfc0_inst = LW_TEMPLATE; | 87 | mfc0_inst = LW_TEMPLATE; |
88 | mfc0_inst |= ((rt & 0x1f) << 16); | 88 | mfc0_inst |= ((rt & 0x1f) << 16); |
89 | mfc0_inst |= | 89 | mfc0_inst |= offsetof(struct kvm_mips_commpage, |
90 | offsetof(struct mips_coproc, | 90 | cop0.reg[rd][sel]); |
91 | reg[rd][sel]) + offsetof(struct kvm_mips_commpage, | ||
92 | cop0); | ||
93 | } | 91 | } |
94 | 92 | ||
95 | if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) { | 93 | if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) { |
@@ -123,9 +121,7 @@ int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) | |||
123 | sel = inst & 0x7; | 121 | sel = inst & 0x7; |
124 | 122 | ||
125 | mtc0_inst |= ((rt & 0x1f) << 16); | 123 | mtc0_inst |= ((rt & 0x1f) << 16); |
126 | mtc0_inst |= | 124 | mtc0_inst |= offsetof(struct kvm_mips_commpage, cop0.reg[rd][sel]); |
127 | offsetof(struct mips_coproc, | ||
128 | reg[rd][sel]) + offsetof(struct kvm_mips_commpage, cop0); | ||
129 | 125 | ||
130 | if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) { | 126 | if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) { |
131 | kseg0_opc = | 127 | kseg0_opc = |
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index 1b675c7ce89f..b37954cc880d 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/random.h> | 20 | #include <linux/random.h> |
21 | #include <asm/page.h> | 21 | #include <asm/page.h> |
22 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
23 | #include <asm/cacheops.h> | ||
23 | #include <asm/cpu-info.h> | 24 | #include <asm/cpu-info.h> |
24 | #include <asm/mmu_context.h> | 25 | #include <asm/mmu_context.h> |
25 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
@@ -29,7 +30,6 @@ | |||
29 | #include <asm/r4kcache.h> | 30 | #include <asm/r4kcache.h> |
30 | #define CONFIG_MIPS_MT | 31 | #define CONFIG_MIPS_MT |
31 | 32 | ||
32 | #include "opcode.h" | ||
33 | #include "interrupt.h" | 33 | #include "interrupt.h" |
34 | #include "commpage.h" | 34 | #include "commpage.h" |
35 | 35 | ||
@@ -1239,21 +1239,20 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, | |||
1239 | er = EMULATE_FAIL; | 1239 | er = EMULATE_FAIL; |
1240 | break; | 1240 | break; |
1241 | 1241 | ||
1242 | case mfmcz_op: | 1242 | case mfmc0_op: |
1243 | #ifdef KVM_MIPS_DEBUG_COP0_COUNTERS | 1243 | #ifdef KVM_MIPS_DEBUG_COP0_COUNTERS |
1244 | cop0->stat[MIPS_CP0_STATUS][0]++; | 1244 | cop0->stat[MIPS_CP0_STATUS][0]++; |
1245 | #endif | 1245 | #endif |
1246 | if (rt != 0) { | 1246 | if (rt != 0) |
1247 | vcpu->arch.gprs[rt] = | 1247 | vcpu->arch.gprs[rt] = |
1248 | kvm_read_c0_guest_status(cop0); | 1248 | kvm_read_c0_guest_status(cop0); |
1249 | } | ||
1250 | /* EI */ | 1249 | /* EI */ |
1251 | if (inst & 0x20) { | 1250 | if (inst & 0x20) { |
1252 | kvm_debug("[%#lx] mfmcz_op: EI\n", | 1251 | kvm_debug("[%#lx] mfmc0_op: EI\n", |
1253 | vcpu->arch.pc); | 1252 | vcpu->arch.pc); |
1254 | kvm_set_c0_guest_status(cop0, ST0_IE); | 1253 | kvm_set_c0_guest_status(cop0, ST0_IE); |
1255 | } else { | 1254 | } else { |
1256 | kvm_debug("[%#lx] mfmcz_op: DI\n", | 1255 | kvm_debug("[%#lx] mfmc0_op: DI\n", |
1257 | vcpu->arch.pc); | 1256 | vcpu->arch.pc); |
1258 | kvm_clear_c0_guest_status(cop0, ST0_IE); | 1257 | kvm_clear_c0_guest_status(cop0, ST0_IE); |
1259 | } | 1258 | } |
@@ -1545,19 +1544,6 @@ int kvm_mips_sync_icache(unsigned long va, struct kvm_vcpu *vcpu) | |||
1545 | return 0; | 1544 | return 0; |
1546 | } | 1545 | } |
1547 | 1546 | ||
1548 | #define MIPS_CACHE_OP_INDEX_INV 0x0 | ||
1549 | #define MIPS_CACHE_OP_INDEX_LD_TAG 0x1 | ||
1550 | #define MIPS_CACHE_OP_INDEX_ST_TAG 0x2 | ||
1551 | #define MIPS_CACHE_OP_IMP 0x3 | ||
1552 | #define MIPS_CACHE_OP_HIT_INV 0x4 | ||
1553 | #define MIPS_CACHE_OP_FILL_WB_INV 0x5 | ||
1554 | #define MIPS_CACHE_OP_HIT_HB 0x6 | ||
1555 | #define MIPS_CACHE_OP_FETCH_LOCK 0x7 | ||
1556 | |||
1557 | #define MIPS_CACHE_ICACHE 0x0 | ||
1558 | #define MIPS_CACHE_DCACHE 0x1 | ||
1559 | #define MIPS_CACHE_SEC 0x3 | ||
1560 | |||
1561 | enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, | 1547 | enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, |
1562 | uint32_t cause, | 1548 | uint32_t cause, |
1563 | struct kvm_run *run, | 1549 | struct kvm_run *run, |
@@ -1582,8 +1568,8 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, | |||
1582 | base = (inst >> 21) & 0x1f; | 1568 | base = (inst >> 21) & 0x1f; |
1583 | op_inst = (inst >> 16) & 0x1f; | 1569 | op_inst = (inst >> 16) & 0x1f; |
1584 | offset = (int16_t)inst; | 1570 | offset = (int16_t)inst; |
1585 | cache = (inst >> 16) & 0x3; | 1571 | cache = op_inst & CacheOp_Cache; |
1586 | op = (inst >> 18) & 0x7; | 1572 | op = op_inst & CacheOp_Op; |
1587 | 1573 | ||
1588 | va = arch->gprs[base] + offset; | 1574 | va = arch->gprs[base] + offset; |
1589 | 1575 | ||
@@ -1595,14 +1581,14 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, | |||
1595 | * invalidate the caches entirely by stepping through all the | 1581 | * invalidate the caches entirely by stepping through all the |
1596 | * ways/indexes | 1582 | * ways/indexes |
1597 | */ | 1583 | */ |
1598 | if (op == MIPS_CACHE_OP_INDEX_INV) { | 1584 | if (op == Index_Writeback_Inv) { |
1599 | kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n", | 1585 | kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n", |
1600 | vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base, | 1586 | vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base, |
1601 | arch->gprs[base], offset); | 1587 | arch->gprs[base], offset); |
1602 | 1588 | ||
1603 | if (cache == MIPS_CACHE_DCACHE) | 1589 | if (cache == Cache_D) |
1604 | r4k_blast_dcache(); | 1590 | r4k_blast_dcache(); |
1605 | else if (cache == MIPS_CACHE_ICACHE) | 1591 | else if (cache == Cache_I) |
1606 | r4k_blast_icache(); | 1592 | r4k_blast_icache(); |
1607 | else { | 1593 | else { |
1608 | kvm_err("%s: unsupported CACHE INDEX operation\n", | 1594 | kvm_err("%s: unsupported CACHE INDEX operation\n", |
@@ -1675,9 +1661,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, | |||
1675 | 1661 | ||
1676 | skip_fault: | 1662 | skip_fault: |
1677 | /* XXXKYMA: Only a subset of cache ops are supported, used by Linux */ | 1663 | /* XXXKYMA: Only a subset of cache ops are supported, used by Linux */ |
1678 | if (cache == MIPS_CACHE_DCACHE | 1664 | if (op_inst == Hit_Writeback_Inv_D || op_inst == Hit_Invalidate_D) { |
1679 | && (op == MIPS_CACHE_OP_FILL_WB_INV | ||
1680 | || op == MIPS_CACHE_OP_HIT_INV)) { | ||
1681 | flush_dcache_line(va); | 1665 | flush_dcache_line(va); |
1682 | 1666 | ||
1683 | #ifdef CONFIG_KVM_MIPS_DYN_TRANS | 1667 | #ifdef CONFIG_KVM_MIPS_DYN_TRANS |
@@ -1687,7 +1671,7 @@ skip_fault: | |||
1687 | */ | 1671 | */ |
1688 | kvm_mips_trans_cache_va(inst, opc, vcpu); | 1672 | kvm_mips_trans_cache_va(inst, opc, vcpu); |
1689 | #endif | 1673 | #endif |
1690 | } else if (op == MIPS_CACHE_OP_HIT_INV && cache == MIPS_CACHE_ICACHE) { | 1674 | } else if (op_inst == Hit_Invalidate_I) { |
1691 | flush_dcache_line(va); | 1675 | flush_dcache_line(va); |
1692 | flush_icache_line(va); | 1676 | flush_icache_line(va); |
1693 | 1677 | ||
@@ -1781,7 +1765,7 @@ enum emulation_result kvm_mips_emulate_syscall(unsigned long cause, | |||
1781 | kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc); | 1765 | kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc); |
1782 | 1766 | ||
1783 | kvm_change_c0_guest_cause(cop0, (0xff), | 1767 | kvm_change_c0_guest_cause(cop0, (0xff), |
1784 | (T_SYSCALL << CAUSEB_EXCCODE)); | 1768 | (EXCCODE_SYS << CAUSEB_EXCCODE)); |
1785 | 1769 | ||
1786 | /* Set PC to the exception entry point */ | 1770 | /* Set PC to the exception entry point */ |
1787 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 1771 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
@@ -1828,7 +1812,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_ld(unsigned long cause, | |||
1828 | } | 1812 | } |
1829 | 1813 | ||
1830 | kvm_change_c0_guest_cause(cop0, (0xff), | 1814 | kvm_change_c0_guest_cause(cop0, (0xff), |
1831 | (T_TLB_LD_MISS << CAUSEB_EXCCODE)); | 1815 | (EXCCODE_TLBL << CAUSEB_EXCCODE)); |
1832 | 1816 | ||
1833 | /* setup badvaddr, context and entryhi registers for the guest */ | 1817 | /* setup badvaddr, context and entryhi registers for the guest */ |
1834 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); | 1818 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); |
@@ -1874,7 +1858,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_ld(unsigned long cause, | |||
1874 | } | 1858 | } |
1875 | 1859 | ||
1876 | kvm_change_c0_guest_cause(cop0, (0xff), | 1860 | kvm_change_c0_guest_cause(cop0, (0xff), |
1877 | (T_TLB_LD_MISS << CAUSEB_EXCCODE)); | 1861 | (EXCCODE_TLBL << CAUSEB_EXCCODE)); |
1878 | 1862 | ||
1879 | /* setup badvaddr, context and entryhi registers for the guest */ | 1863 | /* setup badvaddr, context and entryhi registers for the guest */ |
1880 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); | 1864 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); |
@@ -1918,7 +1902,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_st(unsigned long cause, | |||
1918 | } | 1902 | } |
1919 | 1903 | ||
1920 | kvm_change_c0_guest_cause(cop0, (0xff), | 1904 | kvm_change_c0_guest_cause(cop0, (0xff), |
1921 | (T_TLB_ST_MISS << CAUSEB_EXCCODE)); | 1905 | (EXCCODE_TLBS << CAUSEB_EXCCODE)); |
1922 | 1906 | ||
1923 | /* setup badvaddr, context and entryhi registers for the guest */ | 1907 | /* setup badvaddr, context and entryhi registers for the guest */ |
1924 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); | 1908 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); |
@@ -1962,7 +1946,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_st(unsigned long cause, | |||
1962 | } | 1946 | } |
1963 | 1947 | ||
1964 | kvm_change_c0_guest_cause(cop0, (0xff), | 1948 | kvm_change_c0_guest_cause(cop0, (0xff), |
1965 | (T_TLB_ST_MISS << CAUSEB_EXCCODE)); | 1949 | (EXCCODE_TLBS << CAUSEB_EXCCODE)); |
1966 | 1950 | ||
1967 | /* setup badvaddr, context and entryhi registers for the guest */ | 1951 | /* setup badvaddr, context and entryhi registers for the guest */ |
1968 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); | 1952 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); |
@@ -2033,7 +2017,8 @@ enum emulation_result kvm_mips_emulate_tlbmod(unsigned long cause, | |||
2033 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2017 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
2034 | } | 2018 | } |
2035 | 2019 | ||
2036 | kvm_change_c0_guest_cause(cop0, (0xff), (T_TLB_MOD << CAUSEB_EXCCODE)); | 2020 | kvm_change_c0_guest_cause(cop0, (0xff), |
2021 | (EXCCODE_MOD << CAUSEB_EXCCODE)); | ||
2037 | 2022 | ||
2038 | /* setup badvaddr, context and entryhi registers for the guest */ | 2023 | /* setup badvaddr, context and entryhi registers for the guest */ |
2039 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); | 2024 | kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr); |
@@ -2068,7 +2053,7 @@ enum emulation_result kvm_mips_emulate_fpu_exc(unsigned long cause, | |||
2068 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2053 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
2069 | 2054 | ||
2070 | kvm_change_c0_guest_cause(cop0, (0xff), | 2055 | kvm_change_c0_guest_cause(cop0, (0xff), |
2071 | (T_COP_UNUSABLE << CAUSEB_EXCCODE)); | 2056 | (EXCCODE_CPU << CAUSEB_EXCCODE)); |
2072 | kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE)); | 2057 | kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE)); |
2073 | 2058 | ||
2074 | return EMULATE_DONE; | 2059 | return EMULATE_DONE; |
@@ -2096,7 +2081,7 @@ enum emulation_result kvm_mips_emulate_ri_exc(unsigned long cause, | |||
2096 | kvm_debug("Delivering RI @ pc %#lx\n", arch->pc); | 2081 | kvm_debug("Delivering RI @ pc %#lx\n", arch->pc); |
2097 | 2082 | ||
2098 | kvm_change_c0_guest_cause(cop0, (0xff), | 2083 | kvm_change_c0_guest_cause(cop0, (0xff), |
2099 | (T_RES_INST << CAUSEB_EXCCODE)); | 2084 | (EXCCODE_RI << CAUSEB_EXCCODE)); |
2100 | 2085 | ||
2101 | /* Set PC to the exception entry point */ | 2086 | /* Set PC to the exception entry point */ |
2102 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2087 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
@@ -2131,7 +2116,7 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause, | |||
2131 | kvm_debug("Delivering BP @ pc %#lx\n", arch->pc); | 2116 | kvm_debug("Delivering BP @ pc %#lx\n", arch->pc); |
2132 | 2117 | ||
2133 | kvm_change_c0_guest_cause(cop0, (0xff), | 2118 | kvm_change_c0_guest_cause(cop0, (0xff), |
2134 | (T_BREAK << CAUSEB_EXCCODE)); | 2119 | (EXCCODE_BP << CAUSEB_EXCCODE)); |
2135 | 2120 | ||
2136 | /* Set PC to the exception entry point */ | 2121 | /* Set PC to the exception entry point */ |
2137 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2122 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
@@ -2166,7 +2151,7 @@ enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause, | |||
2166 | kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc); | 2151 | kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc); |
2167 | 2152 | ||
2168 | kvm_change_c0_guest_cause(cop0, (0xff), | 2153 | kvm_change_c0_guest_cause(cop0, (0xff), |
2169 | (T_TRAP << CAUSEB_EXCCODE)); | 2154 | (EXCCODE_TR << CAUSEB_EXCCODE)); |
2170 | 2155 | ||
2171 | /* Set PC to the exception entry point */ | 2156 | /* Set PC to the exception entry point */ |
2172 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2157 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
@@ -2201,7 +2186,7 @@ enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause, | |||
2201 | kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc); | 2186 | kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc); |
2202 | 2187 | ||
2203 | kvm_change_c0_guest_cause(cop0, (0xff), | 2188 | kvm_change_c0_guest_cause(cop0, (0xff), |
2204 | (T_MSAFPE << CAUSEB_EXCCODE)); | 2189 | (EXCCODE_MSAFPE << CAUSEB_EXCCODE)); |
2205 | 2190 | ||
2206 | /* Set PC to the exception entry point */ | 2191 | /* Set PC to the exception entry point */ |
2207 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2192 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
@@ -2236,7 +2221,7 @@ enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause, | |||
2236 | kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc); | 2221 | kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc); |
2237 | 2222 | ||
2238 | kvm_change_c0_guest_cause(cop0, (0xff), | 2223 | kvm_change_c0_guest_cause(cop0, (0xff), |
2239 | (T_FPE << CAUSEB_EXCCODE)); | 2224 | (EXCCODE_FPE << CAUSEB_EXCCODE)); |
2240 | 2225 | ||
2241 | /* Set PC to the exception entry point */ | 2226 | /* Set PC to the exception entry point */ |
2242 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2227 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
@@ -2271,7 +2256,7 @@ enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause, | |||
2271 | kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc); | 2256 | kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc); |
2272 | 2257 | ||
2273 | kvm_change_c0_guest_cause(cop0, (0xff), | 2258 | kvm_change_c0_guest_cause(cop0, (0xff), |
2274 | (T_MSADIS << CAUSEB_EXCCODE)); | 2259 | (EXCCODE_MSADIS << CAUSEB_EXCCODE)); |
2275 | 2260 | ||
2276 | /* Set PC to the exception entry point */ | 2261 | /* Set PC to the exception entry point */ |
2277 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | 2262 | arch->pc = KVM_GUEST_KSEG0 + 0x180; |
@@ -2480,25 +2465,25 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause, | |||
2480 | 2465 | ||
2481 | if (usermode) { | 2466 | if (usermode) { |
2482 | switch (exccode) { | 2467 | switch (exccode) { |
2483 | case T_INT: | 2468 | case EXCCODE_INT: |
2484 | case T_SYSCALL: | 2469 | case EXCCODE_SYS: |
2485 | case T_BREAK: | 2470 | case EXCCODE_BP: |
2486 | case T_RES_INST: | 2471 | case EXCCODE_RI: |
2487 | case T_TRAP: | 2472 | case EXCCODE_TR: |
2488 | case T_MSAFPE: | 2473 | case EXCCODE_MSAFPE: |
2489 | case T_FPE: | 2474 | case EXCCODE_FPE: |
2490 | case T_MSADIS: | 2475 | case EXCCODE_MSADIS: |
2491 | break; | 2476 | break; |
2492 | 2477 | ||
2493 | case T_COP_UNUSABLE: | 2478 | case EXCCODE_CPU: |
2494 | if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0) | 2479 | if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0) |
2495 | er = EMULATE_PRIV_FAIL; | 2480 | er = EMULATE_PRIV_FAIL; |
2496 | break; | 2481 | break; |
2497 | 2482 | ||
2498 | case T_TLB_MOD: | 2483 | case EXCCODE_MOD: |
2499 | break; | 2484 | break; |
2500 | 2485 | ||
2501 | case T_TLB_LD_MISS: | 2486 | case EXCCODE_TLBL: |
2502 | /* | 2487 | /* |
2503 | * We we are accessing Guest kernel space, then send an | 2488 | * We we are accessing Guest kernel space, then send an |
2504 | * address error exception to the guest | 2489 | * address error exception to the guest |
@@ -2507,12 +2492,12 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause, | |||
2507 | kvm_debug("%s: LD MISS @ %#lx\n", __func__, | 2492 | kvm_debug("%s: LD MISS @ %#lx\n", __func__, |
2508 | badvaddr); | 2493 | badvaddr); |
2509 | cause &= ~0xff; | 2494 | cause &= ~0xff; |
2510 | cause |= (T_ADDR_ERR_LD << CAUSEB_EXCCODE); | 2495 | cause |= (EXCCODE_ADEL << CAUSEB_EXCCODE); |
2511 | er = EMULATE_PRIV_FAIL; | 2496 | er = EMULATE_PRIV_FAIL; |
2512 | } | 2497 | } |
2513 | break; | 2498 | break; |
2514 | 2499 | ||
2515 | case T_TLB_ST_MISS: | 2500 | case EXCCODE_TLBS: |
2516 | /* | 2501 | /* |
2517 | * We we are accessing Guest kernel space, then send an | 2502 | * We we are accessing Guest kernel space, then send an |
2518 | * address error exception to the guest | 2503 | * address error exception to the guest |
@@ -2521,26 +2506,26 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause, | |||
2521 | kvm_debug("%s: ST MISS @ %#lx\n", __func__, | 2506 | kvm_debug("%s: ST MISS @ %#lx\n", __func__, |
2522 | badvaddr); | 2507 | badvaddr); |
2523 | cause &= ~0xff; | 2508 | cause &= ~0xff; |
2524 | cause |= (T_ADDR_ERR_ST << CAUSEB_EXCCODE); | 2509 | cause |= (EXCCODE_ADES << CAUSEB_EXCCODE); |
2525 | er = EMULATE_PRIV_FAIL; | 2510 | er = EMULATE_PRIV_FAIL; |
2526 | } | 2511 | } |
2527 | break; | 2512 | break; |
2528 | 2513 | ||
2529 | case T_ADDR_ERR_ST: | 2514 | case EXCCODE_ADES: |
2530 | kvm_debug("%s: address error ST @ %#lx\n", __func__, | 2515 | kvm_debug("%s: address error ST @ %#lx\n", __func__, |
2531 | badvaddr); | 2516 | badvaddr); |
2532 | if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) { | 2517 | if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) { |
2533 | cause &= ~0xff; | 2518 | cause &= ~0xff; |
2534 | cause |= (T_TLB_ST_MISS << CAUSEB_EXCCODE); | 2519 | cause |= (EXCCODE_TLBS << CAUSEB_EXCCODE); |
2535 | } | 2520 | } |
2536 | er = EMULATE_PRIV_FAIL; | 2521 | er = EMULATE_PRIV_FAIL; |
2537 | break; | 2522 | break; |
2538 | case T_ADDR_ERR_LD: | 2523 | case EXCCODE_ADEL: |
2539 | kvm_debug("%s: address error LD @ %#lx\n", __func__, | 2524 | kvm_debug("%s: address error LD @ %#lx\n", __func__, |
2540 | badvaddr); | 2525 | badvaddr); |
2541 | if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) { | 2526 | if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) { |
2542 | cause &= ~0xff; | 2527 | cause &= ~0xff; |
2543 | cause |= (T_TLB_LD_MISS << CAUSEB_EXCCODE); | 2528 | cause |= (EXCCODE_TLBL << CAUSEB_EXCCODE); |
2544 | } | 2529 | } |
2545 | er = EMULATE_PRIV_FAIL; | 2530 | er = EMULATE_PRIV_FAIL; |
2546 | break; | 2531 | break; |
@@ -2583,13 +2568,12 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause, | |||
2583 | * an entry into the guest TLB. | 2568 | * an entry into the guest TLB. |
2584 | */ | 2569 | */ |
2585 | index = kvm_mips_guest_tlb_lookup(vcpu, | 2570 | index = kvm_mips_guest_tlb_lookup(vcpu, |
2586 | (va & VPN2_MASK) | | 2571 | (va & VPN2_MASK) | |
2587 | (kvm_read_c0_guest_entryhi | 2572 | (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & ASID_MASK)); |
2588 | (vcpu->arch.cop0) & ASID_MASK)); | ||
2589 | if (index < 0) { | 2573 | if (index < 0) { |
2590 | if (exccode == T_TLB_LD_MISS) { | 2574 | if (exccode == EXCCODE_TLBL) { |
2591 | er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); | 2575 | er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); |
2592 | } else if (exccode == T_TLB_ST_MISS) { | 2576 | } else if (exccode == EXCCODE_TLBS) { |
2593 | er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu); | 2577 | er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu); |
2594 | } else { | 2578 | } else { |
2595 | kvm_err("%s: invalid exc code: %d\n", __func__, | 2579 | kvm_err("%s: invalid exc code: %d\n", __func__, |
@@ -2604,10 +2588,10 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause, | |||
2604 | * exception to the guest | 2588 | * exception to the guest |
2605 | */ | 2589 | */ |
2606 | if (!TLB_IS_VALID(*tlb, va)) { | 2590 | if (!TLB_IS_VALID(*tlb, va)) { |
2607 | if (exccode == T_TLB_LD_MISS) { | 2591 | if (exccode == EXCCODE_TLBL) { |
2608 | er = kvm_mips_emulate_tlbinv_ld(cause, opc, run, | 2592 | er = kvm_mips_emulate_tlbinv_ld(cause, opc, run, |
2609 | vcpu); | 2593 | vcpu); |
2610 | } else if (exccode == T_TLB_ST_MISS) { | 2594 | } else if (exccode == EXCCODE_TLBS) { |
2611 | er = kvm_mips_emulate_tlbinv_st(cause, opc, run, | 2595 | er = kvm_mips_emulate_tlbinv_st(cause, opc, run, |
2612 | vcpu); | 2596 | vcpu); |
2613 | } else { | 2597 | } else { |
diff --git a/arch/mips/kvm/interrupt.c b/arch/mips/kvm/interrupt.c index 9b4445940c2b..95f790663b0c 100644 --- a/arch/mips/kvm/interrupt.c +++ b/arch/mips/kvm/interrupt.c | |||
@@ -128,7 +128,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, | |||
128 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) | 128 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) |
129 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) { | 129 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) { |
130 | allowed = 1; | 130 | allowed = 1; |
131 | exccode = T_INT; | 131 | exccode = EXCCODE_INT; |
132 | } | 132 | } |
133 | break; | 133 | break; |
134 | 134 | ||
@@ -137,7 +137,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, | |||
137 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) | 137 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) |
138 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) { | 138 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) { |
139 | allowed = 1; | 139 | allowed = 1; |
140 | exccode = T_INT; | 140 | exccode = EXCCODE_INT; |
141 | } | 141 | } |
142 | break; | 142 | break; |
143 | 143 | ||
@@ -146,7 +146,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, | |||
146 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) | 146 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) |
147 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) { | 147 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) { |
148 | allowed = 1; | 148 | allowed = 1; |
149 | exccode = T_INT; | 149 | exccode = EXCCODE_INT; |
150 | } | 150 | } |
151 | break; | 151 | break; |
152 | 152 | ||
@@ -155,7 +155,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, | |||
155 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) | 155 | && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL))) |
156 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) { | 156 | && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) { |
157 | allowed = 1; | 157 | allowed = 1; |
158 | exccode = T_INT; | 158 | exccode = EXCCODE_INT; |
159 | } | 159 | } |
160 | break; | 160 | break; |
161 | 161 | ||
diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S index 7e2210846b8b..81687ab1b523 100644 --- a/arch/mips/kvm/locore.S +++ b/arch/mips/kvm/locore.S | |||
@@ -335,7 +335,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | |||
335 | 335 | ||
336 | /* Now restore the host state just enough to run the handlers */ | 336 | /* Now restore the host state just enough to run the handlers */ |
337 | 337 | ||
338 | /* Swtich EBASE to the one used by Linux */ | 338 | /* Switch EBASE to the one used by Linux */ |
339 | /* load up the host EBASE */ | 339 | /* load up the host EBASE */ |
340 | mfc0 v0, CP0_STATUS | 340 | mfc0 v0, CP0_STATUS |
341 | 341 | ||
@@ -490,11 +490,11 @@ __kvm_mips_return_to_guest: | |||
490 | REG_ADDU t3, t1, t2 | 490 | REG_ADDU t3, t1, t2 |
491 | LONG_L k0, (t3) | 491 | LONG_L k0, (t3) |
492 | andi k0, k0, 0xff | 492 | andi k0, k0, 0xff |
493 | mtc0 k0,CP0_ENTRYHI | 493 | mtc0 k0, CP0_ENTRYHI |
494 | ehb | 494 | ehb |
495 | 495 | ||
496 | /* Disable RDHWR access */ | 496 | /* Disable RDHWR access */ |
497 | mtc0 zero, CP0_HWRENA | 497 | mtc0 zero, CP0_HWRENA |
498 | 498 | ||
499 | /* load the guest context from VCPU and return */ | 499 | /* load the guest context from VCPU and return */ |
500 | LONG_L $0, VCPU_R0(k1) | 500 | LONG_L $0, VCPU_R0(k1) |
@@ -606,11 +606,11 @@ __kvm_mips_return_to_host: | |||
606 | 606 | ||
607 | /* Restore RDHWR access */ | 607 | /* Restore RDHWR access */ |
608 | PTR_LI k0, 0x2000000F | 608 | PTR_LI k0, 0x2000000F |
609 | mtc0 k0, CP0_HWRENA | 609 | mtc0 k0, CP0_HWRENA |
610 | 610 | ||
611 | /* Restore RA, which is the address we will return to */ | 611 | /* Restore RA, which is the address we will return to */ |
612 | LONG_L ra, PT_R31(k1) | 612 | LONG_L ra, PT_R31(k1) |
613 | j ra | 613 | j ra |
614 | nop | 614 | nop |
615 | 615 | ||
616 | VECTOR_END(MIPSX(GuestExceptionEnd)) | 616 | VECTOR_END(MIPSX(GuestExceptionEnd)) |
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index b9b803facdbf..8bc3977576e6 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c | |||
@@ -229,7 +229,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
229 | kzalloc(npages * sizeof(unsigned long), GFP_KERNEL); | 229 | kzalloc(npages * sizeof(unsigned long), GFP_KERNEL); |
230 | 230 | ||
231 | if (!kvm->arch.guest_pmap) { | 231 | if (!kvm->arch.guest_pmap) { |
232 | kvm_err("Failed to allocate guest PMAP"); | 232 | kvm_err("Failed to allocate guest PMAP\n"); |
233 | return; | 233 | return; |
234 | } | 234 | } |
235 | 235 | ||
@@ -1264,8 +1264,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | switch (exccode) { | 1266 | switch (exccode) { |
1267 | case T_INT: | 1267 | case EXCCODE_INT: |
1268 | kvm_debug("[%d]T_INT @ %p\n", vcpu->vcpu_id, opc); | 1268 | kvm_debug("[%d]EXCCODE_INT @ %p\n", vcpu->vcpu_id, opc); |
1269 | 1269 | ||
1270 | ++vcpu->stat.int_exits; | 1270 | ++vcpu->stat.int_exits; |
1271 | trace_kvm_exit(vcpu, INT_EXITS); | 1271 | trace_kvm_exit(vcpu, INT_EXITS); |
@@ -1276,8 +1276,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1276 | ret = RESUME_GUEST; | 1276 | ret = RESUME_GUEST; |
1277 | break; | 1277 | break; |
1278 | 1278 | ||
1279 | case T_COP_UNUSABLE: | 1279 | case EXCCODE_CPU: |
1280 | kvm_debug("T_COP_UNUSABLE: @ PC: %p\n", opc); | 1280 | kvm_debug("EXCCODE_CPU: @ PC: %p\n", opc); |
1281 | 1281 | ||
1282 | ++vcpu->stat.cop_unusable_exits; | 1282 | ++vcpu->stat.cop_unusable_exits; |
1283 | trace_kvm_exit(vcpu, COP_UNUSABLE_EXITS); | 1283 | trace_kvm_exit(vcpu, COP_UNUSABLE_EXITS); |
@@ -1287,13 +1287,13 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1287 | ret = RESUME_HOST; | 1287 | ret = RESUME_HOST; |
1288 | break; | 1288 | break; |
1289 | 1289 | ||
1290 | case T_TLB_MOD: | 1290 | case EXCCODE_MOD: |
1291 | ++vcpu->stat.tlbmod_exits; | 1291 | ++vcpu->stat.tlbmod_exits; |
1292 | trace_kvm_exit(vcpu, TLBMOD_EXITS); | 1292 | trace_kvm_exit(vcpu, TLBMOD_EXITS); |
1293 | ret = kvm_mips_callbacks->handle_tlb_mod(vcpu); | 1293 | ret = kvm_mips_callbacks->handle_tlb_mod(vcpu); |
1294 | break; | 1294 | break; |
1295 | 1295 | ||
1296 | case T_TLB_ST_MISS: | 1296 | case EXCCODE_TLBS: |
1297 | kvm_debug("TLB ST fault: cause %#x, status %#lx, PC: %p, BadVaddr: %#lx\n", | 1297 | kvm_debug("TLB ST fault: cause %#x, status %#lx, PC: %p, BadVaddr: %#lx\n", |
1298 | cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc, | 1298 | cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc, |
1299 | badvaddr); | 1299 | badvaddr); |
@@ -1303,7 +1303,7 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1303 | ret = kvm_mips_callbacks->handle_tlb_st_miss(vcpu); | 1303 | ret = kvm_mips_callbacks->handle_tlb_st_miss(vcpu); |
1304 | break; | 1304 | break; |
1305 | 1305 | ||
1306 | case T_TLB_LD_MISS: | 1306 | case EXCCODE_TLBL: |
1307 | kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n", | 1307 | kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n", |
1308 | cause, opc, badvaddr); | 1308 | cause, opc, badvaddr); |
1309 | 1309 | ||
@@ -1312,55 +1312,55 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1312 | ret = kvm_mips_callbacks->handle_tlb_ld_miss(vcpu); | 1312 | ret = kvm_mips_callbacks->handle_tlb_ld_miss(vcpu); |
1313 | break; | 1313 | break; |
1314 | 1314 | ||
1315 | case T_ADDR_ERR_ST: | 1315 | case EXCCODE_ADES: |
1316 | ++vcpu->stat.addrerr_st_exits; | 1316 | ++vcpu->stat.addrerr_st_exits; |
1317 | trace_kvm_exit(vcpu, ADDRERR_ST_EXITS); | 1317 | trace_kvm_exit(vcpu, ADDRERR_ST_EXITS); |
1318 | ret = kvm_mips_callbacks->handle_addr_err_st(vcpu); | 1318 | ret = kvm_mips_callbacks->handle_addr_err_st(vcpu); |
1319 | break; | 1319 | break; |
1320 | 1320 | ||
1321 | case T_ADDR_ERR_LD: | 1321 | case EXCCODE_ADEL: |
1322 | ++vcpu->stat.addrerr_ld_exits; | 1322 | ++vcpu->stat.addrerr_ld_exits; |
1323 | trace_kvm_exit(vcpu, ADDRERR_LD_EXITS); | 1323 | trace_kvm_exit(vcpu, ADDRERR_LD_EXITS); |
1324 | ret = kvm_mips_callbacks->handle_addr_err_ld(vcpu); | 1324 | ret = kvm_mips_callbacks->handle_addr_err_ld(vcpu); |
1325 | break; | 1325 | break; |
1326 | 1326 | ||
1327 | case T_SYSCALL: | 1327 | case EXCCODE_SYS: |
1328 | ++vcpu->stat.syscall_exits; | 1328 | ++vcpu->stat.syscall_exits; |
1329 | trace_kvm_exit(vcpu, SYSCALL_EXITS); | 1329 | trace_kvm_exit(vcpu, SYSCALL_EXITS); |
1330 | ret = kvm_mips_callbacks->handle_syscall(vcpu); | 1330 | ret = kvm_mips_callbacks->handle_syscall(vcpu); |
1331 | break; | 1331 | break; |
1332 | 1332 | ||
1333 | case T_RES_INST: | 1333 | case EXCCODE_RI: |
1334 | ++vcpu->stat.resvd_inst_exits; | 1334 | ++vcpu->stat.resvd_inst_exits; |
1335 | trace_kvm_exit(vcpu, RESVD_INST_EXITS); | 1335 | trace_kvm_exit(vcpu, RESVD_INST_EXITS); |
1336 | ret = kvm_mips_callbacks->handle_res_inst(vcpu); | 1336 | ret = kvm_mips_callbacks->handle_res_inst(vcpu); |
1337 | break; | 1337 | break; |
1338 | 1338 | ||
1339 | case T_BREAK: | 1339 | case EXCCODE_BP: |
1340 | ++vcpu->stat.break_inst_exits; | 1340 | ++vcpu->stat.break_inst_exits; |
1341 | trace_kvm_exit(vcpu, BREAK_INST_EXITS); | 1341 | trace_kvm_exit(vcpu, BREAK_INST_EXITS); |
1342 | ret = kvm_mips_callbacks->handle_break(vcpu); | 1342 | ret = kvm_mips_callbacks->handle_break(vcpu); |
1343 | break; | 1343 | break; |
1344 | 1344 | ||
1345 | case T_TRAP: | 1345 | case EXCCODE_TR: |
1346 | ++vcpu->stat.trap_inst_exits; | 1346 | ++vcpu->stat.trap_inst_exits; |
1347 | trace_kvm_exit(vcpu, TRAP_INST_EXITS); | 1347 | trace_kvm_exit(vcpu, TRAP_INST_EXITS); |
1348 | ret = kvm_mips_callbacks->handle_trap(vcpu); | 1348 | ret = kvm_mips_callbacks->handle_trap(vcpu); |
1349 | break; | 1349 | break; |
1350 | 1350 | ||
1351 | case T_MSAFPE: | 1351 | case EXCCODE_MSAFPE: |
1352 | ++vcpu->stat.msa_fpe_exits; | 1352 | ++vcpu->stat.msa_fpe_exits; |
1353 | trace_kvm_exit(vcpu, MSA_FPE_EXITS); | 1353 | trace_kvm_exit(vcpu, MSA_FPE_EXITS); |
1354 | ret = kvm_mips_callbacks->handle_msa_fpe(vcpu); | 1354 | ret = kvm_mips_callbacks->handle_msa_fpe(vcpu); |
1355 | break; | 1355 | break; |
1356 | 1356 | ||
1357 | case T_FPE: | 1357 | case EXCCODE_FPE: |
1358 | ++vcpu->stat.fpe_exits; | 1358 | ++vcpu->stat.fpe_exits; |
1359 | trace_kvm_exit(vcpu, FPE_EXITS); | 1359 | trace_kvm_exit(vcpu, FPE_EXITS); |
1360 | ret = kvm_mips_callbacks->handle_fpe(vcpu); | 1360 | ret = kvm_mips_callbacks->handle_fpe(vcpu); |
1361 | break; | 1361 | break; |
1362 | 1362 | ||
1363 | case T_MSADIS: | 1363 | case EXCCODE_MSADIS: |
1364 | ++vcpu->stat.msa_disabled_exits; | 1364 | ++vcpu->stat.msa_disabled_exits; |
1365 | trace_kvm_exit(vcpu, MSA_DISABLED_EXITS); | 1365 | trace_kvm_exit(vcpu, MSA_DISABLED_EXITS); |
1366 | ret = kvm_mips_callbacks->handle_msa_disabled(vcpu); | 1366 | ret = kvm_mips_callbacks->handle_msa_disabled(vcpu); |
@@ -1620,7 +1620,7 @@ static struct notifier_block kvm_mips_csr_die_notifier = { | |||
1620 | .notifier_call = kvm_mips_csr_die_notify, | 1620 | .notifier_call = kvm_mips_csr_die_notify, |
1621 | }; | 1621 | }; |
1622 | 1622 | ||
1623 | int __init kvm_mips_init(void) | 1623 | static int __init kvm_mips_init(void) |
1624 | { | 1624 | { |
1625 | int ret; | 1625 | int ret; |
1626 | 1626 | ||
@@ -1646,7 +1646,7 @@ int __init kvm_mips_init(void) | |||
1646 | return 0; | 1646 | return 0; |
1647 | } | 1647 | } |
1648 | 1648 | ||
1649 | void __exit kvm_mips_exit(void) | 1649 | static void __exit kvm_mips_exit(void) |
1650 | { | 1650 | { |
1651 | kvm_exit(); | 1651 | kvm_exit(); |
1652 | 1652 | ||
diff --git a/arch/mips/kvm/opcode.h b/arch/mips/kvm/opcode.h deleted file mode 100644 index 03a6ae84c7df..000000000000 --- a/arch/mips/kvm/opcode.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
7 | * Authors: Sanjay Lal <sanjayl@kymasys.com> | ||
8 | */ | ||
9 | |||
10 | /* Define opcode values not defined in <asm/isnt.h> */ | ||
11 | |||
12 | #ifndef __KVM_MIPS_OPCODE_H__ | ||
13 | #define __KVM_MIPS_OPCODE_H__ | ||
14 | |||
15 | /* COP0 Ops */ | ||
16 | #define mfmcz_op 0x0b /* 01011 */ | ||
17 | #define wrpgpr_op 0x0e /* 01110 */ | ||
18 | |||
19 | /* COP0 opcodes (only if COP0 and CO=1): */ | ||
20 | #define wait_op 0x20 /* 100000 */ | ||
21 | |||
22 | #endif /* __KVM_MIPS_OPCODE_H__ */ | ||
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c index 570479c03bdc..a08c43946247 100644 --- a/arch/mips/kvm/tlb.c +++ b/arch/mips/kvm/tlb.c | |||
@@ -35,17 +35,17 @@ | |||
35 | #define PRIx64 "llx" | 35 | #define PRIx64 "llx" |
36 | 36 | ||
37 | atomic_t kvm_mips_instance; | 37 | atomic_t kvm_mips_instance; |
38 | EXPORT_SYMBOL(kvm_mips_instance); | 38 | EXPORT_SYMBOL_GPL(kvm_mips_instance); |
39 | 39 | ||
40 | /* These function pointers are initialized once the KVM module is loaded */ | 40 | /* These function pointers are initialized once the KVM module is loaded */ |
41 | kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn); | 41 | kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn); |
42 | EXPORT_SYMBOL(kvm_mips_gfn_to_pfn); | 42 | EXPORT_SYMBOL_GPL(kvm_mips_gfn_to_pfn); |
43 | 43 | ||
44 | void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn); | 44 | void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn); |
45 | EXPORT_SYMBOL(kvm_mips_release_pfn_clean); | 45 | EXPORT_SYMBOL_GPL(kvm_mips_release_pfn_clean); |
46 | 46 | ||
47 | bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn); | 47 | bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn); |
48 | EXPORT_SYMBOL(kvm_mips_is_error_pfn); | 48 | EXPORT_SYMBOL_GPL(kvm_mips_is_error_pfn); |
49 | 49 | ||
50 | uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) | 50 | uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) |
51 | { | 51 | { |
@@ -111,7 +111,7 @@ void kvm_mips_dump_host_tlbs(void) | |||
111 | mtc0_tlbw_hazard(); | 111 | mtc0_tlbw_hazard(); |
112 | local_irq_restore(flags); | 112 | local_irq_restore(flags); |
113 | } | 113 | } |
114 | EXPORT_SYMBOL(kvm_mips_dump_host_tlbs); | 114 | EXPORT_SYMBOL_GPL(kvm_mips_dump_host_tlbs); |
115 | 115 | ||
116 | void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu) | 116 | void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu) |
117 | { | 117 | { |
@@ -139,7 +139,7 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu) | |||
139 | (tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask); | 139 | (tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask); |
140 | } | 140 | } |
141 | } | 141 | } |
142 | EXPORT_SYMBOL(kvm_mips_dump_guest_tlbs); | 142 | EXPORT_SYMBOL_GPL(kvm_mips_dump_guest_tlbs); |
143 | 143 | ||
144 | static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) | 144 | static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) |
145 | { | 145 | { |
@@ -191,7 +191,7 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu, | |||
191 | 191 | ||
192 | return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset; | 192 | return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset; |
193 | } | 193 | } |
194 | EXPORT_SYMBOL(kvm_mips_translate_guest_kseg0_to_hpa); | 194 | EXPORT_SYMBOL_GPL(kvm_mips_translate_guest_kseg0_to_hpa); |
195 | 195 | ||
196 | /* XXXKYMA: Must be called with interrupts disabled */ | 196 | /* XXXKYMA: Must be called with interrupts disabled */ |
197 | /* set flush_dcache_mask == 0 if no dcache flush required */ | 197 | /* set flush_dcache_mask == 0 if no dcache flush required */ |
@@ -308,7 +308,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr, | |||
308 | return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1, | 308 | return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1, |
309 | flush_dcache_mask); | 309 | flush_dcache_mask); |
310 | } | 310 | } |
311 | EXPORT_SYMBOL(kvm_mips_handle_kseg0_tlb_fault); | 311 | EXPORT_SYMBOL_GPL(kvm_mips_handle_kseg0_tlb_fault); |
312 | 312 | ||
313 | int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr, | 313 | int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr, |
314 | struct kvm_vcpu *vcpu) | 314 | struct kvm_vcpu *vcpu) |
@@ -351,7 +351,7 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr, | |||
351 | 351 | ||
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | EXPORT_SYMBOL(kvm_mips_handle_commpage_tlb_fault); | 354 | EXPORT_SYMBOL_GPL(kvm_mips_handle_commpage_tlb_fault); |
355 | 355 | ||
356 | int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, | 356 | int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, |
357 | struct kvm_mips_tlb *tlb, | 357 | struct kvm_mips_tlb *tlb, |
@@ -401,7 +401,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, | |||
401 | return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1, | 401 | return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1, |
402 | tlb->tlb_mask); | 402 | tlb->tlb_mask); |
403 | } | 403 | } |
404 | EXPORT_SYMBOL(kvm_mips_handle_mapped_seg_tlb_fault); | 404 | EXPORT_SYMBOL_GPL(kvm_mips_handle_mapped_seg_tlb_fault); |
405 | 405 | ||
406 | int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi) | 406 | int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi) |
407 | { | 407 | { |
@@ -422,7 +422,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi) | |||
422 | 422 | ||
423 | return index; | 423 | return index; |
424 | } | 424 | } |
425 | EXPORT_SYMBOL(kvm_mips_guest_tlb_lookup); | 425 | EXPORT_SYMBOL_GPL(kvm_mips_guest_tlb_lookup); |
426 | 426 | ||
427 | int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr) | 427 | int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr) |
428 | { | 428 | { |
@@ -458,7 +458,7 @@ int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr) | |||
458 | 458 | ||
459 | return idx; | 459 | return idx; |
460 | } | 460 | } |
461 | EXPORT_SYMBOL(kvm_mips_host_tlb_lookup); | 461 | EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_lookup); |
462 | 462 | ||
463 | int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va) | 463 | int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va) |
464 | { | 464 | { |
@@ -505,44 +505,7 @@ int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va) | |||
505 | 505 | ||
506 | return 0; | 506 | return 0; |
507 | } | 507 | } |
508 | EXPORT_SYMBOL(kvm_mips_host_tlb_inv); | 508 | EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_inv); |
509 | |||
510 | /* XXXKYMA: Fix Guest USER/KERNEL no longer share the same ASID */ | ||
511 | int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index) | ||
512 | { | ||
513 | unsigned long flags, old_entryhi; | ||
514 | |||
515 | if (index >= current_cpu_data.tlbsize) | ||
516 | BUG(); | ||
517 | |||
518 | local_irq_save(flags); | ||
519 | |||
520 | old_entryhi = read_c0_entryhi(); | ||
521 | |||
522 | write_c0_entryhi(UNIQUE_ENTRYHI(index)); | ||
523 | mtc0_tlbw_hazard(); | ||
524 | |||
525 | write_c0_index(index); | ||
526 | mtc0_tlbw_hazard(); | ||
527 | |||
528 | write_c0_entrylo0(0); | ||
529 | mtc0_tlbw_hazard(); | ||
530 | |||
531 | write_c0_entrylo1(0); | ||
532 | mtc0_tlbw_hazard(); | ||
533 | |||
534 | tlb_write_indexed(); | ||
535 | mtc0_tlbw_hazard(); | ||
536 | tlbw_use_hazard(); | ||
537 | |||
538 | write_c0_entryhi(old_entryhi); | ||
539 | mtc0_tlbw_hazard(); | ||
540 | tlbw_use_hazard(); | ||
541 | |||
542 | local_irq_restore(flags); | ||
543 | |||
544 | return 0; | ||
545 | } | ||
546 | 509 | ||
547 | void kvm_mips_flush_host_tlb(int skip_kseg0) | 510 | void kvm_mips_flush_host_tlb(int skip_kseg0) |
548 | { | 511 | { |
@@ -594,7 +557,7 @@ void kvm_mips_flush_host_tlb(int skip_kseg0) | |||
594 | 557 | ||
595 | local_irq_restore(flags); | 558 | local_irq_restore(flags); |
596 | } | 559 | } |
597 | EXPORT_SYMBOL(kvm_mips_flush_host_tlb); | 560 | EXPORT_SYMBOL_GPL(kvm_mips_flush_host_tlb); |
598 | 561 | ||
599 | void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu, | 562 | void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu, |
600 | struct kvm_vcpu *vcpu) | 563 | struct kvm_vcpu *vcpu) |
@@ -642,7 +605,7 @@ void kvm_local_flush_tlb_all(void) | |||
642 | 605 | ||
643 | local_irq_restore(flags); | 606 | local_irq_restore(flags); |
644 | } | 607 | } |
645 | EXPORT_SYMBOL(kvm_local_flush_tlb_all); | 608 | EXPORT_SYMBOL_GPL(kvm_local_flush_tlb_all); |
646 | 609 | ||
647 | /** | 610 | /** |
648 | * kvm_mips_migrate_count() - Migrate timer. | 611 | * kvm_mips_migrate_count() - Migrate timer. |
@@ -673,8 +636,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
673 | 636 | ||
674 | local_irq_save(flags); | 637 | local_irq_save(flags); |
675 | 638 | ||
676 | if (((vcpu->arch. | 639 | if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) & |
677 | guest_kernel_asid[cpu] ^ asid_cache(cpu)) & ASID_VERSION_MASK)) { | 640 | ASID_VERSION_MASK) { |
678 | kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu); | 641 | kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu); |
679 | vcpu->arch.guest_kernel_asid[cpu] = | 642 | vcpu->arch.guest_kernel_asid[cpu] = |
680 | vcpu->arch.guest_kernel_mm.context.asid[cpu]; | 643 | vcpu->arch.guest_kernel_mm.context.asid[cpu]; |
@@ -739,7 +702,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
739 | local_irq_restore(flags); | 702 | local_irq_restore(flags); |
740 | 703 | ||
741 | } | 704 | } |
742 | EXPORT_SYMBOL(kvm_arch_vcpu_load); | 705 | EXPORT_SYMBOL_GPL(kvm_arch_vcpu_load); |
743 | 706 | ||
744 | /* ASID can change if another task is scheduled during preemption */ | 707 | /* ASID can change if another task is scheduled during preemption */ |
745 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 708 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
@@ -768,7 +731,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
768 | 731 | ||
769 | local_irq_restore(flags); | 732 | local_irq_restore(flags); |
770 | } | 733 | } |
771 | EXPORT_SYMBOL(kvm_arch_vcpu_put); | 734 | EXPORT_SYMBOL_GPL(kvm_arch_vcpu_put); |
772 | 735 | ||
773 | uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) | 736 | uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) |
774 | { | 737 | { |
@@ -813,4 +776,4 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) | |||
813 | 776 | ||
814 | return inst; | 777 | return inst; |
815 | } | 778 | } |
816 | EXPORT_SYMBOL(kvm_get_inst); | 779 | EXPORT_SYMBOL_GPL(kvm_get_inst); |
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index d836ed5b0bc7..ad988000563f 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #include <linux/kvm_host.h> | 17 | #include <linux/kvm_host.h> |
18 | 18 | ||
19 | #include "opcode.h" | ||
20 | #include "interrupt.h" | 19 | #include "interrupt.h" |
21 | 20 | ||
22 | static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) | 21 | static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) |
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index 272af8ac2425..5530070e0d05 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c | |||
@@ -57,7 +57,6 @@ notrace void arch_local_irq_disable(void) | |||
57 | } | 57 | } |
58 | EXPORT_SYMBOL(arch_local_irq_disable); | 58 | EXPORT_SYMBOL(arch_local_irq_disable); |
59 | 59 | ||
60 | |||
61 | notrace unsigned long arch_local_irq_save(void) | 60 | notrace unsigned long arch_local_irq_save(void) |
62 | { | 61 | { |
63 | unsigned long flags; | 62 | unsigned long flags; |
@@ -111,31 +110,4 @@ notrace void arch_local_irq_restore(unsigned long flags) | |||
111 | } | 110 | } |
112 | EXPORT_SYMBOL(arch_local_irq_restore); | 111 | EXPORT_SYMBOL(arch_local_irq_restore); |
113 | 112 | ||
114 | 113 | #endif /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */ | |
115 | notrace void __arch_local_irq_restore(unsigned long flags) | ||
116 | { | ||
117 | unsigned long __tmp1; | ||
118 | |||
119 | preempt_disable(); | ||
120 | |||
121 | __asm__ __volatile__( | ||
122 | " .set push \n" | ||
123 | " .set noreorder \n" | ||
124 | " .set noat \n" | ||
125 | " mfc0 $1, $12 \n" | ||
126 | " andi %[flags], 1 \n" | ||
127 | " ori $1, 0x1f \n" | ||
128 | " xori $1, 0x1f \n" | ||
129 | " or %[flags], $1 \n" | ||
130 | " mtc0 %[flags], $12 \n" | ||
131 | " " __stringify(__irq_disable_hazard) " \n" | ||
132 | " .set pop \n" | ||
133 | : [flags] "=r" (__tmp1) | ||
134 | : "0" (flags) | ||
135 | : "memory"); | ||
136 | |||
137 | preempt_enable(); | ||
138 | } | ||
139 | EXPORT_SYMBOL(__arch_local_irq_restore); | ||
140 | |||
141 | #endif /* !CONFIG_CPU_MIPSR2 */ | ||
diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform index 2e48e83d5524..85d808924c94 100644 --- a/arch/mips/loongson64/Platform +++ b/arch/mips/loongson64/Platform | |||
@@ -22,6 +22,27 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS | |||
22 | endif | 22 | endif |
23 | endif | 23 | endif |
24 | 24 | ||
25 | cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap | ||
26 | # | ||
27 | # binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a | ||
28 | # as MIPS64 R2; older versions as just R1. This leaves the possibility open | ||
29 | # that GCC might generate R2 code for -march=loongson3a which then is rejected | ||
30 | # by GAS. The cc-option can't probe for this behaviour so -march=loongson3a | ||
31 | # can't easily be used safely within the kbuild framework. | ||
32 | # | ||
33 | ifeq ($(call cc-ifversion, -ge, 0409, y), y) | ||
34 | ifeq ($(call ld-ifversion, -ge, 22500000, y), y) | ||
35 | cflags-$(CONFIG_CPU_LOONGSON3) += \ | ||
36 | $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) | ||
37 | else | ||
38 | cflags-$(CONFIG_CPU_LOONGSON3) += \ | ||
39 | $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) | ||
40 | endif | ||
41 | else | ||
42 | cflags-$(CONFIG_CPU_LOONGSON3) += \ | ||
43 | $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) | ||
44 | endif | ||
45 | |||
25 | # | 46 | # |
26 | # Loongson Machines' Support | 47 | # Loongson Machines' Support |
27 | # | 48 | # |
diff --git a/arch/mips/loongson64/loongson-3/hpet.c b/arch/mips/loongson64/loongson-3/hpet.c index bf9f1a77f0e5..a2631a52ca99 100644 --- a/arch/mips/loongson64/loongson-3/hpet.c +++ b/arch/mips/loongson64/loongson-3/hpet.c | |||
@@ -13,6 +13,9 @@ | |||
13 | #define SMBUS_PCI_REG64 0x64 | 13 | #define SMBUS_PCI_REG64 0x64 |
14 | #define SMBUS_PCI_REGB4 0xb4 | 14 | #define SMBUS_PCI_REGB4 0xb4 |
15 | 15 | ||
16 | #define HPET_MIN_CYCLES 64 | ||
17 | #define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1)) | ||
18 | |||
16 | static DEFINE_SPINLOCK(hpet_lock); | 19 | static DEFINE_SPINLOCK(hpet_lock); |
17 | DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); | 20 | DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); |
18 | 21 | ||
@@ -161,8 +164,9 @@ static int hpet_next_event(unsigned long delta, | |||
161 | cnt += delta; | 164 | cnt += delta; |
162 | hpet_write(HPET_T0_CMP, cnt); | 165 | hpet_write(HPET_T0_CMP, cnt); |
163 | 166 | ||
164 | res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; | 167 | res = (int)(cnt - hpet_read(HPET_COUNTER)); |
165 | return res; | 168 | |
169 | return res < HPET_MIN_CYCLES ? -ETIME : 0; | ||
166 | } | 170 | } |
167 | 171 | ||
168 | static irqreturn_t hpet_irq_handler(int irq, void *data) | 172 | static irqreturn_t hpet_irq_handler(int irq, void *data) |
@@ -237,7 +241,7 @@ void __init setup_hpet_timer(void) | |||
237 | cd->cpumask = cpumask_of(cpu); | 241 | cd->cpumask = cpumask_of(cpu); |
238 | clockevent_set_clock(cd, HPET_FREQ); | 242 | clockevent_set_clock(cd, HPET_FREQ); |
239 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | 243 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); |
240 | cd->min_delta_ns = 5000; | 244 | cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd); |
241 | 245 | ||
242 | clockevents_register_device(cd); | 246 | clockevents_register_device(cd); |
243 | setup_irq(HPET_T0_IRQ, &hpet_irq); | 247 | setup_irq(HPET_T0_IRQ, &hpet_irq); |
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index 1a4738a8f2d3..509832a9836c 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c | |||
@@ -30,13 +30,13 @@ | |||
30 | #include "smp.h" | 30 | #include "smp.h" |
31 | 31 | ||
32 | DEFINE_PER_CPU(int, cpu_state); | 32 | DEFINE_PER_CPU(int, cpu_state); |
33 | DEFINE_PER_CPU(uint32_t, core0_c0count); | ||
34 | 33 | ||
35 | static void *ipi_set0_regs[16]; | 34 | static void *ipi_set0_regs[16]; |
36 | static void *ipi_clear0_regs[16]; | 35 | static void *ipi_clear0_regs[16]; |
37 | static void *ipi_status0_regs[16]; | 36 | static void *ipi_status0_regs[16]; |
38 | static void *ipi_en0_regs[16]; | 37 | static void *ipi_en0_regs[16]; |
39 | static void *ipi_mailbox_buf[16]; | 38 | static void *ipi_mailbox_buf[16]; |
39 | static uint32_t core0_c0count[NR_CPUS]; | ||
40 | 40 | ||
41 | /* read a 32bit value from ipi register */ | 41 | /* read a 32bit value from ipi register */ |
42 | #define loongson3_ipi_read32(addr) readl(addr) | 42 | #define loongson3_ipi_read32(addr) readl(addr) |
@@ -275,12 +275,14 @@ void loongson3_ipi_interrupt(struct pt_regs *regs) | |||
275 | if (action & SMP_ASK_C0COUNT) { | 275 | if (action & SMP_ASK_C0COUNT) { |
276 | BUG_ON(cpu != 0); | 276 | BUG_ON(cpu != 0); |
277 | c0count = read_c0_count(); | 277 | c0count = read_c0_count(); |
278 | for (i = 1; i < num_possible_cpus(); i++) | 278 | c0count = c0count ? c0count : 1; |
279 | per_cpu(core0_c0count, i) = c0count; | 279 | for (i = 1; i < nr_cpu_ids; i++) |
280 | core0_c0count[i] = c0count; | ||
281 | __wbflush(); /* Let others see the result ASAP */ | ||
280 | } | 282 | } |
281 | } | 283 | } |
282 | 284 | ||
283 | #define MAX_LOOPS 1111 | 285 | #define MAX_LOOPS 800 |
284 | /* | 286 | /* |
285 | * SMP init and finish on secondary CPUs | 287 | * SMP init and finish on secondary CPUs |
286 | */ | 288 | */ |
@@ -305,16 +307,20 @@ static void loongson3_init_secondary(void) | |||
305 | cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; | 307 | cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; |
306 | 308 | ||
307 | i = 0; | 309 | i = 0; |
308 | __this_cpu_write(core0_c0count, 0); | 310 | core0_c0count[cpu] = 0; |
309 | loongson3_send_ipi_single(0, SMP_ASK_C0COUNT); | 311 | loongson3_send_ipi_single(0, SMP_ASK_C0COUNT); |
310 | while (!__this_cpu_read(core0_c0count)) { | 312 | while (!core0_c0count[cpu]) { |
311 | i++; | 313 | i++; |
312 | cpu_relax(); | 314 | cpu_relax(); |
313 | } | 315 | } |
314 | 316 | ||
315 | if (i > MAX_LOOPS) | 317 | if (i > MAX_LOOPS) |
316 | i = MAX_LOOPS; | 318 | i = MAX_LOOPS; |
317 | initcount = __this_cpu_read(core0_c0count) + i; | 319 | if (cpu_data[cpu].package) |
320 | initcount = core0_c0count[cpu] + i; | ||
321 | else /* Local access is faster for loops */ | ||
322 | initcount = core0_c0count[cpu] + i/2; | ||
323 | |||
318 | write_c0_count(initcount); | 324 | write_c0_count(initcount); |
319 | } | 325 | } |
320 | 326 | ||
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 32f0e19a0d7f..cdfd44ffa51c 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -1266,6 +1266,8 @@ branch_common: | |||
1266 | */ | 1266 | */ |
1267 | sig = mips_dsemul(xcp, ir, | 1267 | sig = mips_dsemul(xcp, ir, |
1268 | contpc); | 1268 | contpc); |
1269 | if (sig < 0) | ||
1270 | break; | ||
1269 | if (sig) | 1271 | if (sig) |
1270 | xcp->cp0_epc = bcpc; | 1272 | xcp->cp0_epc = bcpc; |
1271 | /* | 1273 | /* |
@@ -1319,6 +1321,8 @@ branch_common: | |||
1319 | * instruction in the dslot | 1321 | * instruction in the dslot |
1320 | */ | 1322 | */ |
1321 | sig = mips_dsemul(xcp, ir, contpc); | 1323 | sig = mips_dsemul(xcp, ir, contpc); |
1324 | if (sig < 0) | ||
1325 | break; | ||
1322 | if (sig) | 1326 | if (sig) |
1323 | xcp->cp0_epc = bcpc; | 1327 | xcp->cp0_epc = bcpc; |
1324 | /* SIGILL forces out of the emulation loop. */ | 1328 | /* SIGILL forces out of the emulation loop. */ |
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c index 926d56bf37f2..eb96485ed939 100644 --- a/arch/mips/math-emu/dp_simple.c +++ b/arch/mips/math-emu/dp_simple.c | |||
@@ -23,27 +23,39 @@ | |||
23 | 23 | ||
24 | union ieee754dp ieee754dp_neg(union ieee754dp x) | 24 | union ieee754dp ieee754dp_neg(union ieee754dp x) |
25 | { | 25 | { |
26 | unsigned int oldrm; | ||
27 | union ieee754dp y; | 26 | union ieee754dp y; |
28 | 27 | ||
29 | oldrm = ieee754_csr.rm; | 28 | if (ieee754_csr.abs2008) { |
30 | ieee754_csr.rm = FPU_CSR_RD; | 29 | y = x; |
31 | y = ieee754dp_sub(ieee754dp_zero(0), x); | 30 | DPSIGN(y) = !DPSIGN(x); |
32 | ieee754_csr.rm = oldrm; | 31 | } else { |
32 | unsigned int oldrm; | ||
33 | |||
34 | oldrm = ieee754_csr.rm; | ||
35 | ieee754_csr.rm = FPU_CSR_RD; | ||
36 | y = ieee754dp_sub(ieee754dp_zero(0), x); | ||
37 | ieee754_csr.rm = oldrm; | ||
38 | } | ||
33 | return y; | 39 | return y; |
34 | } | 40 | } |
35 | 41 | ||
36 | union ieee754dp ieee754dp_abs(union ieee754dp x) | 42 | union ieee754dp ieee754dp_abs(union ieee754dp x) |
37 | { | 43 | { |
38 | unsigned int oldrm; | ||
39 | union ieee754dp y; | 44 | union ieee754dp y; |
40 | 45 | ||
41 | oldrm = ieee754_csr.rm; | 46 | if (ieee754_csr.abs2008) { |
42 | ieee754_csr.rm = FPU_CSR_RD; | 47 | y = x; |
43 | if (DPSIGN(x)) | 48 | DPSIGN(y) = 0; |
44 | y = ieee754dp_sub(ieee754dp_zero(0), x); | 49 | } else { |
45 | else | 50 | unsigned int oldrm; |
46 | y = ieee754dp_add(ieee754dp_zero(0), x); | 51 | |
47 | ieee754_csr.rm = oldrm; | 52 | oldrm = ieee754_csr.rm; |
53 | ieee754_csr.rm = FPU_CSR_RD; | ||
54 | if (DPSIGN(x)) | ||
55 | y = ieee754dp_sub(ieee754dp_zero(0), x); | ||
56 | else | ||
57 | y = ieee754dp_add(ieee754dp_zero(0), x); | ||
58 | ieee754_csr.rm = oldrm; | ||
59 | } | ||
48 | return y; | 60 | return y; |
49 | } | 61 | } |
diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c index 6ffc336c530e..f3985617ce31 100644 --- a/arch/mips/math-emu/dp_tint.c +++ b/arch/mips/math-emu/dp_tint.c | |||
@@ -38,10 +38,13 @@ int ieee754dp_tint(union ieee754dp x) | |||
38 | switch (xc) { | 38 | switch (xc) { |
39 | case IEEE754_CLASS_SNAN: | 39 | case IEEE754_CLASS_SNAN: |
40 | case IEEE754_CLASS_QNAN: | 40 | case IEEE754_CLASS_QNAN: |
41 | case IEEE754_CLASS_INF: | ||
42 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 41 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
43 | return ieee754si_indef(); | 42 | return ieee754si_indef(); |
44 | 43 | ||
44 | case IEEE754_CLASS_INF: | ||
45 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
46 | return ieee754si_overflow(xs); | ||
47 | |||
45 | case IEEE754_CLASS_ZERO: | 48 | case IEEE754_CLASS_ZERO: |
46 | return 0; | 49 | return 0; |
47 | 50 | ||
@@ -53,7 +56,7 @@ int ieee754dp_tint(union ieee754dp x) | |||
53 | /* Set invalid. We will only use overflow for floating | 56 | /* Set invalid. We will only use overflow for floating |
54 | point overflow */ | 57 | point overflow */ |
55 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 58 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
56 | return ieee754si_indef(); | 59 | return ieee754si_overflow(xs); |
57 | } | 60 | } |
58 | /* oh gawd */ | 61 | /* oh gawd */ |
59 | if (xe > DP_FBITS) { | 62 | if (xe > DP_FBITS) { |
@@ -93,7 +96,7 @@ int ieee754dp_tint(union ieee754dp x) | |||
93 | if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) { | 96 | if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) { |
94 | /* This can happen after rounding */ | 97 | /* This can happen after rounding */ |
95 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 98 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
96 | return ieee754si_indef(); | 99 | return ieee754si_overflow(xs); |
97 | } | 100 | } |
98 | if (round || sticky) | 101 | if (round || sticky) |
99 | ieee754_setcx(IEEE754_INEXACT); | 102 | ieee754_setcx(IEEE754_INEXACT); |
diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c index 9cdc145b75e0..748fa10ed4cf 100644 --- a/arch/mips/math-emu/dp_tlong.c +++ b/arch/mips/math-emu/dp_tlong.c | |||
@@ -38,10 +38,13 @@ s64 ieee754dp_tlong(union ieee754dp x) | |||
38 | switch (xc) { | 38 | switch (xc) { |
39 | case IEEE754_CLASS_SNAN: | 39 | case IEEE754_CLASS_SNAN: |
40 | case IEEE754_CLASS_QNAN: | 40 | case IEEE754_CLASS_QNAN: |
41 | case IEEE754_CLASS_INF: | ||
42 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 41 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
43 | return ieee754di_indef(); | 42 | return ieee754di_indef(); |
44 | 43 | ||
44 | case IEEE754_CLASS_INF: | ||
45 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
46 | return ieee754di_overflow(xs); | ||
47 | |||
45 | case IEEE754_CLASS_ZERO: | 48 | case IEEE754_CLASS_ZERO: |
46 | return 0; | 49 | return 0; |
47 | 50 | ||
@@ -56,7 +59,7 @@ s64 ieee754dp_tlong(union ieee754dp x) | |||
56 | /* Set invalid. We will only use overflow for floating | 59 | /* Set invalid. We will only use overflow for floating |
57 | point overflow */ | 60 | point overflow */ |
58 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 61 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
59 | return ieee754di_indef(); | 62 | return ieee754di_overflow(xs); |
60 | } | 63 | } |
61 | /* oh gawd */ | 64 | /* oh gawd */ |
62 | if (xe > DP_FBITS) { | 65 | if (xe > DP_FBITS) { |
@@ -97,7 +100,7 @@ s64 ieee754dp_tlong(union ieee754dp x) | |||
97 | if ((xm >> 63) != 0) { | 100 | if ((xm >> 63) != 0) { |
98 | /* This can happen after rounding */ | 101 | /* This can happen after rounding */ |
99 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 102 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
100 | return ieee754di_indef(); | 103 | return ieee754di_overflow(xs); |
101 | } | 104 | } |
102 | if (round || sticky) | 105 | if (round || sticky) |
103 | ieee754_setcx(IEEE754_INEXACT); | 106 | ieee754_setcx(IEEE754_INEXACT); |
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index cbb36c14b155..46b964d2b79c 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c | |||
@@ -31,17 +31,41 @@ struct emuframe { | |||
31 | unsigned long epc; | 31 | unsigned long epc; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | /* | ||
35 | * Set up an emulation frame for instruction IR, from a delay slot of | ||
36 | * a branch jumping to CPC. Return 0 if successful, -1 if no emulation | ||
37 | * required, otherwise a signal number causing a frame setup failure. | ||
38 | */ | ||
34 | int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | 39 | int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) |
35 | { | 40 | { |
41 | int isa16 = get_isa16_mode(regs->cp0_epc); | ||
42 | mips_instruction break_math; | ||
36 | struct emuframe __user *fr; | 43 | struct emuframe __user *fr; |
37 | int err; | 44 | int err; |
38 | 45 | ||
39 | if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) || | 46 | /* NOP is easy */ |
40 | (ir == 0)) { | 47 | if (ir == 0) |
41 | /* NOP is easy */ | 48 | return -1; |
42 | regs->cp0_epc = cpc; | 49 | |
43 | clear_delay_slot(regs); | 50 | /* microMIPS instructions */ |
44 | return 0; | 51 | if (isa16) { |
52 | union mips_instruction insn = { .word = ir }; | ||
53 | |||
54 | /* NOP16 aka MOVE16 $0, $0 */ | ||
55 | if ((ir >> 16) == MM_NOP16) | ||
56 | return -1; | ||
57 | |||
58 | /* ADDIUPC */ | ||
59 | if (insn.mm_a_format.opcode == mm_addiupc_op) { | ||
60 | unsigned int rs; | ||
61 | s32 v; | ||
62 | |||
63 | rs = (((insn.mm_a_format.rs + 0x1e) & 0xf) + 2); | ||
64 | v = regs->cp0_epc & ~3; | ||
65 | v += insn.mm_a_format.simmediate << 2; | ||
66 | regs->regs[rs] = (long)v; | ||
67 | return -1; | ||
68 | } | ||
45 | } | 69 | } |
46 | 70 | ||
47 | pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc); | 71 | pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc); |
@@ -55,14 +79,10 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
55 | * Algorithmics used a system call instruction, and | 79 | * Algorithmics used a system call instruction, and |
56 | * borrowed that vector. MIPS/Linux version is a bit | 80 | * borrowed that vector. MIPS/Linux version is a bit |
57 | * more heavyweight in the interests of portability and | 81 | * more heavyweight in the interests of portability and |
58 | * multiprocessor support. For Linux we generate a | 82 | * multiprocessor support. For Linux we use a BREAK 514 |
59 | * an unaligned access and force an address error exception. | 83 | * instruction causing a breakpoint exception. |
60 | * | ||
61 | * For embedded systems (stand-alone) we prefer to use a | ||
62 | * non-existing CP1 instruction. This prevents us from emulating | ||
63 | * branches, but gives us a cleaner interface to the exception | ||
64 | * handler (single entry point). | ||
65 | */ | 84 | */ |
85 | break_math = BREAK_MATH(isa16); | ||
66 | 86 | ||
67 | /* Ensure that the two instructions are in the same cache line */ | 87 | /* Ensure that the two instructions are in the same cache line */ |
68 | fr = (struct emuframe __user *) | 88 | fr = (struct emuframe __user *) |
@@ -72,14 +92,18 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
72 | if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe)))) | 92 | if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe)))) |
73 | return SIGBUS; | 93 | return SIGBUS; |
74 | 94 | ||
75 | if (get_isa16_mode(regs->cp0_epc)) { | 95 | if (isa16) { |
76 | err = __put_user(ir >> 16, (u16 __user *)(&fr->emul)); | 96 | err = __put_user(ir >> 16, |
77 | err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2)); | 97 | (u16 __user *)(&fr->emul)); |
78 | err |= __put_user(BREAK_MATH >> 16, (u16 __user *)(&fr->badinst)); | 98 | err |= __put_user(ir & 0xffff, |
79 | err |= __put_user(BREAK_MATH & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2)); | 99 | (u16 __user *)((long)(&fr->emul) + 2)); |
100 | err |= __put_user(break_math >> 16, | ||
101 | (u16 __user *)(&fr->badinst)); | ||
102 | err |= __put_user(break_math & 0xffff, | ||
103 | (u16 __user *)((long)(&fr->badinst) + 2)); | ||
80 | } else { | 104 | } else { |
81 | err = __put_user(ir, &fr->emul); | 105 | err = __put_user(ir, &fr->emul); |
82 | err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst); | 106 | err |= __put_user(break_math, &fr->badinst); |
83 | } | 107 | } |
84 | 108 | ||
85 | err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); | 109 | err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); |
@@ -90,8 +114,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
90 | return SIGBUS; | 114 | return SIGBUS; |
91 | } | 115 | } |
92 | 116 | ||
93 | regs->cp0_epc = ((unsigned long) &fr->emul) | | 117 | regs->cp0_epc = (unsigned long)&fr->emul | isa16; |
94 | get_isa16_mode(regs->cp0_epc); | ||
95 | 118 | ||
96 | flush_cache_sigtramp((unsigned long)&fr->emul); | 119 | flush_cache_sigtramp((unsigned long)&fr->emul); |
97 | 120 | ||
@@ -100,6 +123,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
100 | 123 | ||
101 | int do_dsemulret(struct pt_regs *xcp) | 124 | int do_dsemulret(struct pt_regs *xcp) |
102 | { | 125 | { |
126 | int isa16 = get_isa16_mode(xcp->cp0_epc); | ||
103 | struct emuframe __user *fr; | 127 | struct emuframe __user *fr; |
104 | unsigned long epc; | 128 | unsigned long epc; |
105 | u32 insn, cookie; | 129 | u32 insn, cookie; |
@@ -122,16 +146,19 @@ int do_dsemulret(struct pt_regs *xcp) | |||
122 | * - Is the instruction pointed to by the EPC an BREAK_MATH? | 146 | * - Is the instruction pointed to by the EPC an BREAK_MATH? |
123 | * - Is the following memory word the BD_COOKIE? | 147 | * - Is the following memory word the BD_COOKIE? |
124 | */ | 148 | */ |
125 | if (get_isa16_mode(xcp->cp0_epc)) { | 149 | if (isa16) { |
126 | err = __get_user(instr[0], (u16 __user *)(&fr->badinst)); | 150 | err = __get_user(instr[0], |
127 | err |= __get_user(instr[1], (u16 __user *)((long)(&fr->badinst) + 2)); | 151 | (u16 __user *)(&fr->badinst)); |
152 | err |= __get_user(instr[1], | ||
153 | (u16 __user *)((long)(&fr->badinst) + 2)); | ||
128 | insn = (instr[0] << 16) | instr[1]; | 154 | insn = (instr[0] << 16) | instr[1]; |
129 | } else { | 155 | } else { |
130 | err = __get_user(insn, &fr->badinst); | 156 | err = __get_user(insn, &fr->badinst); |
131 | } | 157 | } |
132 | err |= __get_user(cookie, &fr->cookie); | 158 | err |= __get_user(cookie, &fr->cookie); |
133 | 159 | ||
134 | if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { | 160 | if (unlikely(err || |
161 | insn != BREAK_MATH(isa16) || cookie != BD_COOKIE)) { | ||
135 | MIPS_FPU_EMU_INC_STATS(errors); | 162 | MIPS_FPU_EMU_INC_STATS(errors); |
136 | return 0; | 163 | return 0; |
137 | } | 164 | } |
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c index 8e97acbbe22c..e16ae7b75dbb 100644 --- a/arch/mips/math-emu/ieee754.c +++ b/arch/mips/math-emu/ieee754.c | |||
@@ -59,7 +59,8 @@ const union ieee754dp __ieee754dp_spcvals[] = { | |||
59 | DPCNST(1, 3, 0x4000000000000ULL), /* - 10.0 */ | 59 | DPCNST(1, 3, 0x4000000000000ULL), /* - 10.0 */ |
60 | DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL), /* + infinity */ | 60 | DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL), /* + infinity */ |
61 | DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL), /* - infinity */ | 61 | DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL), /* - infinity */ |
62 | DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL), /* + indef quiet Nan */ | 62 | DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL), /* + ind legacy qNaN */ |
63 | DPCNST(0, DP_EMAX + 1, 0x8000000000000ULL), /* + indef 2008 qNaN */ | ||
63 | DPCNST(0, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* + max */ | 64 | DPCNST(0, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* + max */ |
64 | DPCNST(1, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* - max */ | 65 | DPCNST(1, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* - max */ |
65 | DPCNST(0, DP_EMIN, 0x0000000000000ULL), /* + min normal */ | 66 | DPCNST(0, DP_EMIN, 0x0000000000000ULL), /* + min normal */ |
@@ -82,7 +83,8 @@ const union ieee754sp __ieee754sp_spcvals[] = { | |||
82 | SPCNST(1, 3, 0x200000), /* - 10.0 */ | 83 | SPCNST(1, 3, 0x200000), /* - 10.0 */ |
83 | SPCNST(0, SP_EMAX + 1, 0x000000), /* + infinity */ | 84 | SPCNST(0, SP_EMAX + 1, 0x000000), /* + infinity */ |
84 | SPCNST(1, SP_EMAX + 1, 0x000000), /* - infinity */ | 85 | SPCNST(1, SP_EMAX + 1, 0x000000), /* - infinity */ |
85 | SPCNST(0, SP_EMAX + 1, 0x3FFFFF), /* + indef quiet Nan */ | 86 | SPCNST(0, SP_EMAX + 1, 0x3FFFFF), /* + indef legacy quiet NaN */ |
87 | SPCNST(0, SP_EMAX + 1, 0x400000), /* + indef 2008 quiet NaN */ | ||
86 | SPCNST(0, SP_EMAX, 0x7FFFFF), /* + max normal */ | 88 | SPCNST(0, SP_EMAX, 0x7FFFFF), /* + max normal */ |
87 | SPCNST(1, SP_EMAX, 0x7FFFFF), /* - max normal */ | 89 | SPCNST(1, SP_EMAX, 0x7FFFFF), /* - max normal */ |
88 | SPCNST(0, SP_EMIN, 0x000000), /* + min normal */ | 90 | SPCNST(0, SP_EMIN, 0x000000), /* + min normal */ |
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h index df94720714c7..d3be351aed15 100644 --- a/arch/mips/math-emu/ieee754.h +++ b/arch/mips/math-emu/ieee754.h | |||
@@ -221,15 +221,16 @@ union ieee754dp ieee754dp_dump(char *s, union ieee754dp x); | |||
221 | #define IEEE754_SPCVAL_NTEN 5 /* -10.0 */ | 221 | #define IEEE754_SPCVAL_NTEN 5 /* -10.0 */ |
222 | #define IEEE754_SPCVAL_PINFINITY 6 /* +inf */ | 222 | #define IEEE754_SPCVAL_PINFINITY 6 /* +inf */ |
223 | #define IEEE754_SPCVAL_NINFINITY 7 /* -inf */ | 223 | #define IEEE754_SPCVAL_NINFINITY 7 /* -inf */ |
224 | #define IEEE754_SPCVAL_INDEF 8 /* quiet NaN */ | 224 | #define IEEE754_SPCVAL_INDEF_LEG 8 /* legacy quiet NaN */ |
225 | #define IEEE754_SPCVAL_PMAX 9 /* +max norm */ | 225 | #define IEEE754_SPCVAL_INDEF_2008 9 /* IEEE 754-2008 quiet NaN */ |
226 | #define IEEE754_SPCVAL_NMAX 10 /* -max norm */ | 226 | #define IEEE754_SPCVAL_PMAX 10 /* +max norm */ |
227 | #define IEEE754_SPCVAL_PMIN 11 /* +min norm */ | 227 | #define IEEE754_SPCVAL_NMAX 11 /* -max norm */ |
228 | #define IEEE754_SPCVAL_NMIN 12 /* -min norm */ | 228 | #define IEEE754_SPCVAL_PMIN 12 /* +min norm */ |
229 | #define IEEE754_SPCVAL_PMIND 13 /* +min denorm */ | 229 | #define IEEE754_SPCVAL_NMIN 13 /* -min norm */ |
230 | #define IEEE754_SPCVAL_NMIND 14 /* -min denorm */ | 230 | #define IEEE754_SPCVAL_PMIND 14 /* +min denorm */ |
231 | #define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */ | 231 | #define IEEE754_SPCVAL_NMIND 15 /* -min denorm */ |
232 | #define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */ | 232 | #define IEEE754_SPCVAL_P1E31 16 /* + 1.0e31 */ |
233 | #define IEEE754_SPCVAL_P1E63 17 /* + 1.0e63 */ | ||
233 | 234 | ||
234 | extern const union ieee754dp __ieee754dp_spcvals[]; | 235 | extern const union ieee754dp __ieee754dp_spcvals[]; |
235 | extern const union ieee754sp __ieee754sp_spcvals[]; | 236 | extern const union ieee754sp __ieee754sp_spcvals[]; |
@@ -243,7 +244,8 @@ extern const union ieee754sp __ieee754sp_spcvals[]; | |||
243 | #define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) | 244 | #define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) |
244 | #define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) | 245 | #define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) |
245 | #define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) | 246 | #define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) |
246 | #define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF]) | 247 | #define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \ |
248 | ieee754_csr.nan2008]) | ||
247 | #define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) | 249 | #define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) |
248 | #define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) | 250 | #define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) |
249 | #define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) | 251 | #define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) |
@@ -254,7 +256,8 @@ extern const union ieee754sp __ieee754sp_spcvals[]; | |||
254 | #define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) | 256 | #define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) |
255 | #define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) | 257 | #define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) |
256 | #define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) | 258 | #define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) |
257 | #define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF]) | 259 | #define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \ |
260 | ieee754_csr.nan2008]) | ||
258 | #define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) | 261 | #define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) |
259 | #define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) | 262 | #define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) |
260 | #define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) | 263 | #define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) |
@@ -266,12 +269,25 @@ extern const union ieee754sp __ieee754sp_spcvals[]; | |||
266 | */ | 269 | */ |
267 | static inline int ieee754si_indef(void) | 270 | static inline int ieee754si_indef(void) |
268 | { | 271 | { |
269 | return INT_MAX; | 272 | return ieee754_csr.nan2008 ? 0 : INT_MAX; |
270 | } | 273 | } |
271 | 274 | ||
272 | static inline s64 ieee754di_indef(void) | 275 | static inline s64 ieee754di_indef(void) |
273 | { | 276 | { |
274 | return S64_MAX; | 277 | return ieee754_csr.nan2008 ? 0 : S64_MAX; |
278 | } | ||
279 | |||
280 | /* | ||
281 | * Overflow integer value | ||
282 | */ | ||
283 | static inline int ieee754si_overflow(int xs) | ||
284 | { | ||
285 | return ieee754_csr.nan2008 && xs ? INT_MIN : INT_MAX; | ||
286 | } | ||
287 | |||
288 | static inline s64 ieee754di_overflow(int xs) | ||
289 | { | ||
290 | return ieee754_csr.nan2008 && xs ? S64_MIN : S64_MAX; | ||
275 | } | 291 | } |
276 | 292 | ||
277 | /* result types for xctx.rt */ | 293 | /* result types for xctx.rt */ |
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c index 522d843f2ffd..ad3c73436777 100644 --- a/arch/mips/math-emu/ieee754dp.c +++ b/arch/mips/math-emu/ieee754dp.c | |||
@@ -37,8 +37,11 @@ static inline int ieee754dp_isnan(union ieee754dp x) | |||
37 | 37 | ||
38 | static inline int ieee754dp_issnan(union ieee754dp x) | 38 | static inline int ieee754dp_issnan(union ieee754dp x) |
39 | { | 39 | { |
40 | int qbit; | ||
41 | |||
40 | assert(ieee754dp_isnan(x)); | 42 | assert(ieee754dp_isnan(x)); |
41 | return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1); | 43 | qbit = (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1); |
44 | return ieee754_csr.nan2008 ^ qbit; | ||
42 | } | 45 | } |
43 | 46 | ||
44 | 47 | ||
@@ -51,7 +54,12 @@ union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r) | |||
51 | assert(ieee754dp_issnan(r)); | 54 | assert(ieee754dp_issnan(r)); |
52 | 55 | ||
53 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 56 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
54 | return ieee754dp_indef(); | 57 | if (ieee754_csr.nan2008) |
58 | DPMANT(r) |= DP_MBIT(DP_FBITS - 1); | ||
59 | else | ||
60 | r = ieee754dp_indef(); | ||
61 | |||
62 | return r; | ||
55 | } | 63 | } |
56 | 64 | ||
57 | static u64 ieee754dp_get_rounding(int sn, u64 xm) | 65 | static u64 ieee754dp_get_rounding(int sn, u64 xm) |
diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h index 6383e2c5c1ad..ed7bb277b3e0 100644 --- a/arch/mips/math-emu/ieee754int.h +++ b/arch/mips/math-emu/ieee754int.h | |||
@@ -63,10 +63,10 @@ static inline int ieee754_class_nan(int xc) | |||
63 | if (ve == SP_EMAX+1+SP_EBIAS) { \ | 63 | if (ve == SP_EMAX+1+SP_EBIAS) { \ |
64 | if (vm == 0) \ | 64 | if (vm == 0) \ |
65 | vc = IEEE754_CLASS_INF; \ | 65 | vc = IEEE754_CLASS_INF; \ |
66 | else if (vm & SP_MBIT(SP_FBITS-1)) \ | 66 | else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \ |
67 | vc = IEEE754_CLASS_SNAN; \ | ||
68 | else \ | ||
69 | vc = IEEE754_CLASS_QNAN; \ | 67 | vc = IEEE754_CLASS_QNAN; \ |
68 | else \ | ||
69 | vc = IEEE754_CLASS_SNAN; \ | ||
70 | } else if (ve == SP_EMIN-1+SP_EBIAS) { \ | 70 | } else if (ve == SP_EMIN-1+SP_EBIAS) { \ |
71 | if (vm) { \ | 71 | if (vm) { \ |
72 | ve = SP_EMIN; \ | 72 | ve = SP_EMIN; \ |
@@ -97,10 +97,10 @@ static inline int ieee754_class_nan(int xc) | |||
97 | if (ve == DP_EMAX+1+DP_EBIAS) { \ | 97 | if (ve == DP_EMAX+1+DP_EBIAS) { \ |
98 | if (vm == 0) \ | 98 | if (vm == 0) \ |
99 | vc = IEEE754_CLASS_INF; \ | 99 | vc = IEEE754_CLASS_INF; \ |
100 | else if (vm & DP_MBIT(DP_FBITS-1)) \ | 100 | else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \ |
101 | vc = IEEE754_CLASS_SNAN; \ | ||
102 | else \ | ||
103 | vc = IEEE754_CLASS_QNAN; \ | 101 | vc = IEEE754_CLASS_QNAN; \ |
102 | else \ | ||
103 | vc = IEEE754_CLASS_SNAN; \ | ||
104 | } else if (ve == DP_EMIN-1+DP_EBIAS) { \ | 104 | } else if (ve == DP_EMIN-1+DP_EBIAS) { \ |
105 | if (vm) { \ | 105 | if (vm) { \ |
106 | ve = DP_EMIN; \ | 106 | ve = DP_EMIN; \ |
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c index ca8e35e33bf7..def00ffc50fc 100644 --- a/arch/mips/math-emu/ieee754sp.c +++ b/arch/mips/math-emu/ieee754sp.c | |||
@@ -37,8 +37,11 @@ static inline int ieee754sp_isnan(union ieee754sp x) | |||
37 | 37 | ||
38 | static inline int ieee754sp_issnan(union ieee754sp x) | 38 | static inline int ieee754sp_issnan(union ieee754sp x) |
39 | { | 39 | { |
40 | int qbit; | ||
41 | |||
40 | assert(ieee754sp_isnan(x)); | 42 | assert(ieee754sp_isnan(x)); |
41 | return SPMANT(x) & SP_MBIT(SP_FBITS - 1); | 43 | qbit = (SPMANT(x) & SP_MBIT(SP_FBITS - 1)) == SP_MBIT(SP_FBITS - 1); |
44 | return ieee754_csr.nan2008 ^ qbit; | ||
42 | } | 45 | } |
43 | 46 | ||
44 | 47 | ||
@@ -51,7 +54,12 @@ union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r) | |||
51 | assert(ieee754sp_issnan(r)); | 54 | assert(ieee754sp_issnan(r)); |
52 | 55 | ||
53 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 56 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
54 | return ieee754sp_indef(); | 57 | if (ieee754_csr.nan2008) |
58 | SPMANT(r) |= SP_MBIT(SP_FBITS - 1); | ||
59 | else | ||
60 | r = ieee754sp_indef(); | ||
61 | |||
62 | return r; | ||
55 | } | 63 | } |
56 | 64 | ||
57 | static unsigned ieee754sp_get_rounding(int sn, unsigned xm) | 65 | static unsigned ieee754sp_get_rounding(int sn, unsigned xm) |
diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c index 3797148893ad..5060e8fdcb0b 100644 --- a/arch/mips/math-emu/sp_fdp.c +++ b/arch/mips/math-emu/sp_fdp.c | |||
@@ -44,13 +44,16 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x) | |||
44 | 44 | ||
45 | switch (xc) { | 45 | switch (xc) { |
46 | case IEEE754_CLASS_SNAN: | 46 | case IEEE754_CLASS_SNAN: |
47 | return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm)); | 47 | x = ieee754dp_nanxcpt(x); |
48 | 48 | EXPLODEXDP; | |
49 | /* Fall through. */ | ||
49 | case IEEE754_CLASS_QNAN: | 50 | case IEEE754_CLASS_QNAN: |
50 | y = ieee754sp_nan_fdp(xs, xm); | 51 | y = ieee754sp_nan_fdp(xs, xm); |
51 | EXPLODEYSP; | 52 | if (!ieee754_csr.nan2008) { |
52 | if (!ieee754_class_nan(yc)) | 53 | EXPLODEYSP; |
53 | y = ieee754sp_indef(); | 54 | if (!ieee754_class_nan(yc)) |
55 | y = ieee754sp_indef(); | ||
56 | } | ||
54 | return y; | 57 | return y; |
55 | 58 | ||
56 | case IEEE754_CLASS_INF: | 59 | case IEEE754_CLASS_INF: |
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c index c50e9451f2d2..756c9cf2dfd2 100644 --- a/arch/mips/math-emu/sp_simple.c +++ b/arch/mips/math-emu/sp_simple.c | |||
@@ -23,27 +23,39 @@ | |||
23 | 23 | ||
24 | union ieee754sp ieee754sp_neg(union ieee754sp x) | 24 | union ieee754sp ieee754sp_neg(union ieee754sp x) |
25 | { | 25 | { |
26 | unsigned int oldrm; | ||
27 | union ieee754sp y; | 26 | union ieee754sp y; |
28 | 27 | ||
29 | oldrm = ieee754_csr.rm; | 28 | if (ieee754_csr.abs2008) { |
30 | ieee754_csr.rm = FPU_CSR_RD; | 29 | y = x; |
31 | y = ieee754sp_sub(ieee754sp_zero(0), x); | 30 | SPSIGN(y) = !SPSIGN(x); |
32 | ieee754_csr.rm = oldrm; | 31 | } else { |
32 | unsigned int oldrm; | ||
33 | |||
34 | oldrm = ieee754_csr.rm; | ||
35 | ieee754_csr.rm = FPU_CSR_RD; | ||
36 | y = ieee754sp_sub(ieee754sp_zero(0), x); | ||
37 | ieee754_csr.rm = oldrm; | ||
38 | } | ||
33 | return y; | 39 | return y; |
34 | } | 40 | } |
35 | 41 | ||
36 | union ieee754sp ieee754sp_abs(union ieee754sp x) | 42 | union ieee754sp ieee754sp_abs(union ieee754sp x) |
37 | { | 43 | { |
38 | unsigned int oldrm; | ||
39 | union ieee754sp y; | 44 | union ieee754sp y; |
40 | 45 | ||
41 | oldrm = ieee754_csr.rm; | 46 | if (ieee754_csr.abs2008) { |
42 | ieee754_csr.rm = FPU_CSR_RD; | 47 | y = x; |
43 | if (SPSIGN(x)) | 48 | SPSIGN(y) = 0; |
44 | y = ieee754sp_sub(ieee754sp_zero(0), x); | 49 | } else { |
45 | else | 50 | unsigned int oldrm; |
46 | y = ieee754sp_add(ieee754sp_zero(0), x); | 51 | |
47 | ieee754_csr.rm = oldrm; | 52 | oldrm = ieee754_csr.rm; |
53 | ieee754_csr.rm = FPU_CSR_RD; | ||
54 | if (SPSIGN(x)) | ||
55 | y = ieee754sp_sub(ieee754sp_zero(0), x); | ||
56 | else | ||
57 | y = ieee754sp_add(ieee754sp_zero(0), x); | ||
58 | ieee754_csr.rm = oldrm; | ||
59 | } | ||
48 | return y; | 60 | return y; |
49 | } | 61 | } |
diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c index 091299a31798..f4b4cabfe2e1 100644 --- a/arch/mips/math-emu/sp_tint.c +++ b/arch/mips/math-emu/sp_tint.c | |||
@@ -38,10 +38,13 @@ int ieee754sp_tint(union ieee754sp x) | |||
38 | switch (xc) { | 38 | switch (xc) { |
39 | case IEEE754_CLASS_SNAN: | 39 | case IEEE754_CLASS_SNAN: |
40 | case IEEE754_CLASS_QNAN: | 40 | case IEEE754_CLASS_QNAN: |
41 | case IEEE754_CLASS_INF: | ||
42 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 41 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
43 | return ieee754si_indef(); | 42 | return ieee754si_indef(); |
44 | 43 | ||
44 | case IEEE754_CLASS_INF: | ||
45 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
46 | return ieee754si_overflow(xs); | ||
47 | |||
45 | case IEEE754_CLASS_ZERO: | 48 | case IEEE754_CLASS_ZERO: |
46 | return 0; | 49 | return 0; |
47 | 50 | ||
@@ -56,7 +59,7 @@ int ieee754sp_tint(union ieee754sp x) | |||
56 | /* Set invalid. We will only use overflow for floating | 59 | /* Set invalid. We will only use overflow for floating |
57 | point overflow */ | 60 | point overflow */ |
58 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 61 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
59 | return ieee754si_indef(); | 62 | return ieee754si_overflow(xs); |
60 | } | 63 | } |
61 | /* oh gawd */ | 64 | /* oh gawd */ |
62 | if (xe > SP_FBITS) { | 65 | if (xe > SP_FBITS) { |
@@ -97,7 +100,7 @@ int ieee754sp_tint(union ieee754sp x) | |||
97 | if ((xm >> 31) != 0) { | 100 | if ((xm >> 31) != 0) { |
98 | /* This can happen after rounding */ | 101 | /* This can happen after rounding */ |
99 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 102 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
100 | return ieee754si_indef(); | 103 | return ieee754si_overflow(xs); |
101 | } | 104 | } |
102 | if (round || sticky) | 105 | if (round || sticky) |
103 | ieee754_setcx(IEEE754_INEXACT); | 106 | ieee754_setcx(IEEE754_INEXACT); |
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c index 9f3c742c1cea..a2450c7e452a 100644 --- a/arch/mips/math-emu/sp_tlong.c +++ b/arch/mips/math-emu/sp_tlong.c | |||
@@ -39,10 +39,13 @@ s64 ieee754sp_tlong(union ieee754sp x) | |||
39 | switch (xc) { | 39 | switch (xc) { |
40 | case IEEE754_CLASS_SNAN: | 40 | case IEEE754_CLASS_SNAN: |
41 | case IEEE754_CLASS_QNAN: | 41 | case IEEE754_CLASS_QNAN: |
42 | case IEEE754_CLASS_INF: | ||
43 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 42 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
44 | return ieee754di_indef(); | 43 | return ieee754di_indef(); |
45 | 44 | ||
45 | case IEEE754_CLASS_INF: | ||
46 | ieee754_setcx(IEEE754_INVALID_OPERATION); | ||
47 | return ieee754di_overflow(xs); | ||
48 | |||
46 | case IEEE754_CLASS_ZERO: | 49 | case IEEE754_CLASS_ZERO: |
47 | return 0; | 50 | return 0; |
48 | 51 | ||
@@ -57,7 +60,7 @@ s64 ieee754sp_tlong(union ieee754sp x) | |||
57 | /* Set invalid. We will only use overflow for floating | 60 | /* Set invalid. We will only use overflow for floating |
58 | point overflow */ | 61 | point overflow */ |
59 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 62 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
60 | return ieee754di_indef(); | 63 | return ieee754di_overflow(xs); |
61 | } | 64 | } |
62 | /* oh gawd */ | 65 | /* oh gawd */ |
63 | if (xe > SP_FBITS) { | 66 | if (xe > SP_FBITS) { |
@@ -94,7 +97,7 @@ s64 ieee754sp_tlong(union ieee754sp x) | |||
94 | if ((xm >> 63) != 0) { | 97 | if ((xm >> 63) != 0) { |
95 | /* This can happen after rounding */ | 98 | /* This can happen after rounding */ |
96 | ieee754_setcx(IEEE754_INVALID_OPERATION); | 99 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
97 | return ieee754di_indef(); | 100 | return ieee754di_overflow(xs); |
98 | } | 101 | } |
99 | if (round || sticky) | 102 | if (round || sticky) |
100 | ieee754_setcx(IEEE754_INEXACT); | 103 | ieee754_setcx(IEEE754_INEXACT); |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 482192cc8f2b..5a04b6f5c6fb 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -241,7 +241,7 @@ static void output_pgtable_bits_defines(void) | |||
241 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 241 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
242 | pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); | 242 | pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); |
243 | #endif | 243 | #endif |
244 | #ifdef CONFIG_CPU_MIPSR2 | 244 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) |
245 | if (cpu_has_rixi) { | 245 | if (cpu_has_rixi) { |
246 | #ifdef _PAGE_NO_EXEC_SHIFT | 246 | #ifdef _PAGE_NO_EXEC_SHIFT |
247 | pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); | 247 | pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); |
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 2eda01e6e08f..139ad1d7ab5e 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -43,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o | |||
43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o | 43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o |
44 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o | 44 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o |
45 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o | 45 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o |
46 | obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o | ||
46 | obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o | 47 | obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o |
47 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o | 48 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o |
48 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o | 49 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o |
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c new file mode 100644 index 000000000000..a009ee458934 --- /dev/null +++ b/arch/mips/pci/pci-mt7620.c | |||
@@ -0,0 +1,426 @@ | |||
1 | /* | ||
2 | * Ralink MT7620A SoC PCI support | ||
3 | * | ||
4 | * Copyright (C) 2007-2013 Bruce Chang (Mediatek) | ||
5 | * Copyright (C) 2013-2016 John Crispin <blogic@openwrt.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published | ||
9 | * by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/of_pci.h> | ||
22 | #include <linux/reset.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | |||
25 | #include <asm/mach-ralink/ralink_regs.h> | ||
26 | #include <asm/mach-ralink/mt7620.h> | ||
27 | |||
28 | #define RALINK_PCI_IO_MAP_BASE 0x10160000 | ||
29 | #define RALINK_PCI_MEMORY_BASE 0x0 | ||
30 | |||
31 | #define RALINK_INT_PCIE0 4 | ||
32 | |||
33 | #define RALINK_CLKCFG1 0x30 | ||
34 | #define RALINK_GPIOMODE 0x60 | ||
35 | |||
36 | #define PPLL_CFG1 0x9c | ||
37 | #define PDRV_SW_SET BIT(23) | ||
38 | |||
39 | #define PPLL_DRV 0xa0 | ||
40 | #define PDRV_SW_SET (1<<31) | ||
41 | #define LC_CKDRVPD (1<<19) | ||
42 | #define LC_CKDRVOHZ (1<<18) | ||
43 | #define LC_CKDRVHZ (1<<17) | ||
44 | #define LC_CKTEST (1<<16) | ||
45 | |||
46 | /* PCI Bridge registers */ | ||
47 | #define RALINK_PCI_PCICFG_ADDR 0x00 | ||
48 | #define PCIRST BIT(1) | ||
49 | |||
50 | #define RALINK_PCI_PCIENA 0x0C | ||
51 | #define PCIINT2 BIT(20) | ||
52 | |||
53 | #define RALINK_PCI_CONFIG_ADDR 0x20 | ||
54 | #define RALINK_PCI_CONFIG_DATA_VIRT_REG 0x24 | ||
55 | #define RALINK_PCI_MEMBASE 0x28 | ||
56 | #define RALINK_PCI_IOBASE 0x2C | ||
57 | |||
58 | /* PCI RC registers */ | ||
59 | #define RALINK_PCI0_BAR0SETUP_ADDR 0x10 | ||
60 | #define RALINK_PCI0_IMBASEBAR0_ADDR 0x18 | ||
61 | #define RALINK_PCI0_ID 0x30 | ||
62 | #define RALINK_PCI0_CLASS 0x34 | ||
63 | #define RALINK_PCI0_SUBID 0x38 | ||
64 | #define RALINK_PCI0_STATUS 0x50 | ||
65 | #define PCIE_LINK_UP_ST BIT(0) | ||
66 | |||
67 | #define PCIEPHY0_CFG 0x90 | ||
68 | |||
69 | #define RALINK_PCIEPHY_P0_CTL_OFFSET 0x7498 | ||
70 | #define RALINK_PCIE0_CLK_EN (1 << 26) | ||
71 | |||
72 | #define BUSY 0x80000000 | ||
73 | #define WAITRETRY_MAX 10 | ||
74 | #define WRITE_MODE (1UL << 23) | ||
75 | #define DATA_SHIFT 0 | ||
76 | #define ADDR_SHIFT 8 | ||
77 | |||
78 | |||
79 | static void __iomem *bridge_base; | ||
80 | static void __iomem *pcie_base; | ||
81 | |||
82 | static struct reset_control *rstpcie0; | ||
83 | |||
84 | static inline void bridge_w32(u32 val, unsigned reg) | ||
85 | { | ||
86 | iowrite32(val, bridge_base + reg); | ||
87 | } | ||
88 | |||
89 | static inline u32 bridge_r32(unsigned reg) | ||
90 | { | ||
91 | return ioread32(bridge_base + reg); | ||
92 | } | ||
93 | |||
94 | static inline void pcie_w32(u32 val, unsigned reg) | ||
95 | { | ||
96 | iowrite32(val, pcie_base + reg); | ||
97 | } | ||
98 | |||
99 | static inline u32 pcie_r32(unsigned reg) | ||
100 | { | ||
101 | return ioread32(pcie_base + reg); | ||
102 | } | ||
103 | |||
104 | static inline void pcie_m32(u32 clr, u32 set, unsigned reg) | ||
105 | { | ||
106 | u32 val = pcie_r32(reg); | ||
107 | |||
108 | val &= ~clr; | ||
109 | val |= set; | ||
110 | pcie_w32(val, reg); | ||
111 | } | ||
112 | |||
113 | static int wait_pciephy_busy(void) | ||
114 | { | ||
115 | unsigned long reg_value = 0x0, retry = 0; | ||
116 | |||
117 | while (1) { | ||
118 | reg_value = pcie_r32(PCIEPHY0_CFG); | ||
119 | |||
120 | if (reg_value & BUSY) | ||
121 | mdelay(100); | ||
122 | else | ||
123 | break; | ||
124 | if (retry++ > WAITRETRY_MAX) { | ||
125 | printk(KERN_WARN "PCIE-PHY retry failed.\n"); | ||
126 | return -1; | ||
127 | } | ||
128 | } | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static void pcie_phy(unsigned long addr, unsigned long val) | ||
133 | { | ||
134 | wait_pciephy_busy(); | ||
135 | pcie_w32(WRITE_MODE | (val << DATA_SHIFT) | (addr << ADDR_SHIFT), | ||
136 | PCIEPHY0_CFG); | ||
137 | mdelay(1); | ||
138 | wait_pciephy_busy(); | ||
139 | } | ||
140 | |||
141 | static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, | ||
142 | int size, u32 *val) | ||
143 | { | ||
144 | unsigned int slot = PCI_SLOT(devfn); | ||
145 | u8 func = PCI_FUNC(devfn); | ||
146 | u32 address; | ||
147 | u32 data; | ||
148 | u32 num = 0; | ||
149 | |||
150 | if (bus) | ||
151 | num = bus->number; | ||
152 | |||
153 | address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) | | ||
154 | (func << 8) | (where & 0xfc) | 0x80000000; | ||
155 | bridge_w32(address, RALINK_PCI_CONFIG_ADDR); | ||
156 | data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG); | ||
157 | |||
158 | switch (size) { | ||
159 | case 1: | ||
160 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
161 | break; | ||
162 | case 2: | ||
163 | *val = (data >> ((where & 3) << 3)) & 0xffff; | ||
164 | break; | ||
165 | case 4: | ||
166 | *val = data; | ||
167 | break; | ||
168 | } | ||
169 | |||
170 | return PCIBIOS_SUCCESSFUL; | ||
171 | } | ||
172 | |||
173 | static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, | ||
174 | int size, u32 val) | ||
175 | { | ||
176 | unsigned int slot = PCI_SLOT(devfn); | ||
177 | u8 func = PCI_FUNC(devfn); | ||
178 | u32 address; | ||
179 | u32 data; | ||
180 | u32 num = 0; | ||
181 | |||
182 | if (bus) | ||
183 | num = bus->number; | ||
184 | |||
185 | address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) | | ||
186 | (func << 8) | (where & 0xfc) | 0x80000000; | ||
187 | bridge_w32(address, RALINK_PCI_CONFIG_ADDR); | ||
188 | data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG); | ||
189 | |||
190 | switch (size) { | ||
191 | case 1: | ||
192 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
193 | (val << ((where & 3) << 3)); | ||
194 | break; | ||
195 | case 2: | ||
196 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
197 | (val << ((where & 3) << 3)); | ||
198 | break; | ||
199 | case 4: | ||
200 | data = val; | ||
201 | break; | ||
202 | } | ||
203 | |||
204 | bridge_w32(data, RALINK_PCI_CONFIG_DATA_VIRT_REG); | ||
205 | |||
206 | return PCIBIOS_SUCCESSFUL; | ||
207 | } | ||
208 | |||
209 | struct pci_ops mt7620_pci_ops = { | ||
210 | .read = pci_config_read, | ||
211 | .write = pci_config_write, | ||
212 | }; | ||
213 | |||
214 | static struct resource mt7620_res_pci_mem1; | ||
215 | static struct resource mt7620_res_pci_io1; | ||
216 | struct pci_controller mt7620_controller = { | ||
217 | .pci_ops = &mt7620_pci_ops, | ||
218 | .mem_resource = &mt7620_res_pci_mem1, | ||
219 | .mem_offset = 0x00000000UL, | ||
220 | .io_resource = &mt7620_res_pci_io1, | ||
221 | .io_offset = 0x00000000UL, | ||
222 | .io_map_base = 0xa0000000, | ||
223 | }; | ||
224 | |||
225 | static int mt7620_pci_hw_init(struct platform_device *pdev) | ||
226 | { | ||
227 | /* bypass PCIe DLL */ | ||
228 | pcie_phy(0x0, 0x80); | ||
229 | pcie_phy(0x1, 0x04); | ||
230 | |||
231 | /* Elastic buffer control */ | ||
232 | pcie_phy(0x68, 0xB4); | ||
233 | |||
234 | /* put core into reset */ | ||
235 | pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR); | ||
236 | reset_control_assert(rstpcie0); | ||
237 | |||
238 | /* disable power and all clocks */ | ||
239 | rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1); | ||
240 | rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV); | ||
241 | |||
242 | /* bring core out of reset */ | ||
243 | reset_control_deassert(rstpcie0); | ||
244 | rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1); | ||
245 | mdelay(100); | ||
246 | |||
247 | if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) { | ||
248 | dev_err(&pdev->dev, "MT7620 PPLL unlock\n"); | ||
249 | reset_control_assert(rstpcie0); | ||
250 | rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1); | ||
251 | return -1; | ||
252 | } | ||
253 | |||
254 | /* power up the bus */ | ||
255 | rt_sysc_m32(LC_CKDRVHZ | LC_CKDRVOHZ, LC_CKDRVPD | PDRV_SW_SET, | ||
256 | PPLL_DRV); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static int mt7628_pci_hw_init(struct platform_device *pdev) | ||
262 | { | ||
263 | u32 val = 0; | ||
264 | |||
265 | /* bring the core out of reset */ | ||
266 | rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE); | ||
267 | reset_control_deassert(rstpcie0); | ||
268 | |||
269 | /* enable the pci clk */ | ||
270 | rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1); | ||
271 | mdelay(100); | ||
272 | |||
273 | /* voodoo from the SDK driver */ | ||
274 | pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET); | ||
275 | |||
276 | pci_config_read(NULL, 0, 0x70c, 4, &val); | ||
277 | val &= ~(0xff) << 8; | ||
278 | val |= 0x50 << 8; | ||
279 | pci_config_write(NULL, 0, 0x70c, 4, val); | ||
280 | |||
281 | pci_config_read(NULL, 0, 0x70c, 4, &val); | ||
282 | dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int mt7620_pci_probe(struct platform_device *pdev) | ||
288 | { | ||
289 | struct resource *bridge_res = platform_get_resource(pdev, | ||
290 | IORESOURCE_MEM, 0); | ||
291 | struct resource *pcie_res = platform_get_resource(pdev, | ||
292 | IORESOURCE_MEM, 1); | ||
293 | u32 val = 0; | ||
294 | |||
295 | rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0"); | ||
296 | if (IS_ERR(rstpcie0)) | ||
297 | return PTR_ERR(rstpcie0); | ||
298 | |||
299 | bridge_base = devm_ioremap_resource(&pdev->dev, bridge_res); | ||
300 | if (!bridge_base) | ||
301 | return -ENOMEM; | ||
302 | |||
303 | pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res); | ||
304 | if (!pcie_base) | ||
305 | return -ENOMEM; | ||
306 | |||
307 | iomem_resource.start = 0; | ||
308 | iomem_resource.end = ~0; | ||
309 | ioport_resource.start = 0; | ||
310 | ioport_resource.end = ~0; | ||
311 | |||
312 | /* bring up the pci core */ | ||
313 | switch (ralink_soc) { | ||
314 | case MT762X_SOC_MT7620A: | ||
315 | if (mt7620_pci_hw_init(pdev)) | ||
316 | return -1; | ||
317 | break; | ||
318 | |||
319 | case MT762X_SOC_MT7628AN: | ||
320 | if (mt7628_pci_hw_init(pdev)) | ||
321 | return -1; | ||
322 | break; | ||
323 | |||
324 | default: | ||
325 | dev_err(&pdev->dev, "pcie is not supported on this hardware\n"); | ||
326 | return -1; | ||
327 | } | ||
328 | mdelay(50); | ||
329 | |||
330 | /* enable write access */ | ||
331 | pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR); | ||
332 | mdelay(100); | ||
333 | |||
334 | /* check if there is a card present */ | ||
335 | if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) { | ||
336 | reset_control_assert(rstpcie0); | ||
337 | rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1); | ||
338 | if (ralink_soc == MT762X_SOC_MT7620A) | ||
339 | rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV); | ||
340 | dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n"); | ||
341 | return -1; | ||
342 | } | ||
343 | |||
344 | /* setup ranges */ | ||
345 | bridge_w32(0xffffffff, RALINK_PCI_MEMBASE); | ||
346 | bridge_w32(RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE); | ||
347 | |||
348 | pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR); | ||
349 | pcie_w32(RALINK_PCI_MEMORY_BASE, RALINK_PCI0_IMBASEBAR0_ADDR); | ||
350 | pcie_w32(0x06040001, RALINK_PCI0_CLASS); | ||
351 | |||
352 | /* enable interrupts */ | ||
353 | pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA); | ||
354 | |||
355 | /* voodoo from the SDK driver */ | ||
356 | pci_config_read(NULL, 0, 4, 4, &val); | ||
357 | pci_config_write(NULL, 0, 4, 4, val | 0x7); | ||
358 | |||
359 | pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node); | ||
360 | register_pci_controller(&mt7620_controller); | ||
361 | |||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
366 | { | ||
367 | u16 cmd; | ||
368 | u32 val; | ||
369 | int irq = 0; | ||
370 | |||
371 | if ((dev->bus->number == 0) && (slot == 0)) { | ||
372 | pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR); | ||
373 | pci_config_write(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, | ||
374 | RALINK_PCI_MEMORY_BASE); | ||
375 | pci_config_read(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, &val); | ||
376 | } else if ((dev->bus->number == 1) && (slot == 0x0)) { | ||
377 | irq = RALINK_INT_PCIE0; | ||
378 | } else { | ||
379 | dev_err(&dev->dev, "no irq found - bus=0x%x, slot = 0x%x\n", | ||
380 | dev->bus->number, slot); | ||
381 | return 0; | ||
382 | } | ||
383 | dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n", | ||
384 | dev->bus->number, slot, irq); | ||
385 | |||
386 | /* configure the cache line size to 0x14 */ | ||
387 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14); | ||
388 | |||
389 | /* configure latency timer to 0xff */ | ||
390 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xff); | ||
391 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
392 | |||
393 | /* setup the slot */ | ||
394 | cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; | ||
395 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
396 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
397 | |||
398 | return irq; | ||
399 | } | ||
400 | |||
401 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
402 | { | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static const struct of_device_id mt7620_pci_ids[] = { | ||
407 | { .compatible = "mediatek,mt7620-pci" }, | ||
408 | {}, | ||
409 | }; | ||
410 | MODULE_DEVICE_TABLE(of, mt7620_pci_ids); | ||
411 | |||
412 | static struct platform_driver mt7620_pci_driver = { | ||
413 | .probe = mt7620_pci_probe, | ||
414 | .driver = { | ||
415 | .name = "mt7620-pci", | ||
416 | .owner = THIS_MODULE, | ||
417 | .of_match_table = of_match_ptr(mt7620_pci_ids), | ||
418 | }, | ||
419 | }; | ||
420 | |||
421 | static int __init mt7620_pci_init(void) | ||
422 | { | ||
423 | return platform_driver_register(&mt7620_pci_driver); | ||
424 | } | ||
425 | |||
426 | arch_initcall(mt7620_pci_init); | ||
diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig new file mode 100644 index 000000000000..fde56a8b85ca --- /dev/null +++ b/arch/mips/pic32/Kconfig | |||
@@ -0,0 +1,51 @@ | |||
1 | if MACH_PIC32 | ||
2 | |||
3 | choice | ||
4 | prompt "Machine Type" | ||
5 | |||
6 | config PIC32MZDA | ||
7 | bool "Microchip PIC32MZDA Platform" | ||
8 | select BOOT_ELF32 | ||
9 | select BOOT_RAW | ||
10 | select CEVT_R4K | ||
11 | select CSRC_R4K | ||
12 | select DMA_NONCOHERENT | ||
13 | select SYS_HAS_CPU_MIPS32_R2 | ||
14 | select SYS_HAS_EARLY_PRINTK | ||
15 | select SYS_SUPPORTS_32BIT_KERNEL | ||
16 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
17 | select ARCH_REQUIRE_GPIOLIB | ||
18 | select HAVE_MACH_CLKDEV | ||
19 | select COMMON_CLK | ||
20 | select CLKDEV_LOOKUP | ||
21 | select LIBFDT | ||
22 | select USE_OF | ||
23 | select PINCTRL | ||
24 | select PIC32_EVIC | ||
25 | help | ||
26 | Support for the Microchip PIC32MZDA microcontroller. | ||
27 | |||
28 | This is a 32-bit microcontroller with support for external or | ||
29 | internally packaged DDR2 memory up to 128MB. | ||
30 | |||
31 | For more information, see <http://www.microchip.com/>. | ||
32 | |||
33 | endchoice | ||
34 | |||
35 | choice | ||
36 | prompt "Devicetree selection" | ||
37 | default DTB_PIC32_NONE | ||
38 | help | ||
39 | Select the devicetree. | ||
40 | |||
41 | config DTB_PIC32_NONE | ||
42 | bool "None" | ||
43 | |||
44 | config DTB_PIC32_MZDA_SK | ||
45 | bool "PIC32MZDA Starter Kit" | ||
46 | depends on PIC32MZDA | ||
47 | select BUILTIN_DTB | ||
48 | |||
49 | endchoice | ||
50 | |||
51 | endif # MACH_PIC32 | ||
diff --git a/arch/mips/pic32/Makefile b/arch/mips/pic32/Makefile new file mode 100644 index 000000000000..fd357f49ac6c --- /dev/null +++ b/arch/mips/pic32/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Joshua Henderson, <joshua.henderson@microchip.com> | ||
3 | # Copyright (C) 2015 Microchip Technology, Inc. All rights reserved. | ||
4 | # | ||
5 | obj-$(CONFIG_MACH_PIC32) += common/ | ||
6 | obj-$(CONFIG_PIC32MZDA) += pic32mzda/ | ||
diff --git a/arch/mips/pic32/Platform b/arch/mips/pic32/Platform new file mode 100644 index 000000000000..cd2084f44507 --- /dev/null +++ b/arch/mips/pic32/Platform | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # PIC32MZDA | ||
3 | # | ||
4 | platform-$(CONFIG_PIC32MZDA) += pic32/ | ||
5 | cflags-$(CONFIG_PIC32MZDA) += -I$(srctree)/arch/mips/include/asm/mach-pic32 | ||
6 | load-$(CONFIG_PIC32MZDA) += 0xffffffff88000000 | ||
7 | all-$(CONFIG_PIC32MZDA) := $(COMPRESSION_FNAME).bin | ||
diff --git a/arch/mips/pic32/common/Makefile b/arch/mips/pic32/common/Makefile new file mode 100644 index 000000000000..be1909cc0467 --- /dev/null +++ b/arch/mips/pic32/common/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Joshua Henderson, <joshua.henderson@microchip.com> | ||
3 | # Copyright (C) 2015 Microchip Technology, Inc. All rights reserved. | ||
4 | # | ||
5 | obj-y = reset.o irq.o | ||
diff --git a/arch/mips/pic32/common/irq.c b/arch/mips/pic32/common/irq.c new file mode 100644 index 000000000000..6df347e36036 --- /dev/null +++ b/arch/mips/pic32/common/irq.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/irqchip.h> | ||
16 | #include <asm/irq.h> | ||
17 | |||
18 | void __init arch_init_irq(void) | ||
19 | { | ||
20 | irqchip_init(); | ||
21 | } | ||
diff --git a/arch/mips/pic32/common/reset.c b/arch/mips/pic32/common/reset.c new file mode 100644 index 000000000000..83345757be5f --- /dev/null +++ b/arch/mips/pic32/common/reset.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/pm.h> | ||
16 | #include <asm/reboot.h> | ||
17 | #include <asm/mach-pic32/pic32.h> | ||
18 | |||
19 | #define PIC32_RSWRST 0x10 | ||
20 | |||
21 | static void pic32_halt(void) | ||
22 | { | ||
23 | while (1) { | ||
24 | __asm__(".set push;\n" | ||
25 | ".set arch=r4000;\n" | ||
26 | "wait;\n" | ||
27 | ".set pop;\n" | ||
28 | ); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | static void pic32_machine_restart(char *command) | ||
33 | { | ||
34 | void __iomem *reg = | ||
35 | ioremap(PIC32_BASE_RESET + PIC32_RSWRST, sizeof(u32)); | ||
36 | |||
37 | pic32_syskey_unlock(); | ||
38 | |||
39 | /* magic write/read */ | ||
40 | __raw_writel(1, reg); | ||
41 | (void)__raw_readl(reg); | ||
42 | |||
43 | pic32_halt(); | ||
44 | } | ||
45 | |||
46 | static void pic32_machine_halt(void) | ||
47 | { | ||
48 | local_irq_disable(); | ||
49 | |||
50 | pic32_halt(); | ||
51 | } | ||
52 | |||
53 | static int __init mips_reboot_setup(void) | ||
54 | { | ||
55 | _machine_restart = pic32_machine_restart; | ||
56 | _machine_halt = pic32_machine_halt; | ||
57 | pm_power_off = pic32_machine_halt; | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | arch_initcall(mips_reboot_setup); | ||
diff --git a/arch/mips/pic32/pic32mzda/Makefile b/arch/mips/pic32/pic32mzda/Makefile new file mode 100644 index 000000000000..4a4c2728c027 --- /dev/null +++ b/arch/mips/pic32/pic32mzda/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # | ||
2 | # Joshua Henderson, <joshua.henderson@microchip.com> | ||
3 | # Copyright (C) 2015 Microchip Technology, Inc. All rights reserved. | ||
4 | # | ||
5 | obj-y := init.o time.o config.o | ||
6 | |||
7 | obj-$(CONFIG_EARLY_PRINTK) += early_console.o \ | ||
8 | early_pin.o \ | ||
9 | early_clk.o | ||
diff --git a/arch/mips/pic32/pic32mzda/config.c b/arch/mips/pic32/pic32mzda/config.c new file mode 100644 index 000000000000..fe293a070003 --- /dev/null +++ b/arch/mips/pic32/pic32mzda/config.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * Purna Chandra Mandal, purna.mandal@microchip.com | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | |||
18 | #include <asm/mach-pic32/pic32.h> | ||
19 | |||
20 | #include "pic32mzda.h" | ||
21 | |||
22 | #define PIC32_CFGCON 0x0000 | ||
23 | #define PIC32_DEVID 0x0020 | ||
24 | #define PIC32_SYSKEY 0x0030 | ||
25 | #define PIC32_CFGEBIA 0x00c0 | ||
26 | #define PIC32_CFGEBIC 0x00d0 | ||
27 | #define PIC32_CFGCON2 0x00f0 | ||
28 | #define PIC32_RCON 0x1240 | ||
29 | |||
30 | static void __iomem *pic32_conf_base; | ||
31 | static DEFINE_SPINLOCK(config_lock); | ||
32 | static u32 pic32_reset_status; | ||
33 | |||
34 | static u32 pic32_conf_get_reg_field(u32 offset, u32 rshift, u32 mask) | ||
35 | { | ||
36 | u32 v; | ||
37 | |||
38 | v = readl(pic32_conf_base + offset); | ||
39 | v >>= rshift; | ||
40 | v &= mask; | ||
41 | |||
42 | return v; | ||
43 | } | ||
44 | |||
45 | static u32 pic32_conf_modify_atomic(u32 offset, u32 mask, u32 set) | ||
46 | { | ||
47 | u32 v; | ||
48 | unsigned long flags; | ||
49 | |||
50 | spin_lock_irqsave(&config_lock, flags); | ||
51 | v = readl(pic32_conf_base + offset); | ||
52 | v &= ~mask; | ||
53 | v |= (set & mask); | ||
54 | writel(v, pic32_conf_base + offset); | ||
55 | spin_unlock_irqrestore(&config_lock, flags); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | int pic32_enable_lcd(void) | ||
61 | { | ||
62 | return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), BIT(31)); | ||
63 | } | ||
64 | |||
65 | int pic32_disable_lcd(void) | ||
66 | { | ||
67 | return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(31), 0); | ||
68 | } | ||
69 | |||
70 | int pic32_set_lcd_mode(int mode) | ||
71 | { | ||
72 | u32 mask = mode ? BIT(30) : 0; | ||
73 | |||
74 | return pic32_conf_modify_atomic(PIC32_CFGCON2, BIT(30), mask); | ||
75 | } | ||
76 | |||
77 | int pic32_set_sdhci_adma_fifo_threshold(u32 rthrsh, u32 wthrsh) | ||
78 | { | ||
79 | u32 clr, set; | ||
80 | |||
81 | clr = (0x3ff << 4) | (0x3ff << 16); | ||
82 | set = (rthrsh << 4) | (wthrsh << 16); | ||
83 | return pic32_conf_modify_atomic(PIC32_CFGCON2, clr, set); | ||
84 | } | ||
85 | |||
86 | void pic32_syskey_unlock_debug(const char *func, const ulong line) | ||
87 | { | ||
88 | void __iomem *syskey = pic32_conf_base + PIC32_SYSKEY; | ||
89 | |||
90 | pr_debug("%s: called from %s:%lu\n", __func__, func, line); | ||
91 | writel(0x00000000, syskey); | ||
92 | writel(0xAA996655, syskey); | ||
93 | writel(0x556699AA, syskey); | ||
94 | } | ||
95 | |||
96 | static u32 pic32_get_device_id(void) | ||
97 | { | ||
98 | return pic32_conf_get_reg_field(PIC32_DEVID, 0, 0x0fffffff); | ||
99 | } | ||
100 | |||
101 | static u32 pic32_get_device_version(void) | ||
102 | { | ||
103 | return pic32_conf_get_reg_field(PIC32_DEVID, 28, 0xf); | ||
104 | } | ||
105 | |||
106 | u32 pic32_get_boot_status(void) | ||
107 | { | ||
108 | return pic32_reset_status; | ||
109 | } | ||
110 | EXPORT_SYMBOL(pic32_get_boot_status); | ||
111 | |||
112 | void __init pic32_config_init(void) | ||
113 | { | ||
114 | pic32_conf_base = ioremap(PIC32_BASE_CONFIG, 0x110); | ||
115 | if (!pic32_conf_base) | ||
116 | panic("pic32: config base not mapped"); | ||
117 | |||
118 | /* Boot Status */ | ||
119 | pic32_reset_status = readl(pic32_conf_base + PIC32_RCON); | ||
120 | writel(-1, PIC32_CLR(pic32_conf_base + PIC32_RCON)); | ||
121 | |||
122 | /* Device Inforation */ | ||
123 | pr_info("Device Id: 0x%08x, Device Ver: 0x%04x\n", | ||
124 | pic32_get_device_id(), | ||
125 | pic32_get_device_version()); | ||
126 | } | ||
diff --git a/arch/mips/pic32/pic32mzda/early_clk.c b/arch/mips/pic32/pic32mzda/early_clk.c new file mode 100644 index 000000000000..96c090e9d637 --- /dev/null +++ b/arch/mips/pic32/pic32mzda/early_clk.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <asm/mach-pic32/pic32.h> | ||
15 | |||
16 | #include "pic32mzda.h" | ||
17 | |||
18 | /* Oscillators, PLL & clocks */ | ||
19 | #define ICLK_MASK 0x00000080 | ||
20 | #define PLLDIV_MASK 0x00000007 | ||
21 | #define CUROSC_MASK 0x00000007 | ||
22 | #define PLLMUL_MASK 0x0000007F | ||
23 | #define PB_MASK 0x00000007 | ||
24 | #define FRC1 0 | ||
25 | #define FRC2 7 | ||
26 | #define SPLL 1 | ||
27 | #define POSC 2 | ||
28 | #define FRC_CLK 8000000 | ||
29 | |||
30 | #define PIC32_POSC_FREQ 24000000 | ||
31 | |||
32 | #define OSCCON 0x0000 | ||
33 | #define SPLLCON 0x0020 | ||
34 | #define PB1DIV 0x0140 | ||
35 | |||
36 | u32 pic32_get_sysclk(void) | ||
37 | { | ||
38 | u32 osc_freq = 0; | ||
39 | u32 pllclk; | ||
40 | u32 frcdivn; | ||
41 | u32 osccon; | ||
42 | u32 spllcon; | ||
43 | int curr_osc; | ||
44 | |||
45 | u32 plliclk; | ||
46 | u32 pllidiv; | ||
47 | u32 pllodiv; | ||
48 | u32 pllmult; | ||
49 | u32 frcdiv; | ||
50 | |||
51 | void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200); | ||
52 | |||
53 | osccon = __raw_readl(osc_base + OSCCON); | ||
54 | spllcon = __raw_readl(osc_base + SPLLCON); | ||
55 | |||
56 | plliclk = (spllcon & ICLK_MASK); | ||
57 | pllidiv = ((spllcon >> 8) & PLLDIV_MASK) + 1; | ||
58 | pllodiv = ((spllcon >> 24) & PLLDIV_MASK); | ||
59 | pllmult = ((spllcon >> 16) & PLLMUL_MASK) + 1; | ||
60 | frcdiv = ((osccon >> 24) & PLLDIV_MASK); | ||
61 | |||
62 | pllclk = plliclk ? FRC_CLK : PIC32_POSC_FREQ; | ||
63 | frcdivn = ((1 << frcdiv) + 1) + (128 * (frcdiv == 7)); | ||
64 | |||
65 | if (pllodiv < 2) | ||
66 | pllodiv = 2; | ||
67 | else if (pllodiv < 5) | ||
68 | pllodiv = (1 << pllodiv); | ||
69 | else | ||
70 | pllodiv = 32; | ||
71 | |||
72 | curr_osc = (int)((osccon >> 12) & CUROSC_MASK); | ||
73 | |||
74 | switch (curr_osc) { | ||
75 | case FRC1: | ||
76 | case FRC2: | ||
77 | osc_freq = FRC_CLK / frcdivn; | ||
78 | break; | ||
79 | case SPLL: | ||
80 | osc_freq = ((pllclk / pllidiv) * pllmult) / pllodiv; | ||
81 | break; | ||
82 | case POSC: | ||
83 | osc_freq = PIC32_POSC_FREQ; | ||
84 | break; | ||
85 | default: | ||
86 | break; | ||
87 | } | ||
88 | |||
89 | iounmap(osc_base); | ||
90 | |||
91 | return osc_freq; | ||
92 | } | ||
93 | |||
94 | u32 pic32_get_pbclk(int bus) | ||
95 | { | ||
96 | u32 clk_freq; | ||
97 | void __iomem *osc_base = ioremap(PIC32_BASE_OSC, 0x200); | ||
98 | u32 pbxdiv = PB1DIV + ((bus - 1) * 0x10); | ||
99 | u32 pbdiv = (__raw_readl(osc_base + pbxdiv) & PB_MASK) + 1; | ||
100 | |||
101 | iounmap(osc_base); | ||
102 | |||
103 | clk_freq = pic32_get_sysclk(); | ||
104 | |||
105 | return clk_freq / pbdiv; | ||
106 | } | ||
diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c new file mode 100644 index 000000000000..d7b783463fac --- /dev/null +++ b/arch/mips/pic32/pic32mzda/early_console.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <asm/mach-pic32/pic32.h> | ||
15 | #include <asm/fw/fw.h> | ||
16 | |||
17 | #include "pic32mzda.h" | ||
18 | #include "early_pin.h" | ||
19 | |||
20 | /* Default early console parameters */ | ||
21 | #define EARLY_CONSOLE_PORT 1 | ||
22 | #define EARLY_CONSOLE_BAUDRATE 115200 | ||
23 | |||
24 | #define UART_ENABLE BIT(15) | ||
25 | #define UART_ENABLE_RX BIT(12) | ||
26 | #define UART_ENABLE_TX BIT(10) | ||
27 | #define UART_TX_FULL BIT(9) | ||
28 | |||
29 | /* UART1(x == 0) - UART6(x == 5) */ | ||
30 | #define UART_BASE(x) ((x) * 0x0200) | ||
31 | #define U_MODE(x) UART_BASE(x) | ||
32 | #define U_STA(x) (UART_BASE(x) + 0x10) | ||
33 | #define U_TXR(x) (UART_BASE(x) + 0x20) | ||
34 | #define U_BRG(x) (UART_BASE(x) + 0x40) | ||
35 | |||
36 | static void __iomem *uart_base; | ||
37 | static char console_port = -1; | ||
38 | |||
39 | static int __init configure_uart_pins(int port) | ||
40 | { | ||
41 | switch (port) { | ||
42 | case 1: | ||
43 | pic32_pps_input(IN_FUNC_U2RX, IN_RPB0); | ||
44 | pic32_pps_output(OUT_FUNC_U2TX, OUT_RPG9); | ||
45 | break; | ||
46 | case 5: | ||
47 | pic32_pps_input(IN_FUNC_U6RX, IN_RPD0); | ||
48 | pic32_pps_output(OUT_FUNC_U6TX, OUT_RPB8); | ||
49 | break; | ||
50 | default: | ||
51 | return -1; | ||
52 | } | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static void __init configure_uart(char port, int baud) | ||
58 | { | ||
59 | u32 pbclk; | ||
60 | |||
61 | pbclk = pic32_get_pbclk(2); | ||
62 | |||
63 | __raw_writel(0, uart_base + U_MODE(port)); | ||
64 | __raw_writel(((pbclk / baud) / 16) - 1, uart_base + U_BRG(port)); | ||
65 | __raw_writel(UART_ENABLE, uart_base + U_MODE(port)); | ||
66 | __raw_writel(UART_ENABLE_TX | UART_ENABLE_RX, | ||
67 | uart_base + PIC32_SET(U_STA(port))); | ||
68 | } | ||
69 | |||
70 | static void __init setup_early_console(char port, int baud) | ||
71 | { | ||
72 | if (configure_uart_pins(port)) | ||
73 | return; | ||
74 | |||
75 | console_port = port; | ||
76 | configure_uart(console_port, baud); | ||
77 | } | ||
78 | |||
79 | static char * __init pic32_getcmdline(void) | ||
80 | { | ||
81 | /* | ||
82 | * arch_mem_init() has not been called yet, so we don't have a real | ||
83 | * command line setup if using CONFIG_CMDLINE_BOOL. | ||
84 | */ | ||
85 | #ifdef CONFIG_CMDLINE_OVERRIDE | ||
86 | return CONFIG_CMDLINE; | ||
87 | #else | ||
88 | return fw_getcmdline(); | ||
89 | #endif | ||
90 | } | ||
91 | |||
92 | static int __init get_port_from_cmdline(char *arch_cmdline) | ||
93 | { | ||
94 | char *s; | ||
95 | int port = -1; | ||
96 | |||
97 | if (!arch_cmdline || *arch_cmdline == '\0') | ||
98 | goto _out; | ||
99 | |||
100 | s = strstr(arch_cmdline, "earlyprintk="); | ||
101 | if (s) { | ||
102 | s = strstr(s, "ttyS"); | ||
103 | if (s) | ||
104 | s += 4; | ||
105 | else | ||
106 | goto _out; | ||
107 | |||
108 | port = (*s) - '0'; | ||
109 | } | ||
110 | |||
111 | _out: | ||
112 | return port; | ||
113 | } | ||
114 | |||
115 | static int __init get_baud_from_cmdline(char *arch_cmdline) | ||
116 | { | ||
117 | char *s; | ||
118 | int baud = -1; | ||
119 | |||
120 | if (!arch_cmdline || *arch_cmdline == '\0') | ||
121 | goto _out; | ||
122 | |||
123 | s = strstr(arch_cmdline, "earlyprintk="); | ||
124 | if (s) { | ||
125 | s = strstr(s, "ttyS"); | ||
126 | if (s) | ||
127 | s += 6; | ||
128 | else | ||
129 | goto _out; | ||
130 | |||
131 | baud = 0; | ||
132 | while (*s >= '0' && *s <= '9') | ||
133 | baud = baud * 10 + *s++ - '0'; | ||
134 | } | ||
135 | |||
136 | _out: | ||
137 | return baud; | ||
138 | } | ||
139 | |||
140 | void __init fw_init_early_console(char port) | ||
141 | { | ||
142 | char *arch_cmdline = pic32_getcmdline(); | ||
143 | int baud = -1; | ||
144 | |||
145 | uart_base = ioremap_nocache(PIC32_BASE_UART, 0xc00); | ||
146 | |||
147 | baud = get_baud_from_cmdline(arch_cmdline); | ||
148 | if (port == -1) | ||
149 | port = get_port_from_cmdline(arch_cmdline); | ||
150 | |||
151 | if (port == -1) | ||
152 | port = EARLY_CONSOLE_PORT; | ||
153 | |||
154 | if (baud == -1) | ||
155 | baud = EARLY_CONSOLE_BAUDRATE; | ||
156 | |||
157 | setup_early_console(port, baud); | ||
158 | } | ||
159 | |||
160 | int prom_putchar(char c) | ||
161 | { | ||
162 | if (console_port >= 0) { | ||
163 | while (__raw_readl( | ||
164 | uart_base + U_STA(console_port)) & UART_TX_FULL) | ||
165 | ; | ||
166 | |||
167 | __raw_writel(c, uart_base + U_TXR(console_port)); | ||
168 | } | ||
169 | |||
170 | return 1; | ||
171 | } | ||
diff --git a/arch/mips/pic32/pic32mzda/early_pin.c b/arch/mips/pic32/pic32mzda/early_pin.c new file mode 100644 index 000000000000..aa673f8023a8 --- /dev/null +++ b/arch/mips/pic32/pic32mzda/early_pin.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <asm/io.h> | ||
15 | |||
16 | #include "early_pin.h" | ||
17 | |||
18 | #define PPS_BASE 0x1f800000 | ||
19 | |||
20 | /* Input PPS Registers */ | ||
21 | #define INT1R 0x1404 | ||
22 | #define INT2R 0x1408 | ||
23 | #define INT3R 0x140C | ||
24 | #define INT4R 0x1410 | ||
25 | #define T2CKR 0x1418 | ||
26 | #define T3CKR 0x141C | ||
27 | #define T4CKR 0x1420 | ||
28 | #define T5CKR 0x1424 | ||
29 | #define T6CKR 0x1428 | ||
30 | #define T7CKR 0x142C | ||
31 | #define T8CKR 0x1430 | ||
32 | #define T9CKR 0x1434 | ||
33 | #define IC1R 0x1438 | ||
34 | #define IC2R 0x143C | ||
35 | #define IC3R 0x1440 | ||
36 | #define IC4R 0x1444 | ||
37 | #define IC5R 0x1448 | ||
38 | #define IC6R 0x144C | ||
39 | #define IC7R 0x1450 | ||
40 | #define IC8R 0x1454 | ||
41 | #define IC9R 0x1458 | ||
42 | #define OCFAR 0x1460 | ||
43 | #define U1RXR 0x1468 | ||
44 | #define U1CTSR 0x146C | ||
45 | #define U2RXR 0x1470 | ||
46 | #define U2CTSR 0x1474 | ||
47 | #define U3RXR 0x1478 | ||
48 | #define U3CTSR 0x147C | ||
49 | #define U4RXR 0x1480 | ||
50 | #define U4CTSR 0x1484 | ||
51 | #define U5RXR 0x1488 | ||
52 | #define U5CTSR 0x148C | ||
53 | #define U6RXR 0x1490 | ||
54 | #define U6CTSR 0x1494 | ||
55 | #define SDI1R 0x149C | ||
56 | #define SS1R 0x14A0 | ||
57 | #define SDI2R 0x14A8 | ||
58 | #define SS2R 0x14AC | ||
59 | #define SDI3R 0x14B4 | ||
60 | #define SS3R 0x14B8 | ||
61 | #define SDI4R 0x14C0 | ||
62 | #define SS4R 0x14C4 | ||
63 | #define SDI5R 0x14CC | ||
64 | #define SS5R 0x14D0 | ||
65 | #define SDI6R 0x14D8 | ||
66 | #define SS6R 0x14DC | ||
67 | #define C1RXR 0x14E0 | ||
68 | #define C2RXR 0x14E4 | ||
69 | #define REFCLKI1R 0x14E8 | ||
70 | #define REFCLKI3R 0x14F0 | ||
71 | #define REFCLKI4R 0x14F4 | ||
72 | |||
73 | static const struct | ||
74 | { | ||
75 | int function; | ||
76 | int reg; | ||
77 | } input_pin_reg[] = { | ||
78 | { IN_FUNC_INT3, INT3R }, | ||
79 | { IN_FUNC_T2CK, T2CKR }, | ||
80 | { IN_FUNC_T6CK, T6CKR }, | ||
81 | { IN_FUNC_IC3, IC3R }, | ||
82 | { IN_FUNC_IC7, IC7R }, | ||
83 | { IN_FUNC_U1RX, U1RXR }, | ||
84 | { IN_FUNC_U2CTS, U2CTSR }, | ||
85 | { IN_FUNC_U5RX, U5RXR }, | ||
86 | { IN_FUNC_U6CTS, U6CTSR }, | ||
87 | { IN_FUNC_SDI1, SDI1R }, | ||
88 | { IN_FUNC_SDI3, SDI3R }, | ||
89 | { IN_FUNC_SDI5, SDI5R }, | ||
90 | { IN_FUNC_SS6, SS6R }, | ||
91 | { IN_FUNC_REFCLKI1, REFCLKI1R }, | ||
92 | { IN_FUNC_INT4, INT4R }, | ||
93 | { IN_FUNC_T5CK, T5CKR }, | ||
94 | { IN_FUNC_T7CK, T7CKR }, | ||
95 | { IN_FUNC_IC4, IC4R }, | ||
96 | { IN_FUNC_IC8, IC8R }, | ||
97 | { IN_FUNC_U3RX, U3RXR }, | ||
98 | { IN_FUNC_U4CTS, U4CTSR }, | ||
99 | { IN_FUNC_SDI2, SDI2R }, | ||
100 | { IN_FUNC_SDI4, SDI4R }, | ||
101 | { IN_FUNC_C1RX, C1RXR }, | ||
102 | { IN_FUNC_REFCLKI4, REFCLKI4R }, | ||
103 | { IN_FUNC_INT2, INT2R }, | ||
104 | { IN_FUNC_T3CK, T3CKR }, | ||
105 | { IN_FUNC_T8CK, T8CKR }, | ||
106 | { IN_FUNC_IC2, IC2R }, | ||
107 | { IN_FUNC_IC5, IC5R }, | ||
108 | { IN_FUNC_IC9, IC9R }, | ||
109 | { IN_FUNC_U1CTS, U1CTSR }, | ||
110 | { IN_FUNC_U2RX, U2RXR }, | ||
111 | { IN_FUNC_U5CTS, U5CTSR }, | ||
112 | { IN_FUNC_SS1, SS1R }, | ||
113 | { IN_FUNC_SS3, SS3R }, | ||
114 | { IN_FUNC_SS4, SS4R }, | ||
115 | { IN_FUNC_SS5, SS5R }, | ||
116 | { IN_FUNC_C2RX, C2RXR }, | ||
117 | { IN_FUNC_INT1, INT1R }, | ||
118 | { IN_FUNC_T4CK, T4CKR }, | ||
119 | { IN_FUNC_T9CK, T9CKR }, | ||
120 | { IN_FUNC_IC1, IC1R }, | ||
121 | { IN_FUNC_IC6, IC6R }, | ||
122 | { IN_FUNC_U3CTS, U3CTSR }, | ||
123 | { IN_FUNC_U4RX, U4RXR }, | ||
124 | { IN_FUNC_U6RX, U6RXR }, | ||
125 | { IN_FUNC_SS2, SS2R }, | ||
126 | { IN_FUNC_SDI6, SDI6R }, | ||
127 | { IN_FUNC_OCFA, OCFAR }, | ||
128 | { IN_FUNC_REFCLKI3, REFCLKI3R }, | ||
129 | }; | ||
130 | |||
131 | void pic32_pps_input(int function, int pin) | ||
132 | { | ||
133 | void __iomem *pps_base = ioremap_nocache(PPS_BASE, 0xF4); | ||
134 | int i; | ||
135 | |||
136 | for (i = 0; i < ARRAY_SIZE(input_pin_reg); i++) { | ||
137 | if (input_pin_reg[i].function == function) { | ||
138 | __raw_writel(pin, pps_base + input_pin_reg[i].reg); | ||
139 | return; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | iounmap(pps_base); | ||
144 | } | ||
145 | |||
146 | /* Output PPS Registers */ | ||
147 | #define RPA14R 0x1538 | ||
148 | #define RPA15R 0x153C | ||
149 | #define RPB0R 0x1540 | ||
150 | #define RPB1R 0x1544 | ||
151 | #define RPB2R 0x1548 | ||
152 | #define RPB3R 0x154C | ||
153 | #define RPB5R 0x1554 | ||
154 | #define RPB6R 0x1558 | ||
155 | #define RPB7R 0x155C | ||
156 | #define RPB8R 0x1560 | ||
157 | #define RPB9R 0x1564 | ||
158 | #define RPB10R 0x1568 | ||
159 | #define RPB14R 0x1578 | ||
160 | #define RPB15R 0x157C | ||
161 | #define RPC1R 0x1584 | ||
162 | #define RPC2R 0x1588 | ||
163 | #define RPC3R 0x158C | ||
164 | #define RPC4R 0x1590 | ||
165 | #define RPC13R 0x15B4 | ||
166 | #define RPC14R 0x15B8 | ||
167 | #define RPD0R 0x15C0 | ||
168 | #define RPD1R 0x15C4 | ||
169 | #define RPD2R 0x15C8 | ||
170 | #define RPD3R 0x15CC | ||
171 | #define RPD4R 0x15D0 | ||
172 | #define RPD5R 0x15D4 | ||
173 | #define RPD6R 0x15D8 | ||
174 | #define RPD7R 0x15DC | ||
175 | #define RPD9R 0x15E4 | ||
176 | #define RPD10R 0x15E8 | ||
177 | #define RPD11R 0x15EC | ||
178 | #define RPD12R 0x15F0 | ||
179 | #define RPD14R 0x15F8 | ||
180 | #define RPD15R 0x15FC | ||
181 | #define RPE3R 0x160C | ||
182 | #define RPE5R 0x1614 | ||
183 | #define RPE8R 0x1620 | ||
184 | #define RPE9R 0x1624 | ||
185 | #define RPF0R 0x1640 | ||
186 | #define RPF1R 0x1644 | ||
187 | #define RPF2R 0x1648 | ||
188 | #define RPF3R 0x164C | ||
189 | #define RPF4R 0x1650 | ||
190 | #define RPF5R 0x1654 | ||
191 | #define RPF8R 0x1660 | ||
192 | #define RPF12R 0x1670 | ||
193 | #define RPF13R 0x1674 | ||
194 | #define RPG0R 0x1680 | ||
195 | #define RPG1R 0x1684 | ||
196 | #define RPG6R 0x1698 | ||
197 | #define RPG7R 0x169C | ||
198 | #define RPG8R 0x16A0 | ||
199 | #define RPG9R 0x16A4 | ||
200 | |||
201 | static const struct | ||
202 | { | ||
203 | int pin; | ||
204 | int reg; | ||
205 | } output_pin_reg[] = { | ||
206 | { OUT_RPD2, RPD2R }, | ||
207 | { OUT_RPG8, RPG8R }, | ||
208 | { OUT_RPF4, RPF4R }, | ||
209 | { OUT_RPD10, RPD10R }, | ||
210 | { OUT_RPF1, RPF1R }, | ||
211 | { OUT_RPB9, RPB9R }, | ||
212 | { OUT_RPB10, RPB10R }, | ||
213 | { OUT_RPC14, RPC14R }, | ||
214 | { OUT_RPB5, RPB5R }, | ||
215 | { OUT_RPC1, RPC1R }, | ||
216 | { OUT_RPD14, RPD14R }, | ||
217 | { OUT_RPG1, RPG1R }, | ||
218 | { OUT_RPA14, RPA14R }, | ||
219 | { OUT_RPD6, RPD6R }, | ||
220 | { OUT_RPD3, RPD3R }, | ||
221 | { OUT_RPG7, RPG7R }, | ||
222 | { OUT_RPF5, RPF5R }, | ||
223 | { OUT_RPD11, RPD11R }, | ||
224 | { OUT_RPF0, RPF0R }, | ||
225 | { OUT_RPB1, RPB1R }, | ||
226 | { OUT_RPE5, RPE5R }, | ||
227 | { OUT_RPC13, RPC13R }, | ||
228 | { OUT_RPB3, RPB3R }, | ||
229 | { OUT_RPC4, RPC4R }, | ||
230 | { OUT_RPD15, RPD15R }, | ||
231 | { OUT_RPG0, RPG0R }, | ||
232 | { OUT_RPA15, RPA15R }, | ||
233 | { OUT_RPD7, RPD7R }, | ||
234 | { OUT_RPD9, RPD9R }, | ||
235 | { OUT_RPG6, RPG6R }, | ||
236 | { OUT_RPB8, RPB8R }, | ||
237 | { OUT_RPB15, RPB15R }, | ||
238 | { OUT_RPD4, RPD4R }, | ||
239 | { OUT_RPB0, RPB0R }, | ||
240 | { OUT_RPE3, RPE3R }, | ||
241 | { OUT_RPB7, RPB7R }, | ||
242 | { OUT_RPF12, RPF12R }, | ||
243 | { OUT_RPD12, RPD12R }, | ||
244 | { OUT_RPF8, RPF8R }, | ||
245 | { OUT_RPC3, RPC3R }, | ||
246 | { OUT_RPE9, RPE9R }, | ||
247 | { OUT_RPD1, RPD1R }, | ||
248 | { OUT_RPG9, RPG9R }, | ||
249 | { OUT_RPB14, RPB14R }, | ||
250 | { OUT_RPD0, RPD0R }, | ||
251 | { OUT_RPB6, RPB6R }, | ||
252 | { OUT_RPD5, RPD5R }, | ||
253 | { OUT_RPB2, RPB2R }, | ||
254 | { OUT_RPF3, RPF3R }, | ||
255 | { OUT_RPF13, RPF13R }, | ||
256 | { OUT_RPC2, RPC2R }, | ||
257 | { OUT_RPE8, RPE8R }, | ||
258 | { OUT_RPF2, RPF2R }, | ||
259 | }; | ||
260 | |||
261 | void pic32_pps_output(int function, int pin) | ||
262 | { | ||
263 | void __iomem *pps_base = ioremap_nocache(PPS_BASE, 0x170); | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < ARRAY_SIZE(output_pin_reg); i++) { | ||
267 | if (output_pin_reg[i].pin == pin) { | ||
268 | __raw_writel(function, | ||
269 | pps_base + output_pin_reg[i].reg); | ||
270 | return; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | iounmap(pps_base); | ||
275 | } | ||
diff --git a/arch/mips/pic32/pic32mzda/early_pin.h b/arch/mips/pic32/pic32mzda/early_pin.h new file mode 100644 index 000000000000..417fae9a9627 --- /dev/null +++ b/arch/mips/pic32/pic32mzda/early_pin.h | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #ifndef _PIC32MZDA_EARLY_PIN_H | ||
15 | #define _PIC32MZDA_EARLY_PIN_H | ||
16 | |||
17 | /* | ||
18 | * This is a complete, yet overly simplistic and unoptimized, PIC32MZDA PPS | ||
19 | * configuration only useful before we have full pinctrl initialized. | ||
20 | */ | ||
21 | |||
22 | /* Input PPS Functions */ | ||
23 | enum { | ||
24 | IN_FUNC_INT3, | ||
25 | IN_FUNC_T2CK, | ||
26 | IN_FUNC_T6CK, | ||
27 | IN_FUNC_IC3, | ||
28 | IN_FUNC_IC7, | ||
29 | IN_FUNC_U1RX, | ||
30 | IN_FUNC_U2CTS, | ||
31 | IN_FUNC_U5RX, | ||
32 | IN_FUNC_U6CTS, | ||
33 | IN_FUNC_SDI1, | ||
34 | IN_FUNC_SDI3, | ||
35 | IN_FUNC_SDI5, | ||
36 | IN_FUNC_SS6, | ||
37 | IN_FUNC_REFCLKI1, | ||
38 | IN_FUNC_INT4, | ||
39 | IN_FUNC_T5CK, | ||
40 | IN_FUNC_T7CK, | ||
41 | IN_FUNC_IC4, | ||
42 | IN_FUNC_IC8, | ||
43 | IN_FUNC_U3RX, | ||
44 | IN_FUNC_U4CTS, | ||
45 | IN_FUNC_SDI2, | ||
46 | IN_FUNC_SDI4, | ||
47 | IN_FUNC_C1RX, | ||
48 | IN_FUNC_REFCLKI4, | ||
49 | IN_FUNC_INT2, | ||
50 | IN_FUNC_T3CK, | ||
51 | IN_FUNC_T8CK, | ||
52 | IN_FUNC_IC2, | ||
53 | IN_FUNC_IC5, | ||
54 | IN_FUNC_IC9, | ||
55 | IN_FUNC_U1CTS, | ||
56 | IN_FUNC_U2RX, | ||
57 | IN_FUNC_U5CTS, | ||
58 | IN_FUNC_SS1, | ||
59 | IN_FUNC_SS3, | ||
60 | IN_FUNC_SS4, | ||
61 | IN_FUNC_SS5, | ||
62 | IN_FUNC_C2RX, | ||
63 | IN_FUNC_INT1, | ||
64 | IN_FUNC_T4CK, | ||
65 | IN_FUNC_T9CK, | ||
66 | IN_FUNC_IC1, | ||
67 | IN_FUNC_IC6, | ||
68 | IN_FUNC_U3CTS, | ||
69 | IN_FUNC_U4RX, | ||
70 | IN_FUNC_U6RX, | ||
71 | IN_FUNC_SS2, | ||
72 | IN_FUNC_SDI6, | ||
73 | IN_FUNC_OCFA, | ||
74 | IN_FUNC_REFCLKI3, | ||
75 | }; | ||
76 | |||
77 | /* Input PPS Pins */ | ||
78 | #define IN_RPD2 0x00 | ||
79 | #define IN_RPG8 0x01 | ||
80 | #define IN_RPF4 0x02 | ||
81 | #define IN_RPD10 0x03 | ||
82 | #define IN_RPF1 0x04 | ||
83 | #define IN_RPB9 0x05 | ||
84 | #define IN_RPB10 0x06 | ||
85 | #define IN_RPC14 0x07 | ||
86 | #define IN_RPB5 0x08 | ||
87 | #define IN_RPC1 0x0A | ||
88 | #define IN_RPD14 0x0B | ||
89 | #define IN_RPG1 0x0C | ||
90 | #define IN_RPA14 0x0D | ||
91 | #define IN_RPD6 0x0E | ||
92 | #define IN_RPD3 0x00 | ||
93 | #define IN_RPG7 0x01 | ||
94 | #define IN_RPF5 0x02 | ||
95 | #define IN_RPD11 0x03 | ||
96 | #define IN_RPF0 0x04 | ||
97 | #define IN_RPB1 0x05 | ||
98 | #define IN_RPE5 0x06 | ||
99 | #define IN_RPC13 0x07 | ||
100 | #define IN_RPB3 0x08 | ||
101 | #define IN_RPC4 0x0A | ||
102 | #define IN_RPD15 0x0B | ||
103 | #define IN_RPG0 0x0C | ||
104 | #define IN_RPA15 0x0D | ||
105 | #define IN_RPD7 0x0E | ||
106 | #define IN_RPD9 0x00 | ||
107 | #define IN_RPG6 0x01 | ||
108 | #define IN_RPB8 0x02 | ||
109 | #define IN_RPB15 0x03 | ||
110 | #define IN_RPD4 0x04 | ||
111 | #define IN_RPB0 0x05 | ||
112 | #define IN_RPE3 0x06 | ||
113 | #define IN_RPB7 0x07 | ||
114 | #define IN_RPF12 0x09 | ||
115 | #define IN_RPD12 0x0A | ||
116 | #define IN_RPF8 0x0B | ||
117 | #define IN_RPC3 0x0C | ||
118 | #define IN_RPE9 0x0D | ||
119 | #define IN_RPD1 0x00 | ||
120 | #define IN_RPG9 0x01 | ||
121 | #define IN_RPB14 0x02 | ||
122 | #define IN_RPD0 0x03 | ||
123 | #define IN_RPB6 0x05 | ||
124 | #define IN_RPD5 0x06 | ||
125 | #define IN_RPB2 0x07 | ||
126 | #define IN_RPF3 0x08 | ||
127 | #define IN_RPF13 0x09 | ||
128 | #define IN_RPF2 0x0B | ||
129 | #define IN_RPC2 0x0C | ||
130 | #define IN_RPE8 0x0D | ||
131 | |||
132 | /* Output PPS Pins */ | ||
133 | enum { | ||
134 | OUT_RPD2, | ||
135 | OUT_RPG8, | ||
136 | OUT_RPF4, | ||
137 | OUT_RPD10, | ||
138 | OUT_RPF1, | ||
139 | OUT_RPB9, | ||
140 | OUT_RPB10, | ||
141 | OUT_RPC14, | ||
142 | OUT_RPB5, | ||
143 | OUT_RPC1, | ||
144 | OUT_RPD14, | ||
145 | OUT_RPG1, | ||
146 | OUT_RPA14, | ||
147 | OUT_RPD6, | ||
148 | OUT_RPD3, | ||
149 | OUT_RPG7, | ||
150 | OUT_RPF5, | ||
151 | OUT_RPD11, | ||
152 | OUT_RPF0, | ||
153 | OUT_RPB1, | ||
154 | OUT_RPE5, | ||
155 | OUT_RPC13, | ||
156 | OUT_RPB3, | ||
157 | OUT_RPC4, | ||
158 | OUT_RPD15, | ||
159 | OUT_RPG0, | ||
160 | OUT_RPA15, | ||
161 | OUT_RPD7, | ||
162 | OUT_RPD9, | ||
163 | OUT_RPG6, | ||
164 | OUT_RPB8, | ||
165 | OUT_RPB15, | ||
166 | OUT_RPD4, | ||
167 | OUT_RPB0, | ||
168 | OUT_RPE3, | ||
169 | OUT_RPB7, | ||
170 | OUT_RPF12, | ||
171 | OUT_RPD12, | ||
172 | OUT_RPF8, | ||
173 | OUT_RPC3, | ||
174 | OUT_RPE9, | ||
175 | OUT_RPD1, | ||
176 | OUT_RPG9, | ||
177 | OUT_RPB14, | ||
178 | OUT_RPD0, | ||
179 | OUT_RPB6, | ||
180 | OUT_RPD5, | ||
181 | OUT_RPB2, | ||
182 | OUT_RPF3, | ||
183 | OUT_RPF13, | ||
184 | OUT_RPC2, | ||
185 | OUT_RPE8, | ||
186 | OUT_RPF2, | ||
187 | }; | ||
188 | |||
189 | /* Output PPS Functions */ | ||
190 | #define OUT_FUNC_U3TX 0x01 | ||
191 | #define OUT_FUNC_U4RTS 0x02 | ||
192 | #define OUT_FUNC_SDO1 0x05 | ||
193 | #define OUT_FUNC_SDO2 0x06 | ||
194 | #define OUT_FUNC_SDO3 0x07 | ||
195 | #define OUT_FUNC_SDO5 0x09 | ||
196 | #define OUT_FUNC_SS6 0x0A | ||
197 | #define OUT_FUNC_OC3 0x0B | ||
198 | #define OUT_FUNC_OC6 0x0C | ||
199 | #define OUT_FUNC_REFCLKO4 0x0D | ||
200 | #define OUT_FUNC_C2OUT 0x0E | ||
201 | #define OUT_FUNC_C1TX 0x0F | ||
202 | #define OUT_FUNC_U1TX 0x01 | ||
203 | #define OUT_FUNC_U2RTS 0x02 | ||
204 | #define OUT_FUNC_U5TX 0x03 | ||
205 | #define OUT_FUNC_U6RTS 0x04 | ||
206 | #define OUT_FUNC_SDO1 0x05 | ||
207 | #define OUT_FUNC_SDO2 0x06 | ||
208 | #define OUT_FUNC_SDO3 0x07 | ||
209 | #define OUT_FUNC_SDO4 0x08 | ||
210 | #define OUT_FUNC_SDO5 0x09 | ||
211 | #define OUT_FUNC_OC4 0x0B | ||
212 | #define OUT_FUNC_OC7 0x0C | ||
213 | #define OUT_FUNC_REFCLKO1 0x0F | ||
214 | #define OUT_FUNC_U3RTS 0x01 | ||
215 | #define OUT_FUNC_U4TX 0x02 | ||
216 | #define OUT_FUNC_U6TX 0x04 | ||
217 | #define OUT_FUNC_SS1 0x05 | ||
218 | #define OUT_FUNC_SS3 0x07 | ||
219 | #define OUT_FUNC_SS4 0x08 | ||
220 | #define OUT_FUNC_SS5 0x09 | ||
221 | #define OUT_FUNC_SDO6 0x0A | ||
222 | #define OUT_FUNC_OC5 0x0B | ||
223 | #define OUT_FUNC_OC8 0x0C | ||
224 | #define OUT_FUNC_C1OUT 0x0E | ||
225 | #define OUT_FUNC_REFCLKO3 0x0F | ||
226 | #define OUT_FUNC_U1RTS 0x01 | ||
227 | #define OUT_FUNC_U2TX 0x02 | ||
228 | #define OUT_FUNC_U5RTS 0x03 | ||
229 | #define OUT_FUNC_U6TX 0x04 | ||
230 | #define OUT_FUNC_SS2 0x06 | ||
231 | #define OUT_FUNC_SDO4 0x08 | ||
232 | #define OUT_FUNC_SDO6 0x0A | ||
233 | #define OUT_FUNC_OC2 0x0B | ||
234 | #define OUT_FUNC_OC1 0x0C | ||
235 | #define OUT_FUNC_OC9 0x0D | ||
236 | #define OUT_FUNC_C2TX 0x0F | ||
237 | |||
238 | void pic32_pps_input(int function, int pin); | ||
239 | void pic32_pps_output(int function, int pin); | ||
240 | |||
241 | #endif | ||
diff --git a/arch/mips/pic32/pic32mzda/init.c b/arch/mips/pic32/pic32mzda/init.c new file mode 100644 index 000000000000..775ff90a9962 --- /dev/null +++ b/arch/mips/pic32/pic32mzda/init.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * Joshua Henderson, joshua.henderson@microchip.com | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_fdt.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <linux/platform_data/sdhci-pic32.h> | ||
20 | |||
21 | #include <asm/fw/fw.h> | ||
22 | #include <asm/mips-boards/generic.h> | ||
23 | #include <asm/prom.h> | ||
24 | |||
25 | #include "pic32mzda.h" | ||
26 | |||
27 | const char *get_system_type(void) | ||
28 | { | ||
29 | return "PIC32MZDA"; | ||
30 | } | ||
31 | |||
32 | static ulong get_fdtaddr(void) | ||
33 | { | ||
34 | ulong ftaddr = 0; | ||
35 | |||
36 | if ((fw_arg0 == -2) && fw_arg1 && !fw_arg2 && !fw_arg3) | ||
37 | return (ulong)fw_arg1; | ||
38 | |||
39 | if (__dtb_start < __dtb_end) | ||
40 | ftaddr = (ulong)__dtb_start; | ||
41 | |||
42 | return ftaddr; | ||
43 | } | ||
44 | |||
45 | void __init plat_mem_setup(void) | ||
46 | { | ||
47 | void *dtb; | ||
48 | |||
49 | dtb = (void *)get_fdtaddr(); | ||
50 | if (!dtb) { | ||
51 | pr_err("pic32: no DTB found.\n"); | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * Load the builtin device tree. This causes the chosen node to be | ||
57 | * parsed resulting in our memory appearing. | ||
58 | */ | ||
59 | __dt_setup_arch(dtb); | ||
60 | |||
61 | pr_info("Found following command lines\n"); | ||
62 | pr_info(" boot_command_line: %s\n", boot_command_line); | ||
63 | pr_info(" arcs_cmdline : %s\n", arcs_cmdline); | ||
64 | #ifdef CONFIG_CMDLINE_BOOL | ||
65 | pr_info(" builtin_cmdline : %s\n", CONFIG_CMDLINE); | ||
66 | #endif | ||
67 | if (dtb != __dtb_start) | ||
68 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||
69 | |||
70 | #ifdef CONFIG_EARLY_PRINTK | ||
71 | fw_init_early_console(-1); | ||
72 | #endif | ||
73 | pic32_config_init(); | ||
74 | } | ||
75 | |||
76 | static __init void pic32_init_cmdline(int argc, char *argv[]) | ||
77 | { | ||
78 | unsigned int count = COMMAND_LINE_SIZE - 1; | ||
79 | int i; | ||
80 | char *dst = &(arcs_cmdline[0]); | ||
81 | char *src; | ||
82 | |||
83 | for (i = 1; i < argc && count; ++i) { | ||
84 | src = argv[i]; | ||
85 | while (*src && count) { | ||
86 | *dst++ = *src++; | ||
87 | --count; | ||
88 | } | ||
89 | *dst++ = ' '; | ||
90 | } | ||
91 | if (i > 1) | ||
92 | --dst; | ||
93 | |||
94 | *dst = 0; | ||
95 | } | ||
96 | |||
97 | void __init prom_init(void) | ||
98 | { | ||
99 | pic32_init_cmdline((int)fw_arg0, (char **)fw_arg1); | ||
100 | } | ||
101 | |||
102 | void __init prom_free_prom_memory(void) | ||
103 | { | ||
104 | } | ||
105 | |||
106 | void __init device_tree_init(void) | ||
107 | { | ||
108 | if (!initial_boot_params) | ||
109 | return; | ||
110 | |||
111 | unflatten_and_copy_device_tree(); | ||
112 | } | ||
113 | |||
114 | static struct pic32_sdhci_platform_data sdhci_data = { | ||
115 | .setup_dma = pic32_set_sdhci_adma_fifo_threshold, | ||
116 | }; | ||
117 | |||
118 | static struct of_dev_auxdata pic32_auxdata_lookup[] __initdata = { | ||
119 | OF_DEV_AUXDATA("microchip,pic32mzda-sdhci", 0, "sdhci", &sdhci_data), | ||
120 | { /* sentinel */} | ||
121 | }; | ||
122 | |||
123 | static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup) | ||
124 | { | ||
125 | struct device_node *root, *np; | ||
126 | struct resource res; | ||
127 | |||
128 | root = of_find_node_by_path("/"); | ||
129 | |||
130 | for (; lookup->compatible; lookup++) { | ||
131 | np = of_find_compatible_node(NULL, NULL, lookup->compatible); | ||
132 | if (np) { | ||
133 | lookup->name = (char *)np->name; | ||
134 | if (lookup->phys_addr) | ||
135 | continue; | ||
136 | if (!of_address_to_resource(np, 0, &res)) | ||
137 | lookup->phys_addr = res.start; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int __init plat_of_setup(void) | ||
145 | { | ||
146 | if (!of_have_populated_dt()) | ||
147 | panic("Device tree not present"); | ||
148 | |||
149 | pic32_of_prepare_platform_data(pic32_auxdata_lookup); | ||
150 | if (of_platform_populate(NULL, of_default_bus_match_table, | ||
151 | pic32_auxdata_lookup, NULL)) | ||
152 | panic("Failed to populate DT"); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | arch_initcall(plat_of_setup); | ||
diff --git a/arch/mips/pic32/pic32mzda/pic32mzda.h b/arch/mips/pic32/pic32mzda/pic32mzda.h new file mode 100644 index 000000000000..96d10e2af475 --- /dev/null +++ b/arch/mips/pic32/pic32mzda/pic32mzda.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #ifndef PIC32MZDA_COMMON_H | ||
15 | #define PIC32MZDA_COMMON_H | ||
16 | |||
17 | /* early clock */ | ||
18 | u32 pic32_get_pbclk(int bus); | ||
19 | u32 pic32_get_sysclk(void); | ||
20 | |||
21 | /* Device configuration */ | ||
22 | void __init pic32_config_init(void); | ||
23 | int pic32_set_lcd_mode(int mode); | ||
24 | int pic32_set_sdhci_adma_fifo_threshold(u32 rthrs, u32 wthrs); | ||
25 | u32 pic32_get_boot_status(void); | ||
26 | int pic32_disable_lcd(void); | ||
27 | int pic32_enable_lcd(void); | ||
28 | |||
29 | #endif | ||
diff --git a/arch/mips/pic32/pic32mzda/time.c b/arch/mips/pic32/pic32mzda/time.c new file mode 100644 index 000000000000..ca6a62bb10db --- /dev/null +++ b/arch/mips/pic32/pic32mzda/time.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/clk-provider.h> | ||
16 | #include <linux/clocksource.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_irq.h> | ||
20 | #include <linux/irqdomain.h> | ||
21 | |||
22 | #include <asm/time.h> | ||
23 | |||
24 | #include "pic32mzda.h" | ||
25 | |||
26 | static const struct of_device_id pic32_infra_match[] = { | ||
27 | { .compatible = "microchip,pic32mzda-infra", }, | ||
28 | { }, | ||
29 | }; | ||
30 | |||
31 | #define DEFAULT_CORE_TIMER_INTERRUPT 0 | ||
32 | |||
33 | static unsigned int pic32_xlate_core_timer_irq(void) | ||
34 | { | ||
35 | static struct device_node *node; | ||
36 | unsigned int irq; | ||
37 | |||
38 | node = of_find_matching_node(NULL, pic32_infra_match); | ||
39 | |||
40 | if (WARN_ON(!node)) | ||
41 | goto default_map; | ||
42 | |||
43 | irq = irq_of_parse_and_map(node, 0); | ||
44 | if (!irq) | ||
45 | goto default_map; | ||
46 | |||
47 | return irq; | ||
48 | |||
49 | default_map: | ||
50 | |||
51 | return irq_create_mapping(NULL, DEFAULT_CORE_TIMER_INTERRUPT); | ||
52 | } | ||
53 | |||
54 | unsigned int get_c0_compare_int(void) | ||
55 | { | ||
56 | return pic32_xlate_core_timer_irq(); | ||
57 | } | ||
58 | |||
59 | void __init plat_time_init(void) | ||
60 | { | ||
61 | struct clk *clk; | ||
62 | |||
63 | of_clk_init(NULL); | ||
64 | clk = clk_get_sys("cpu_clk", NULL); | ||
65 | if (IS_ERR(clk)) | ||
66 | panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); | ||
67 | |||
68 | clk_prepare_enable(clk); | ||
69 | pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000); | ||
70 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
71 | |||
72 | clocksource_probe(); | ||
73 | } | ||
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index e9bc8c96174e..813826a456ca 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig | |||
@@ -12,6 +12,11 @@ config RALINK_ILL_ACC | |||
12 | depends on SOC_RT305X | 12 | depends on SOC_RT305X |
13 | default y | 13 | default y |
14 | 14 | ||
15 | config IRQ_INTC | ||
16 | bool | ||
17 | default y | ||
18 | depends on !SOC_MT7621 | ||
19 | |||
15 | choice | 20 | choice |
16 | prompt "Ralink SoC selection" | 21 | prompt "Ralink SoC selection" |
17 | default SOC_RT305X | 22 | default SOC_RT305X |
@@ -33,7 +38,18 @@ choice | |||
33 | 38 | ||
34 | config SOC_MT7620 | 39 | config SOC_MT7620 |
35 | bool "MT7620/8" | 40 | bool "MT7620/8" |
41 | select HW_HAS_PCI | ||
36 | 42 | ||
43 | config SOC_MT7621 | ||
44 | bool "MT7621" | ||
45 | select MIPS_CPU_SCACHE | ||
46 | select SYS_SUPPORTS_MULTITHREADING | ||
47 | select SYS_SUPPORTS_SMP | ||
48 | select SYS_SUPPORTS_MIPS_CPS | ||
49 | select MIPS_GIC | ||
50 | select COMMON_CLK | ||
51 | select CLKSRC_MIPS_GIC | ||
52 | select HW_HAS_PCI | ||
37 | endchoice | 53 | endchoice |
38 | 54 | ||
39 | choice | 55 | choice |
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile index a6c9d0061326..0d1795a0321e 100644 --- a/arch/mips/ralink/Makefile +++ b/arch/mips/ralink/Makefile | |||
@@ -6,16 +6,24 @@ | |||
6 | # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> | 6 | # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> |
7 | # Copyright (C) 2013 John Crispin <blogic@openwrt.org> | 7 | # Copyright (C) 2013 John Crispin <blogic@openwrt.org> |
8 | 8 | ||
9 | obj-y := prom.o of.o reset.o clk.o irq.o timer.o | 9 | obj-y := prom.o of.o reset.o |
10 | |||
11 | ifndef CONFIG_MIPS_GIC | ||
12 | obj-y += clk.o timer.o | ||
13 | endif | ||
10 | 14 | ||
11 | obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o | 15 | obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o |
12 | 16 | ||
13 | obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o | 17 | obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o |
14 | 18 | ||
19 | obj-$(CONFIG_IRQ_INTC) += irq.o | ||
20 | obj-$(CONFIG_MIPS_GIC) += irq-gic.o timer-gic.o | ||
21 | |||
15 | obj-$(CONFIG_SOC_RT288X) += rt288x.o | 22 | obj-$(CONFIG_SOC_RT288X) += rt288x.o |
16 | obj-$(CONFIG_SOC_RT305X) += rt305x.o | 23 | obj-$(CONFIG_SOC_RT305X) += rt305x.o |
17 | obj-$(CONFIG_SOC_RT3883) += rt3883.o | 24 | obj-$(CONFIG_SOC_RT3883) += rt3883.o |
18 | obj-$(CONFIG_SOC_MT7620) += mt7620.o | 25 | obj-$(CONFIG_SOC_MT7620) += mt7620.o |
26 | obj-$(CONFIG_SOC_MT7621) += mt7621.o | ||
19 | 27 | ||
20 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 28 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
21 | 29 | ||
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform index 6d9c8c499f98..6095fcc334f4 100644 --- a/arch/mips/ralink/Platform +++ b/arch/mips/ralink/Platform | |||
@@ -27,3 +27,8 @@ cflags-$(CONFIG_SOC_RT3883) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt | |||
27 | # | 27 | # |
28 | load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000 | 28 | load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000 |
29 | cflags-$(CONFIG_SOC_MT7620) += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7620 | 29 | cflags-$(CONFIG_SOC_MT7620) += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7620 |
30 | |||
31 | # Ralink MT7621 | ||
32 | # | ||
33 | load-$(CONFIG_SOC_MT7621) += 0xffffffff80001000 | ||
34 | cflags-$(CONFIG_SOC_MT7621) += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7621 | ||
diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c new file mode 100644 index 000000000000..50d6c55ab1de --- /dev/null +++ b/arch/mips/ralink/irq-gic.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> | ||
7 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | |||
12 | #include <linux/of.h> | ||
13 | #include <linux/irqchip.h> | ||
14 | #include <linux/irqchip/mips-gic.h> | ||
15 | |||
16 | int get_c0_perfcount_int(void) | ||
17 | { | ||
18 | return gic_get_c0_perfcount_int(); | ||
19 | } | ||
20 | EXPORT_SYMBOL_GPL(get_c0_perfcount_int); | ||
21 | |||
22 | void __init arch_init_irq(void) | ||
23 | { | ||
24 | irqchip_init(); | ||
25 | } | ||
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index dfb04fcedb04..0d3d1a97895f 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c | |||
@@ -107,31 +107,31 @@ static struct rt2880_pmx_group mt7620a_pinmux_data[] = { | |||
107 | }; | 107 | }; |
108 | 108 | ||
109 | static struct rt2880_pmx_func pwm1_grp_mt7628[] = { | 109 | static struct rt2880_pmx_func pwm1_grp_mt7628[] = { |
110 | FUNC("sdcx", 3, 19, 1), | 110 | FUNC("sdxc d6", 3, 19, 1), |
111 | FUNC("utif", 2, 19, 1), | 111 | FUNC("utif", 2, 19, 1), |
112 | FUNC("gpio", 1, 19, 1), | 112 | FUNC("gpio", 1, 19, 1), |
113 | FUNC("pwm", 0, 19, 1), | 113 | FUNC("pwm1", 0, 19, 1), |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static struct rt2880_pmx_func pwm0_grp_mt7628[] = { | 116 | static struct rt2880_pmx_func pwm0_grp_mt7628[] = { |
117 | FUNC("sdcx", 3, 18, 1), | 117 | FUNC("sdxc d7", 3, 18, 1), |
118 | FUNC("utif", 2, 18, 1), | 118 | FUNC("utif", 2, 18, 1), |
119 | FUNC("gpio", 1, 18, 1), | 119 | FUNC("gpio", 1, 18, 1), |
120 | FUNC("pwm", 0, 18, 1), | 120 | FUNC("pwm0", 0, 18, 1), |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static struct rt2880_pmx_func uart2_grp_mt7628[] = { | 123 | static struct rt2880_pmx_func uart2_grp_mt7628[] = { |
124 | FUNC("sdcx", 3, 20, 2), | 124 | FUNC("sdxc d5 d4", 3, 20, 2), |
125 | FUNC("pwm", 2, 20, 2), | 125 | FUNC("pwm", 2, 20, 2), |
126 | FUNC("gpio", 1, 20, 2), | 126 | FUNC("gpio", 1, 20, 2), |
127 | FUNC("uart", 0, 20, 2), | 127 | FUNC("uart2", 0, 20, 2), |
128 | }; | 128 | }; |
129 | 129 | ||
130 | static struct rt2880_pmx_func uart1_grp_mt7628[] = { | 130 | static struct rt2880_pmx_func uart1_grp_mt7628[] = { |
131 | FUNC("sdcx", 3, 45, 2), | 131 | FUNC("sw_r", 3, 45, 2), |
132 | FUNC("pwm", 2, 45, 2), | 132 | FUNC("pwm", 2, 45, 2), |
133 | FUNC("gpio", 1, 45, 2), | 133 | FUNC("gpio", 1, 45, 2), |
134 | FUNC("uart", 0, 45, 2), | 134 | FUNC("uart1", 0, 45, 2), |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct rt2880_pmx_func i2c_grp_mt7628[] = { | 137 | static struct rt2880_pmx_func i2c_grp_mt7628[] = { |
@@ -143,21 +143,21 @@ static struct rt2880_pmx_func i2c_grp_mt7628[] = { | |||
143 | 143 | ||
144 | static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) }; | 144 | static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) }; |
145 | static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) }; | 145 | static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) }; |
146 | static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) }; | 146 | static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) }; |
147 | static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) }; | 147 | static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) }; |
148 | 148 | ||
149 | static struct rt2880_pmx_func sd_mode_grp_mt7628[] = { | 149 | static struct rt2880_pmx_func sd_mode_grp_mt7628[] = { |
150 | FUNC("jtag", 3, 22, 8), | 150 | FUNC("jtag", 3, 22, 8), |
151 | FUNC("utif", 2, 22, 8), | 151 | FUNC("utif", 2, 22, 8), |
152 | FUNC("gpio", 1, 22, 8), | 152 | FUNC("gpio", 1, 22, 8), |
153 | FUNC("sdcx", 0, 22, 8), | 153 | FUNC("sdxc", 0, 22, 8), |
154 | }; | 154 | }; |
155 | 155 | ||
156 | static struct rt2880_pmx_func uart0_grp_mt7628[] = { | 156 | static struct rt2880_pmx_func uart0_grp_mt7628[] = { |
157 | FUNC("-", 3, 12, 2), | 157 | FUNC("-", 3, 12, 2), |
158 | FUNC("-", 2, 12, 2), | 158 | FUNC("-", 2, 12, 2), |
159 | FUNC("gpio", 1, 12, 2), | 159 | FUNC("gpio", 1, 12, 2), |
160 | FUNC("uart", 0, 12, 2), | 160 | FUNC("uart0", 0, 12, 2), |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static struct rt2880_pmx_func i2s_grp_mt7628[] = { | 163 | static struct rt2880_pmx_func i2s_grp_mt7628[] = { |
@@ -171,7 +171,7 @@ static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = { | |||
171 | FUNC("-", 3, 6, 1), | 171 | FUNC("-", 3, 6, 1), |
172 | FUNC("refclk", 2, 6, 1), | 172 | FUNC("refclk", 2, 6, 1), |
173 | FUNC("gpio", 1, 6, 1), | 173 | FUNC("gpio", 1, 6, 1), |
174 | FUNC("spi", 0, 6, 1), | 174 | FUNC("spi cs1", 0, 6, 1), |
175 | }; | 175 | }; |
176 | 176 | ||
177 | static struct rt2880_pmx_func spis_grp_mt7628[] = { | 177 | static struct rt2880_pmx_func spis_grp_mt7628[] = { |
@@ -188,28 +188,44 @@ static struct rt2880_pmx_func gpio_grp_mt7628[] = { | |||
188 | FUNC("gpio", 0, 11, 1), | 188 | FUNC("gpio", 0, 11, 1), |
189 | }; | 189 | }; |
190 | 190 | ||
191 | #define MT7628_GPIO_MODE_MASK 0x3 | 191 | static struct rt2880_pmx_func wled_kn_grp_mt7628[] = { |
192 | 192 | FUNC("rsvd", 3, 35, 1), | |
193 | #define MT7628_GPIO_MODE_PWM1 30 | 193 | FUNC("rsvd", 2, 35, 1), |
194 | #define MT7628_GPIO_MODE_PWM0 28 | 194 | FUNC("gpio", 1, 35, 1), |
195 | #define MT7628_GPIO_MODE_UART2 26 | 195 | FUNC("wled_kn", 0, 35, 1), |
196 | #define MT7628_GPIO_MODE_UART1 24 | 196 | }; |
197 | #define MT7628_GPIO_MODE_I2C 20 | 197 | |
198 | #define MT7628_GPIO_MODE_REFCLK 18 | 198 | static struct rt2880_pmx_func wled_an_grp_mt7628[] = { |
199 | #define MT7628_GPIO_MODE_PERST 16 | 199 | FUNC("rsvd", 3, 35, 1), |
200 | #define MT7628_GPIO_MODE_WDT 14 | 200 | FUNC("rsvd", 2, 35, 1), |
201 | #define MT7628_GPIO_MODE_SPI 12 | 201 | FUNC("gpio", 1, 35, 1), |
202 | #define MT7628_GPIO_MODE_SDMODE 10 | 202 | FUNC("wled_an", 0, 35, 1), |
203 | #define MT7628_GPIO_MODE_UART0 8 | 203 | }; |
204 | #define MT7628_GPIO_MODE_I2S 6 | 204 | |
205 | #define MT7628_GPIO_MODE_CS1 4 | 205 | #define MT7628_GPIO_MODE_MASK 0x3 |
206 | #define MT7628_GPIO_MODE_SPIS 2 | 206 | |
207 | #define MT7628_GPIO_MODE_GPIO 0 | 207 | #define MT7628_GPIO_MODE_WLED_KN 48 |
208 | #define MT7628_GPIO_MODE_WLED_AN 32 | ||
209 | #define MT7628_GPIO_MODE_PWM1 30 | ||
210 | #define MT7628_GPIO_MODE_PWM0 28 | ||
211 | #define MT7628_GPIO_MODE_UART2 26 | ||
212 | #define MT7628_GPIO_MODE_UART1 24 | ||
213 | #define MT7628_GPIO_MODE_I2C 20 | ||
214 | #define MT7628_GPIO_MODE_REFCLK 18 | ||
215 | #define MT7628_GPIO_MODE_PERST 16 | ||
216 | #define MT7628_GPIO_MODE_WDT 14 | ||
217 | #define MT7628_GPIO_MODE_SPI 12 | ||
218 | #define MT7628_GPIO_MODE_SDMODE 10 | ||
219 | #define MT7628_GPIO_MODE_UART0 8 | ||
220 | #define MT7628_GPIO_MODE_I2S 6 | ||
221 | #define MT7628_GPIO_MODE_CS1 4 | ||
222 | #define MT7628_GPIO_MODE_SPIS 2 | ||
223 | #define MT7628_GPIO_MODE_GPIO 0 | ||
208 | 224 | ||
209 | static struct rt2880_pmx_group mt7628an_pinmux_data[] = { | 225 | static struct rt2880_pmx_group mt7628an_pinmux_data[] = { |
210 | GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK, | 226 | GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK, |
211 | 1, MT7628_GPIO_MODE_PWM1), | 227 | 1, MT7628_GPIO_MODE_PWM1), |
212 | GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK, | 228 | GRP_G("pmw0", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK, |
213 | 1, MT7628_GPIO_MODE_PWM0), | 229 | 1, MT7628_GPIO_MODE_PWM0), |
214 | GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK, | 230 | GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK, |
215 | 1, MT7628_GPIO_MODE_UART2), | 231 | 1, MT7628_GPIO_MODE_UART2), |
@@ -233,6 +249,10 @@ static struct rt2880_pmx_group mt7628an_pinmux_data[] = { | |||
233 | 1, MT7628_GPIO_MODE_SPIS), | 249 | 1, MT7628_GPIO_MODE_SPIS), |
234 | GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, | 250 | GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, |
235 | 1, MT7628_GPIO_MODE_GPIO), | 251 | 1, MT7628_GPIO_MODE_GPIO), |
252 | GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
253 | 1, MT7628_GPIO_MODE_WLED_AN), | ||
254 | GRP_G("wled_kn", wled_kn_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
255 | 1, MT7628_GPIO_MODE_WLED_KN), | ||
236 | { 0 } | 256 | { 0 } |
237 | }; | 257 | }; |
238 | 258 | ||
@@ -436,10 +456,13 @@ void __init ralink_clk_init(void) | |||
436 | ralink_clk_add("10000100.timer", periph_rate); | 456 | ralink_clk_add("10000100.timer", periph_rate); |
437 | ralink_clk_add("10000120.watchdog", periph_rate); | 457 | ralink_clk_add("10000120.watchdog", periph_rate); |
438 | ralink_clk_add("10000b00.spi", sys_rate); | 458 | ralink_clk_add("10000b00.spi", sys_rate); |
459 | ralink_clk_add("10000b40.spi", sys_rate); | ||
439 | ralink_clk_add("10000c00.uartlite", periph_rate); | 460 | ralink_clk_add("10000c00.uartlite", periph_rate); |
461 | ralink_clk_add("10000d00.uart1", periph_rate); | ||
462 | ralink_clk_add("10000e00.uart2", periph_rate); | ||
440 | ralink_clk_add("10180000.wmac", xtal_rate); | 463 | ralink_clk_add("10180000.wmac", xtal_rate); |
441 | 464 | ||
442 | if (IS_ENABLED(CONFIG_USB) && is_mt76x8()) { | 465 | if (IS_ENABLED(CONFIG_USB) && !is_mt76x8()) { |
443 | /* | 466 | /* |
444 | * When the CPU goes into sleep mode, the BUS clock will be | 467 | * When the CPU goes into sleep mode, the BUS clock will be |
445 | * too low for USB to function properly. Adjust the busses | 468 | * too low for USB to function properly. Adjust the busses |
@@ -552,7 +575,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
552 | } | 575 | } |
553 | 576 | ||
554 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, | 577 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, |
555 | "Ralink %s ver:%u eco:%u", | 578 | "MediaTek %s ver:%u eco:%u", |
556 | name, | 579 | name, |
557 | (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, | 580 | (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, |
558 | (rev & CHIP_REV_ECO_MASK)); | 581 | (rev & CHIP_REV_ECO_MASK)); |
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c new file mode 100644 index 000000000000..e9b9fa3e1e51 --- /dev/null +++ b/arch/mips/ralink/mt7621.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> | ||
7 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | #include <asm/mipsregs.h> | ||
15 | #include <asm/smp-ops.h> | ||
16 | #include <asm/mips-cm.h> | ||
17 | #include <asm/mips-cpc.h> | ||
18 | #include <asm/mach-ralink/ralink_regs.h> | ||
19 | #include <asm/mach-ralink/mt7621.h> | ||
20 | |||
21 | #include <pinmux.h> | ||
22 | |||
23 | #include "common.h" | ||
24 | |||
25 | #define SYSC_REG_SYSCFG 0x10 | ||
26 | #define SYSC_REG_CPLL_CLKCFG0 0x2c | ||
27 | #define SYSC_REG_CUR_CLK_STS 0x44 | ||
28 | #define CPU_CLK_SEL (BIT(30) | BIT(31)) | ||
29 | |||
30 | #define MT7621_GPIO_MODE_UART1 1 | ||
31 | #define MT7621_GPIO_MODE_I2C 2 | ||
32 | #define MT7621_GPIO_MODE_UART3_MASK 0x3 | ||
33 | #define MT7621_GPIO_MODE_UART3_SHIFT 3 | ||
34 | #define MT7621_GPIO_MODE_UART3_GPIO 1 | ||
35 | #define MT7621_GPIO_MODE_UART2_MASK 0x3 | ||
36 | #define MT7621_GPIO_MODE_UART2_SHIFT 5 | ||
37 | #define MT7621_GPIO_MODE_UART2_GPIO 1 | ||
38 | #define MT7621_GPIO_MODE_JTAG 7 | ||
39 | #define MT7621_GPIO_MODE_WDT_MASK 0x3 | ||
40 | #define MT7621_GPIO_MODE_WDT_SHIFT 8 | ||
41 | #define MT7621_GPIO_MODE_WDT_GPIO 1 | ||
42 | #define MT7621_GPIO_MODE_PCIE_RST 0 | ||
43 | #define MT7621_GPIO_MODE_PCIE_REF 2 | ||
44 | #define MT7621_GPIO_MODE_PCIE_MASK 0x3 | ||
45 | #define MT7621_GPIO_MODE_PCIE_SHIFT 10 | ||
46 | #define MT7621_GPIO_MODE_PCIE_GPIO 1 | ||
47 | #define MT7621_GPIO_MODE_MDIO_MASK 0x3 | ||
48 | #define MT7621_GPIO_MODE_MDIO_SHIFT 12 | ||
49 | #define MT7621_GPIO_MODE_MDIO_GPIO 1 | ||
50 | #define MT7621_GPIO_MODE_RGMII1 14 | ||
51 | #define MT7621_GPIO_MODE_RGMII2 15 | ||
52 | #define MT7621_GPIO_MODE_SPI_MASK 0x3 | ||
53 | #define MT7621_GPIO_MODE_SPI_SHIFT 16 | ||
54 | #define MT7621_GPIO_MODE_SPI_GPIO 1 | ||
55 | #define MT7621_GPIO_MODE_SDHCI_MASK 0x3 | ||
56 | #define MT7621_GPIO_MODE_SDHCI_SHIFT 18 | ||
57 | #define MT7621_GPIO_MODE_SDHCI_GPIO 1 | ||
58 | |||
59 | static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) }; | ||
60 | static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) }; | ||
61 | static struct rt2880_pmx_func uart3_grp[] = { | ||
62 | FUNC("uart3", 0, 5, 4), | ||
63 | FUNC("i2s", 2, 5, 4), | ||
64 | FUNC("spdif3", 3, 5, 4), | ||
65 | }; | ||
66 | static struct rt2880_pmx_func uart2_grp[] = { | ||
67 | FUNC("uart2", 0, 9, 4), | ||
68 | FUNC("pcm", 2, 9, 4), | ||
69 | FUNC("spdif2", 3, 9, 4), | ||
70 | }; | ||
71 | static struct rt2880_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) }; | ||
72 | static struct rt2880_pmx_func wdt_grp[] = { | ||
73 | FUNC("wdt rst", 0, 18, 1), | ||
74 | FUNC("wdt refclk", 2, 18, 1), | ||
75 | }; | ||
76 | static struct rt2880_pmx_func pcie_rst_grp[] = { | ||
77 | FUNC("pcie rst", MT7621_GPIO_MODE_PCIE_RST, 19, 1), | ||
78 | FUNC("pcie refclk", MT7621_GPIO_MODE_PCIE_REF, 19, 1) | ||
79 | }; | ||
80 | static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) }; | ||
81 | static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) }; | ||
82 | static struct rt2880_pmx_func spi_grp[] = { | ||
83 | FUNC("spi", 0, 34, 7), | ||
84 | FUNC("nand1", 2, 34, 7), | ||
85 | }; | ||
86 | static struct rt2880_pmx_func sdhci_grp[] = { | ||
87 | FUNC("sdhci", 0, 41, 8), | ||
88 | FUNC("nand2", 2, 41, 8), | ||
89 | }; | ||
90 | static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) }; | ||
91 | |||
92 | static struct rt2880_pmx_group mt7621_pinmux_data[] = { | ||
93 | GRP("uart1", uart1_grp, 1, MT7621_GPIO_MODE_UART1), | ||
94 | GRP("i2c", i2c_grp, 1, MT7621_GPIO_MODE_I2C), | ||
95 | GRP_G("uart3", uart3_grp, MT7621_GPIO_MODE_UART3_MASK, | ||
96 | MT7621_GPIO_MODE_UART3_GPIO, MT7621_GPIO_MODE_UART3_SHIFT), | ||
97 | GRP_G("uart2", uart2_grp, MT7621_GPIO_MODE_UART2_MASK, | ||
98 | MT7621_GPIO_MODE_UART2_GPIO, MT7621_GPIO_MODE_UART2_SHIFT), | ||
99 | GRP("jtag", jtag_grp, 1, MT7621_GPIO_MODE_JTAG), | ||
100 | GRP_G("wdt", wdt_grp, MT7621_GPIO_MODE_WDT_MASK, | ||
101 | MT7621_GPIO_MODE_WDT_GPIO, MT7621_GPIO_MODE_WDT_SHIFT), | ||
102 | GRP_G("pcie", pcie_rst_grp, MT7621_GPIO_MODE_PCIE_MASK, | ||
103 | MT7621_GPIO_MODE_PCIE_GPIO, MT7621_GPIO_MODE_PCIE_SHIFT), | ||
104 | GRP_G("mdio", mdio_grp, MT7621_GPIO_MODE_MDIO_MASK, | ||
105 | MT7621_GPIO_MODE_MDIO_GPIO, MT7621_GPIO_MODE_MDIO_SHIFT), | ||
106 | GRP("rgmii2", rgmii2_grp, 1, MT7621_GPIO_MODE_RGMII2), | ||
107 | GRP_G("spi", spi_grp, MT7621_GPIO_MODE_SPI_MASK, | ||
108 | MT7621_GPIO_MODE_SPI_GPIO, MT7621_GPIO_MODE_SPI_SHIFT), | ||
109 | GRP_G("sdhci", sdhci_grp, MT7621_GPIO_MODE_SDHCI_MASK, | ||
110 | MT7621_GPIO_MODE_SDHCI_GPIO, MT7621_GPIO_MODE_SDHCI_SHIFT), | ||
111 | GRP("rgmii1", rgmii1_grp, 1, MT7621_GPIO_MODE_RGMII1), | ||
112 | { 0 } | ||
113 | }; | ||
114 | |||
115 | phys_addr_t mips_cpc_default_phys_base(void) | ||
116 | { | ||
117 | panic("Cannot detect cpc address"); | ||
118 | } | ||
119 | |||
120 | void __init ralink_clk_init(void) | ||
121 | { | ||
122 | int cpu_fdiv = 0; | ||
123 | int cpu_ffrac = 0; | ||
124 | int fbdiv = 0; | ||
125 | u32 clk_sts, syscfg; | ||
126 | u8 clk_sel = 0, xtal_mode; | ||
127 | u32 cpu_clk; | ||
128 | |||
129 | if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0) | ||
130 | clk_sel = 1; | ||
131 | |||
132 | switch (clk_sel) { | ||
133 | case 0: | ||
134 | clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS); | ||
135 | cpu_fdiv = ((clk_sts >> 8) & 0x1F); | ||
136 | cpu_ffrac = (clk_sts & 0x1F); | ||
137 | cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000; | ||
138 | break; | ||
139 | |||
140 | case 1: | ||
141 | fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1; | ||
142 | syscfg = rt_sysc_r32(SYSC_REG_SYSCFG); | ||
143 | xtal_mode = (syscfg >> 6) & 0x7; | ||
144 | if (xtal_mode >= 6) { | ||
145 | /* 25Mhz Xtal */ | ||
146 | cpu_clk = 25 * fbdiv * 1000 * 1000; | ||
147 | } else if (xtal_mode >= 3) { | ||
148 | /* 40Mhz Xtal */ | ||
149 | cpu_clk = 40 * fbdiv * 1000 * 1000; | ||
150 | } else { | ||
151 | /* 20Mhz Xtal */ | ||
152 | cpu_clk = 20 * fbdiv * 1000 * 1000; | ||
153 | } | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | void __init ralink_of_remap(void) | ||
159 | { | ||
160 | rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc"); | ||
161 | rt_memc_membase = plat_of_remap_node("mtk,mt7621-memc"); | ||
162 | |||
163 | if (!rt_sysc_membase || !rt_memc_membase) | ||
164 | panic("Failed to remap core resources"); | ||
165 | } | ||
166 | |||
167 | void prom_soc_init(struct ralink_soc_info *soc_info) | ||
168 | { | ||
169 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE); | ||
170 | unsigned char *name = NULL; | ||
171 | u32 n0; | ||
172 | u32 n1; | ||
173 | u32 rev; | ||
174 | |||
175 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); | ||
176 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); | ||
177 | |||
178 | if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) { | ||
179 | name = "MT7621"; | ||
180 | soc_info->compatible = "mtk,mt7621-soc"; | ||
181 | } else { | ||
182 | panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1); | ||
183 | } | ||
184 | |||
185 | rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); | ||
186 | |||
187 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, | ||
188 | "MediaTek %s ver:%u eco:%u", | ||
189 | name, | ||
190 | (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, | ||
191 | (rev & CHIP_REV_ECO_MASK)); | ||
192 | |||
193 | soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN; | ||
194 | soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX; | ||
195 | soc_info->mem_base = MT7621_DRAM_BASE; | ||
196 | |||
197 | rt2880_pinmux_data = mt7621_pinmux_data; | ||
198 | |||
199 | /* Early detection of CMP support */ | ||
200 | mips_cm_probe(); | ||
201 | mips_cpc_probe(); | ||
202 | |||
203 | if (mips_cm_numiocu()) { | ||
204 | /* | ||
205 | * mips_cm_probe() wipes out bootloader | ||
206 | * config for CM regions and we have to configure them | ||
207 | * again. This SoC cannot talk to pamlbus devices | ||
208 | * witout proper iocu region set up. | ||
209 | * | ||
210 | * FIXME: it would be better to do this with values | ||
211 | * from DT, but we need this very early because | ||
212 | * without this we cannot talk to pretty much anything | ||
213 | * including serial. | ||
214 | */ | ||
215 | write_gcr_reg0_base(MT7621_PALMBUS_BASE); | ||
216 | write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE | | ||
217 | CM_GCR_REGn_MASK_CMTGT_IOCU0); | ||
218 | } | ||
219 | |||
220 | if (!register_cps_smp_ops()) | ||
221 | return; | ||
222 | if (!register_cmp_smp_ops()) | ||
223 | return; | ||
224 | if (!register_vsmp_smp_ops()) | ||
225 | return; | ||
226 | } | ||
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c index 844f5cd55c8f..3c84166ebcb7 100644 --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c | |||
@@ -119,5 +119,5 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
119 | soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; | 119 | soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; |
120 | 120 | ||
121 | rt2880_pinmux_data = rt2880_pinmux_data_act; | 121 | rt2880_pinmux_data = rt2880_pinmux_data_act; |
122 | ralink_soc == RT2880_SOC; | 122 | ralink_soc = RT2880_SOC; |
123 | } | 123 | } |
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c index 9e4572592065..d7c4ba43a428 100644 --- a/arch/mips/ralink/rt305x.c +++ b/arch/mips/ralink/rt305x.c | |||
@@ -201,6 +201,7 @@ void __init ralink_clk_init(void) | |||
201 | ralink_clk_add("cpu", cpu_rate); | 201 | ralink_clk_add("cpu", cpu_rate); |
202 | ralink_clk_add("sys", sys_rate); | 202 | ralink_clk_add("sys", sys_rate); |
203 | ralink_clk_add("10000b00.spi", sys_rate); | 203 | ralink_clk_add("10000b00.spi", sys_rate); |
204 | ralink_clk_add("10000b40.spi", sys_rate); | ||
204 | ralink_clk_add("10000100.timer", wdt_rate); | 205 | ralink_clk_add("10000100.timer", wdt_rate); |
205 | ralink_clk_add("10000120.watchdog", wdt_rate); | 206 | ralink_clk_add("10000120.watchdog", wdt_rate); |
206 | ralink_clk_add("10000500.uart", uart_rate); | 207 | ralink_clk_add("10000500.uart", uart_rate); |
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index 582995aaaf4e..fafec947b27d 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c | |||
@@ -109,6 +109,7 @@ void __init ralink_clk_init(void) | |||
109 | ralink_clk_add("10000120.watchdog", sys_rate); | 109 | ralink_clk_add("10000120.watchdog", sys_rate); |
110 | ralink_clk_add("10000500.uart", 40000000); | 110 | ralink_clk_add("10000500.uart", 40000000); |
111 | ralink_clk_add("10000b00.spi", sys_rate); | 111 | ralink_clk_add("10000b00.spi", sys_rate); |
112 | ralink_clk_add("10000b40.spi", sys_rate); | ||
112 | ralink_clk_add("10000c00.uartlite", 40000000); | 113 | ralink_clk_add("10000c00.uartlite", 40000000); |
113 | ralink_clk_add("10100000.ethernet", sys_rate); | 114 | ralink_clk_add("10100000.ethernet", sys_rate); |
114 | ralink_clk_add("10180000.wmac", 40000000); | 115 | ralink_clk_add("10180000.wmac", 40000000); |
diff --git a/arch/mips/ralink/timer-gic.c b/arch/mips/ralink/timer-gic.c new file mode 100644 index 000000000000..5b4f186bcf95 --- /dev/null +++ b/arch/mips/ralink/timer-gic.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> | ||
7 | * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | |||
12 | #include <linux/of.h> | ||
13 | #include <linux/clk-provider.h> | ||
14 | #include <linux/clocksource.h> | ||
15 | |||
16 | #include "common.h" | ||
17 | |||
18 | void __init plat_time_init(void) | ||
19 | { | ||
20 | ralink_of_remap(); | ||
21 | |||
22 | of_clk_init(NULL); | ||
23 | clocksource_probe(); | ||
24 | } | ||
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index 650d5d39f34d..fd1108543a71 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c | |||
@@ -89,7 +89,7 @@ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
89 | struct rb532_gpio_chip *gpch; | 89 | struct rb532_gpio_chip *gpch; |
90 | 90 | ||
91 | gpch = container_of(chip, struct rb532_gpio_chip, chip); | 91 | gpch = container_of(chip, struct rb532_gpio_chip, chip); |
92 | return rb532_get_bit(offset, gpch->regbase + GPIOD); | 92 | return !!rb532_get_bit(offset, gpch->regbase + GPIOD); |
93 | } | 93 | } |
94 | 94 | ||
95 | /* | 95 | /* |
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 9d9962ab7d25..2fd350f31f4b 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
@@ -689,7 +689,7 @@ static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset) | |||
689 | { | 689 | { |
690 | struct txx9_iocled_data *data = | 690 | struct txx9_iocled_data *data = |
691 | container_of(chip, struct txx9_iocled_data, chip); | 691 | container_of(chip, struct txx9_iocled_data, chip); |
692 | return data->cur_val & (1 << offset); | 692 | return !!(data->cur_val & (1 << offset)); |
693 | } | 693 | } |
694 | 694 | ||
695 | static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, | 695 | static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, |
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 11fc2a27fa2e..715923d5236c 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
@@ -130,6 +130,11 @@ config ORION_IRQCHIP | |||
130 | select IRQ_DOMAIN | 130 | select IRQ_DOMAIN |
131 | select MULTI_IRQ_HANDLER | 131 | select MULTI_IRQ_HANDLER |
132 | 132 | ||
133 | config PIC32_EVIC | ||
134 | bool | ||
135 | select GENERIC_IRQ_CHIP | ||
136 | select IRQ_DOMAIN | ||
137 | |||
133 | config RENESAS_INTC_IRQPIN | 138 | config RENESAS_INTC_IRQPIN |
134 | bool | 139 | bool |
135 | select IRQ_DOMAIN | 140 | select IRQ_DOMAIN |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index d4c2e4ebc308..18caacb60d58 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -58,3 +58,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o | |||
58 | obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o | 58 | obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o |
59 | obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o | 59 | obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o |
60 | obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o | 60 | obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o |
61 | obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o | ||
diff --git a/drivers/irqchip/irq-pic32-evic.c b/drivers/irqchip/irq-pic32-evic.c new file mode 100644 index 000000000000..e7155db01d55 --- /dev/null +++ b/drivers/irqchip/irq-pic32-evic.c | |||
@@ -0,0 +1,324 @@ | |||
1 | /* | ||
2 | * Cristian Birsan <cristian.birsan@microchip.com> | ||
3 | * Joshua Henderson <joshua.henderson@microchip.com> | ||
4 | * Copyright (C) 2016 Microchip Technology Inc. All rights reserved. | ||
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 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irqdomain.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/irqchip.h> | ||
19 | #include <linux/irq.h> | ||
20 | |||
21 | #include <asm/irq.h> | ||
22 | #include <asm/traps.h> | ||
23 | #include <asm/mach-pic32/pic32.h> | ||
24 | |||
25 | #define REG_INTCON 0x0000 | ||
26 | #define REG_INTSTAT 0x0020 | ||
27 | #define REG_IFS_OFFSET 0x0040 | ||
28 | #define REG_IEC_OFFSET 0x00C0 | ||
29 | #define REG_IPC_OFFSET 0x0140 | ||
30 | #define REG_OFF_OFFSET 0x0540 | ||
31 | |||
32 | #define MAJPRI_MASK 0x07 | ||
33 | #define SUBPRI_MASK 0x03 | ||
34 | #define PRIORITY_MASK 0x1F | ||
35 | |||
36 | #define PIC32_INT_PRI(pri, subpri) \ | ||
37 | ((((pri) & MAJPRI_MASK) << 2) | ((subpri) & SUBPRI_MASK)) | ||
38 | |||
39 | struct evic_chip_data { | ||
40 | u32 irq_types[NR_IRQS]; | ||
41 | u32 ext_irqs[8]; | ||
42 | }; | ||
43 | |||
44 | static struct irq_domain *evic_irq_domain; | ||
45 | static void __iomem *evic_base; | ||
46 | |||
47 | asmlinkage void __weak plat_irq_dispatch(void) | ||
48 | { | ||
49 | unsigned int irq, hwirq; | ||
50 | |||
51 | hwirq = readl(evic_base + REG_INTSTAT) & 0xFF; | ||
52 | irq = irq_linear_revmap(evic_irq_domain, hwirq); | ||
53 | do_IRQ(irq); | ||
54 | } | ||
55 | |||
56 | static struct evic_chip_data *irqd_to_priv(struct irq_data *data) | ||
57 | { | ||
58 | return (struct evic_chip_data *)data->domain->host_data; | ||
59 | } | ||
60 | |||
61 | static int pic32_set_ext_polarity(int bit, u32 type) | ||
62 | { | ||
63 | /* | ||
64 | * External interrupts can be either edge rising or edge falling, | ||
65 | * but not both. | ||
66 | */ | ||
67 | switch (type) { | ||
68 | case IRQ_TYPE_EDGE_RISING: | ||
69 | writel(BIT(bit), evic_base + PIC32_SET(REG_INTCON)); | ||
70 | break; | ||
71 | case IRQ_TYPE_EDGE_FALLING: | ||
72 | writel(BIT(bit), evic_base + PIC32_CLR(REG_INTCON)); | ||
73 | break; | ||
74 | default: | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int pic32_set_type_edge(struct irq_data *data, | ||
82 | unsigned int flow_type) | ||
83 | { | ||
84 | struct evic_chip_data *priv = irqd_to_priv(data); | ||
85 | int ret; | ||
86 | int i; | ||
87 | |||
88 | if (!(flow_type & IRQ_TYPE_EDGE_BOTH)) | ||
89 | return -EBADR; | ||
90 | |||
91 | /* set polarity for external interrupts only */ | ||
92 | for (i = 0; i < ARRAY_SIZE(priv->ext_irqs); i++) { | ||
93 | if (priv->ext_irqs[i] == data->hwirq) { | ||
94 | ret = pic32_set_ext_polarity(i + 1, flow_type); | ||
95 | if (ret) | ||
96 | return ret; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | irqd_set_trigger_type(data, flow_type); | ||
101 | |||
102 | return IRQ_SET_MASK_OK; | ||
103 | } | ||
104 | |||
105 | static void pic32_bind_evic_interrupt(int irq, int set) | ||
106 | { | ||
107 | writel(set, evic_base + REG_OFF_OFFSET + irq * 4); | ||
108 | } | ||
109 | |||
110 | static void pic32_set_irq_priority(int irq, int priority) | ||
111 | { | ||
112 | u32 reg, shift; | ||
113 | |||
114 | reg = irq / 4; | ||
115 | shift = (irq % 4) * 8; | ||
116 | |||
117 | writel(PRIORITY_MASK << shift, | ||
118 | evic_base + PIC32_CLR(REG_IPC_OFFSET + reg * 0x10)); | ||
119 | writel(priority << shift, | ||
120 | evic_base + PIC32_SET(REG_IPC_OFFSET + reg * 0x10)); | ||
121 | } | ||
122 | |||
123 | #define IRQ_REG_MASK(_hwirq, _reg, _mask) \ | ||
124 | do { \ | ||
125 | _reg = _hwirq / 32; \ | ||
126 | _mask = 1 << (_hwirq % 32); \ | ||
127 | } while (0) | ||
128 | |||
129 | static int pic32_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
130 | irq_hw_number_t hw) | ||
131 | { | ||
132 | struct evic_chip_data *priv = d->host_data; | ||
133 | struct irq_data *data; | ||
134 | int ret; | ||
135 | u32 iecclr, ifsclr; | ||
136 | u32 reg, mask; | ||
137 | |||
138 | ret = irq_map_generic_chip(d, virq, hw); | ||
139 | if (ret) | ||
140 | return ret; | ||
141 | |||
142 | /* | ||
143 | * Piggyback on xlate function to move to an alternate chip as necessary | ||
144 | * at time of mapping instead of allowing the flow handler/chip to be | ||
145 | * changed later. This requires all interrupts to be configured through | ||
146 | * DT. | ||
147 | */ | ||
148 | if (priv->irq_types[hw] & IRQ_TYPE_SENSE_MASK) { | ||
149 | data = irq_domain_get_irq_data(d, virq); | ||
150 | irqd_set_trigger_type(data, priv->irq_types[hw]); | ||
151 | irq_setup_alt_chip(data, priv->irq_types[hw]); | ||
152 | } | ||
153 | |||
154 | IRQ_REG_MASK(hw, reg, mask); | ||
155 | |||
156 | iecclr = PIC32_CLR(REG_IEC_OFFSET + reg * 0x10); | ||
157 | ifsclr = PIC32_CLR(REG_IFS_OFFSET + reg * 0x10); | ||
158 | |||
159 | /* mask and clear flag */ | ||
160 | writel(mask, evic_base + iecclr); | ||
161 | writel(mask, evic_base + ifsclr); | ||
162 | |||
163 | /* default priority is required */ | ||
164 | pic32_set_irq_priority(hw, PIC32_INT_PRI(2, 0)); | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | int pic32_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, | ||
170 | const u32 *intspec, unsigned int intsize, | ||
171 | irq_hw_number_t *out_hwirq, unsigned int *out_type) | ||
172 | { | ||
173 | struct evic_chip_data *priv = d->host_data; | ||
174 | |||
175 | if (WARN_ON(intsize < 2)) | ||
176 | return -EINVAL; | ||
177 | |||
178 | if (WARN_ON(intspec[0] >= NR_IRQS)) | ||
179 | return -EINVAL; | ||
180 | |||
181 | *out_hwirq = intspec[0]; | ||
182 | *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; | ||
183 | |||
184 | priv->irq_types[intspec[0]] = intspec[1] & IRQ_TYPE_SENSE_MASK; | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static const struct irq_domain_ops pic32_irq_domain_ops = { | ||
190 | .map = pic32_irq_domain_map, | ||
191 | .xlate = pic32_irq_domain_xlate, | ||
192 | }; | ||
193 | |||
194 | static void __init pic32_ext_irq_of_init(struct irq_domain *domain) | ||
195 | { | ||
196 | struct device_node *node = irq_domain_get_of_node(domain); | ||
197 | struct evic_chip_data *priv = domain->host_data; | ||
198 | struct property *prop; | ||
199 | const __le32 *p; | ||
200 | u32 hwirq; | ||
201 | int i = 0; | ||
202 | const char *pname = "microchip,external-irqs"; | ||
203 | |||
204 | of_property_for_each_u32(node, pname, prop, p, hwirq) { | ||
205 | if (i >= ARRAY_SIZE(priv->ext_irqs)) { | ||
206 | pr_warn("More than %d external irq, skip rest\n", | ||
207 | ARRAY_SIZE(priv->ext_irqs)); | ||
208 | break; | ||
209 | } | ||
210 | |||
211 | priv->ext_irqs[i] = hwirq; | ||
212 | i++; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static int __init pic32_of_init(struct device_node *node, | ||
217 | struct device_node *parent) | ||
218 | { | ||
219 | struct irq_chip_generic *gc; | ||
220 | struct evic_chip_data *priv; | ||
221 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | ||
222 | int nchips, ret; | ||
223 | int i; | ||
224 | |||
225 | nchips = DIV_ROUND_UP(NR_IRQS, 32); | ||
226 | |||
227 | evic_base = of_iomap(node, 0); | ||
228 | if (!evic_base) | ||
229 | return -ENOMEM; | ||
230 | |||
231 | priv = kcalloc(nchips, sizeof(*priv), GFP_KERNEL); | ||
232 | if (!priv) { | ||
233 | ret = -ENOMEM; | ||
234 | goto err_iounmap; | ||
235 | } | ||
236 | |||
237 | evic_irq_domain = irq_domain_add_linear(node, nchips * 32, | ||
238 | &pic32_irq_domain_ops, | ||
239 | priv); | ||
240 | if (!evic_irq_domain) { | ||
241 | ret = -ENOMEM; | ||
242 | goto err_free_priv; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * The PIC32 EVIC has a linear list of irqs and the type of each | ||
247 | * irq is determined by the hardware peripheral the EVIC is arbitrating. | ||
248 | * These irq types are defined in the datasheet as "persistent" and | ||
249 | * "non-persistent" which are mapped here to level and edge | ||
250 | * respectively. To manage the different flow handler requirements of | ||
251 | * each irq type, different chip_types are used. | ||
252 | */ | ||
253 | ret = irq_alloc_domain_generic_chips(evic_irq_domain, 32, 2, | ||
254 | "evic-level", handle_level_irq, | ||
255 | clr, 0, 0); | ||
256 | if (ret) | ||
257 | goto err_domain_remove; | ||
258 | |||
259 | board_bind_eic_interrupt = &pic32_bind_evic_interrupt; | ||
260 | |||
261 | for (i = 0; i < nchips; i++) { | ||
262 | u32 ifsclr = PIC32_CLR(REG_IFS_OFFSET + (i * 0x10)); | ||
263 | u32 iec = REG_IEC_OFFSET + (i * 0x10); | ||
264 | |||
265 | gc = irq_get_domain_generic_chip(evic_irq_domain, i * 32); | ||
266 | |||
267 | gc->reg_base = evic_base; | ||
268 | gc->unused = 0; | ||
269 | |||
270 | /* | ||
271 | * Level/persistent interrupts have a special requirement that | ||
272 | * the condition generating the interrupt be cleared before the | ||
273 | * interrupt flag (ifs) can be cleared. chip.irq_eoi is used to | ||
274 | * complete the interrupt with an ack. | ||
275 | */ | ||
276 | gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK; | ||
277 | gc->chip_types[0].handler = handle_fasteoi_irq; | ||
278 | gc->chip_types[0].regs.ack = ifsclr; | ||
279 | gc->chip_types[0].regs.mask = iec; | ||
280 | gc->chip_types[0].chip.name = "evic-level"; | ||
281 | gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit; | ||
282 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; | ||
283 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | ||
284 | gc->chip_types[0].chip.flags = IRQCHIP_SKIP_SET_WAKE; | ||
285 | |||
286 | /* Edge interrupts */ | ||
287 | gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; | ||
288 | gc->chip_types[1].handler = handle_edge_irq; | ||
289 | gc->chip_types[1].regs.ack = ifsclr; | ||
290 | gc->chip_types[1].regs.mask = iec; | ||
291 | gc->chip_types[1].chip.name = "evic-edge"; | ||
292 | gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit; | ||
293 | gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit; | ||
294 | gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit; | ||
295 | gc->chip_types[1].chip.irq_set_type = pic32_set_type_edge; | ||
296 | gc->chip_types[1].chip.flags = IRQCHIP_SKIP_SET_WAKE; | ||
297 | |||
298 | gc->private = &priv[i]; | ||
299 | } | ||
300 | |||
301 | irq_set_default_host(evic_irq_domain); | ||
302 | |||
303 | /* | ||
304 | * External interrupts have software configurable edge polarity. These | ||
305 | * interrupts are defined in DT allowing polarity to be configured only | ||
306 | * for these interrupts when requested. | ||
307 | */ | ||
308 | pic32_ext_irq_of_init(evic_irq_domain); | ||
309 | |||
310 | return 0; | ||
311 | |||
312 | err_domain_remove: | ||
313 | irq_domain_remove(evic_irq_domain); | ||
314 | |||
315 | err_free_priv: | ||
316 | kfree(priv); | ||
317 | |||
318 | err_iounmap: | ||
319 | iounmap(evic_base); | ||
320 | |||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | IRQCHIP_DECLARE(pic32_evic, "microchip,pic32mzda-evic", pic32_of_init); | ||
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 440936998593..cec3188a170d 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
26 | 26 | ||
27 | #include <linux/bcm963xx_tag.h> | ||
27 | #include <linux/crc32.h> | 28 | #include <linux/crc32.h> |
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
29 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
@@ -34,11 +35,8 @@ | |||
34 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
35 | 36 | ||
36 | #include <asm/mach-bcm63xx/bcm63xx_nvram.h> | 37 | #include <asm/mach-bcm63xx/bcm63xx_nvram.h> |
37 | #include <asm/mach-bcm63xx/bcm963xx_tag.h> | ||
38 | #include <asm/mach-bcm63xx/board_bcm963xx.h> | 38 | #include <asm/mach-bcm63xx/board_bcm963xx.h> |
39 | 39 | ||
40 | #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ | ||
41 | |||
42 | #define BCM63XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ | 40 | #define BCM63XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ |
43 | 41 | ||
44 | #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 | 42 | #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 |
@@ -123,8 +121,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
123 | pr_info("CFE boot tag found with version %s and board type %s\n", | 121 | pr_info("CFE boot tag found with version %s and board type %s\n", |
124 | tagversion, boardid); | 122 | tagversion, boardid); |
125 | 123 | ||
126 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; | 124 | kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; |
127 | rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; | 125 | rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; |
128 | spareaddr = roundup(totallen, master->erasesize) + cfelen; | 126 | spareaddr = roundup(totallen, master->erasesize) + cfelen; |
129 | 127 | ||
130 | if (rootfsaddr < kerneladdr) { | 128 | if (rootfsaddr < kerneladdr) { |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3a93755e880f..051ea4809c14 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -491,6 +491,7 @@ static inline int arch_elf_pt_proc(struct elfhdr *ehdr, | |||
491 | * arch_check_elf() - check an ELF executable | 491 | * arch_check_elf() - check an ELF executable |
492 | * @ehdr: The main ELF header | 492 | * @ehdr: The main ELF header |
493 | * @has_interp: True if the ELF has an interpreter, else false. | 493 | * @has_interp: True if the ELF has an interpreter, else false. |
494 | * @interp_ehdr: The interpreter's ELF header | ||
494 | * @state: Architecture-specific state preserved throughout the process | 495 | * @state: Architecture-specific state preserved throughout the process |
495 | * of loading the ELF. | 496 | * of loading the ELF. |
496 | * | 497 | * |
@@ -502,6 +503,7 @@ static inline int arch_elf_pt_proc(struct elfhdr *ehdr, | |||
502 | * with that return code. | 503 | * with that return code. |
503 | */ | 504 | */ |
504 | static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp, | 505 | static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp, |
506 | struct elfhdr *interp_ehdr, | ||
505 | struct arch_elf_state *state) | 507 | struct arch_elf_state *state) |
506 | { | 508 | { |
507 | /* Dummy implementation, always proceed */ | 509 | /* Dummy implementation, always proceed */ |
@@ -829,7 +831,9 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
829 | * still possible to return an error to the code that invoked | 831 | * still possible to return an error to the code that invoked |
830 | * the exec syscall. | 832 | * the exec syscall. |
831 | */ | 833 | */ |
832 | retval = arch_check_elf(&loc->elf_ex, !!interpreter, &arch_state); | 834 | retval = arch_check_elf(&loc->elf_ex, |
835 | !!interpreter, &loc->interp_elf_ex, | ||
836 | &arch_state); | ||
833 | if (retval) | 837 | if (retval) |
834 | goto out_free_dentry; | 838 | goto out_free_dentry; |
835 | 839 | ||
diff --git a/include/linux/bcm963xx_nvram.h b/include/linux/bcm963xx_nvram.h new file mode 100644 index 000000000000..290c231b8cf1 --- /dev/null +++ b/include/linux/bcm963xx_nvram.h | |||
@@ -0,0 +1,112 @@ | |||
1 | #ifndef __LINUX_BCM963XX_NVRAM_H__ | ||
2 | #define __LINUX_BCM963XX_NVRAM_H__ | ||
3 | |||
4 | #include <linux/crc32.h> | ||
5 | #include <linux/if_ether.h> | ||
6 | #include <linux/sizes.h> | ||
7 | #include <linux/types.h> | ||
8 | |||
9 | /* | ||
10 | * Broadcom BCM963xx SoC board nvram data structure. | ||
11 | * | ||
12 | * The nvram structure varies in size depending on the SoC board version. Use | ||
13 | * the appropriate minimum BCM963XX_NVRAM_*_SIZE define for the information | ||
14 | * you need instead of sizeof(struct bcm963xx_nvram) as this may change. | ||
15 | */ | ||
16 | |||
17 | #define BCM963XX_NVRAM_V4_SIZE 300 | ||
18 | #define BCM963XX_NVRAM_V5_SIZE (1 * SZ_1K) | ||
19 | |||
20 | #define BCM963XX_DEFAULT_PSI_SIZE 64 | ||
21 | |||
22 | enum bcm963xx_nvram_nand_part { | ||
23 | BCM963XX_NVRAM_NAND_PART_BOOT = 0, | ||
24 | BCM963XX_NVRAM_NAND_PART_ROOTFS_1, | ||
25 | BCM963XX_NVRAM_NAND_PART_ROOTFS_2, | ||
26 | BCM963XX_NVRAM_NAND_PART_DATA, | ||
27 | BCM963XX_NVRAM_NAND_PART_BBT, | ||
28 | |||
29 | __BCM963XX_NVRAM_NAND_NR_PARTS | ||
30 | }; | ||
31 | |||
32 | struct bcm963xx_nvram { | ||
33 | u32 version; | ||
34 | char bootline[256]; | ||
35 | char name[16]; | ||
36 | u32 main_tp_number; | ||
37 | u32 psi_size; | ||
38 | u32 mac_addr_count; | ||
39 | u8 mac_addr_base[ETH_ALEN]; | ||
40 | u8 __reserved1[2]; | ||
41 | u32 checksum_v4; | ||
42 | |||
43 | u8 __reserved2[292]; | ||
44 | u32 nand_part_offset[__BCM963XX_NVRAM_NAND_NR_PARTS]; | ||
45 | u32 nand_part_size[__BCM963XX_NVRAM_NAND_NR_PARTS]; | ||
46 | u8 __reserved3[388]; | ||
47 | u32 checksum_v5; | ||
48 | }; | ||
49 | |||
50 | #define BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, part) \ | ||
51 | bcm963xx_nvram_nand_part_offset(nvram, BCM963XX_NVRAM_NAND_PART_ ##part) | ||
52 | |||
53 | static inline u64 __pure bcm963xx_nvram_nand_part_offset( | ||
54 | const struct bcm963xx_nvram *nvram, | ||
55 | enum bcm963xx_nvram_nand_part part) | ||
56 | { | ||
57 | return nvram->nand_part_offset[part] * SZ_1K; | ||
58 | } | ||
59 | |||
60 | #define BCM963XX_NVRAM_NAND_PART_SIZE(nvram, part) \ | ||
61 | bcm963xx_nvram_nand_part_size(nvram, BCM963XX_NVRAM_NAND_PART_ ##part) | ||
62 | |||
63 | static inline u64 __pure bcm963xx_nvram_nand_part_size( | ||
64 | const struct bcm963xx_nvram *nvram, | ||
65 | enum bcm963xx_nvram_nand_part part) | ||
66 | { | ||
67 | return nvram->nand_part_size[part] * SZ_1K; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * bcm963xx_nvram_checksum - Verify nvram checksum | ||
72 | * | ||
73 | * @nvram: pointer to full size nvram data structure | ||
74 | * @expected_out: optional pointer to store expected checksum value | ||
75 | * @actual_out: optional pointer to store actual checksum value | ||
76 | * | ||
77 | * Return: 0 if the checksum is valid, otherwise -EINVAL | ||
78 | */ | ||
79 | static int __maybe_unused bcm963xx_nvram_checksum( | ||
80 | const struct bcm963xx_nvram *nvram, | ||
81 | u32 *expected_out, u32 *actual_out) | ||
82 | { | ||
83 | u32 expected, actual; | ||
84 | size_t len; | ||
85 | |||
86 | if (nvram->version <= 4) { | ||
87 | expected = nvram->checksum_v4; | ||
88 | len = BCM963XX_NVRAM_V4_SIZE - sizeof(u32); | ||
89 | } else { | ||
90 | expected = nvram->checksum_v5; | ||
91 | len = BCM963XX_NVRAM_V5_SIZE - sizeof(u32); | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Calculate the CRC32 value for the nvram with a checksum value | ||
96 | * of 0 without modifying or copying the nvram by combining: | ||
97 | * - The CRC32 of the nvram without the checksum value | ||
98 | * - The CRC32 of a zero checksum value (which is also 0) | ||
99 | */ | ||
100 | actual = crc32_le_combine( | ||
101 | crc32_le(~0, (u8 *)nvram, len), 0, sizeof(u32)); | ||
102 | |||
103 | if (expected_out) | ||
104 | *expected_out = expected; | ||
105 | |||
106 | if (actual_out) | ||
107 | *actual_out = actual; | ||
108 | |||
109 | return expected == actual ? 0 : -EINVAL; | ||
110 | }; | ||
111 | |||
112 | #endif /* __LINUX_BCM963XX_NVRAM_H__ */ | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/include/linux/bcm963xx_tag.h index 1e6b587f62c9..161c7b37a77b 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h +++ b/include/linux/bcm963xx_tag.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef __BCM963XX_TAG_H | 1 | #ifndef __LINUX_BCM963XX_TAG_H__ |
2 | #define __BCM963XX_TAG_H | 2 | #define __LINUX_BCM963XX_TAG_H__ |
3 | |||
4 | #include <linux/types.h> | ||
3 | 5 | ||
4 | #define TAGVER_LEN 4 /* Length of Tag Version */ | 6 | #define TAGVER_LEN 4 /* Length of Tag Version */ |
5 | #define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ | 7 | #define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ |
@@ -10,8 +12,7 @@ | |||
10 | #define CHIPID_LEN 6 /* Chip Id Length */ | 12 | #define CHIPID_LEN 6 /* Chip Id Length */ |
11 | #define IMAGE_LEN 10 /* Length of Length Field */ | 13 | #define IMAGE_LEN 10 /* Length of Length Field */ |
12 | #define ADDRESS_LEN 12 /* Length of Address field */ | 14 | #define ADDRESS_LEN 12 /* Length of Address field */ |
13 | #define DUALFLAG_LEN 2 /* Dual Image flag Length */ | 15 | #define IMAGE_SEQUENCE_LEN 4 /* Image sequence Length */ |
14 | #define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ | ||
15 | #define RSASIG_LEN 20 /* Length of RSA Signature in tag */ | 16 | #define RSASIG_LEN 20 /* Length of RSA Signature in tag */ |
16 | #define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ | 17 | #define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ |
17 | #define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ | 18 | #define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ |
@@ -26,6 +27,11 @@ | |||
26 | "DWV-S0", \ | 27 | "DWV-S0", \ |
27 | } | 28 | } |
28 | 29 | ||
30 | /* Extended flash address, needs to be subtracted | ||
31 | * from bcm_tag flash image offsets. | ||
32 | */ | ||
33 | #define BCM963XX_EXTENDED_SIZE 0xBFC00000 | ||
34 | |||
29 | /* | 35 | /* |
30 | * The broadcom firmware assumes the rootfs starts the image, | 36 | * The broadcom firmware assumes the rootfs starts the image, |
31 | * therefore uses the rootfs start (flash_image_address) | 37 | * therefore uses the rootfs start (flash_image_address) |
@@ -65,10 +71,10 @@ struct bcm_tag { | |||
65 | char kernel_address[ADDRESS_LEN]; | 71 | char kernel_address[ADDRESS_LEN]; |
66 | /* 128-137: Size of kernel */ | 72 | /* 128-137: Size of kernel */ |
67 | char kernel_length[IMAGE_LEN]; | 73 | char kernel_length[IMAGE_LEN]; |
68 | /* 138-139: Unused at the moment */ | 74 | /* 138-141: Image sequence number |
69 | char dual_image[DUALFLAG_LEN]; | 75 | * (to be incremented when flashed with a new image) |
70 | /* 140-141: Unused at the moment */ | 76 | */ |
71 | char inactive_flag[INACTIVEFLAG_LEN]; | 77 | char image_sequence[IMAGE_SEQUENCE_LEN]; |
72 | /* 142-161: RSA Signature (not used; some vendors may use this) */ | 78 | /* 142-161: RSA Signature (not used; some vendors may use this) */ |
73 | char rsa_signature[RSASIG_LEN]; | 79 | char rsa_signature[RSASIG_LEN]; |
74 | /* 162-191: Compilation and related information (not used in OpenWrt) */ | 80 | /* 162-191: Compilation and related information (not used in OpenWrt) */ |
@@ -93,4 +99,4 @@ struct bcm_tag { | |||
93 | char reserved2[16]; | 99 | char reserved2[16]; |
94 | }; | 100 | }; |
95 | 101 | ||
96 | #endif /* __BCM63XX_TAG_H */ | 102 | #endif /* __LINUX_BCM63XX_TAG_H__ */ |
diff --git a/include/linux/platform_data/sdhci-pic32.h b/include/linux/platform_data/sdhci-pic32.h new file mode 100644 index 000000000000..7e0efe64c8c5 --- /dev/null +++ b/include/linux/platform_data/sdhci-pic32.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Purna Chandra Mandal, purna.mandal@microchip.com | ||
3 | * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | */ | ||
14 | #ifndef __PIC32_SDHCI_PDATA_H__ | ||
15 | #define __PIC32_SDHCI_PDATA_H__ | ||
16 | |||
17 | struct pic32_sdhci_platform_data { | ||
18 | /* read & write fifo threshold */ | ||
19 | int (*setup_dma)(u32 rfifo, u32 wfifo); | ||
20 | }; | ||
21 | |||
22 | #endif | ||