diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-07 22:22:44 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-07 22:22:44 +0300 |
commit | 8578953687393945ccb84488973784b9a745b059 (patch) | |
tree | fbf9ec529fcefc5b9640c0a8e9733d7a8acfe690 | |
parent | e03ab6c4ade684bf5d2bf53674440bcb6f476949 (diff) | |
parent | 8f2256d8eaf5acef3b49ea27edf79cc1069c4de9 (diff) | |
download | linux-8578953687393945ccb84488973784b9a745b059.tar.xz |
Merge tag 'mips_4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/mips
Pull MIPS updates from James Hogan:
"These are the main MIPS changes for 4.16.
Rough overview:
(1) Basic support for the Ingenic JZ4770 based GCW Zero open-source
handheld video game console
(2) Support for the Ranchu board (used by Android emulator)
(3) Various cleanups and misc improvements
More detailed summary:
Fixes:
- Fix generic platform's USB_*HCI_BIG_ENDIAN selects (4.9)
- Fix vmlinuz default build when ZBOOT selected
- Fix clean up of vmlinuz targets
- Fix command line duplication (in preparation for Ingenic JZ4770)
Miscellaneous:
- Allow Processor ID reads to be to be optimised away by the compiler
(improves performance when running in guest)
- Push ARCH_MIGHT_HAVE_PC_SERIO/PARPORT down to platform level to
disable on generic platform with Ranchu board support
- Add helpers for assembler macro instructions for older assemblers
- Use assembler macro instructions to support VZ, XPA & MSA
operations on older assemblers, removing C wrapper duplication
- Various improvements to VZ & XPA assembly wrappers
- Add drivers/platform/mips/ to MIPS MAINTAINERS entry
Minor cleanups:
- Misc FPU emulation cleanups (removal of unnecessary include, moving
macros to common header, checkpatch and sparse fixes)
- Remove duplicate assignment of core in play_dead()
- Remove duplication in watchpoint handling
- Remove mips_dma_mapping_error() stub
- Use NULL instead of 0 in prepare_ftrace_return()
- Use proper kernel-doc Return keyword for
__compute_return_epc_for_insn()
- Remove duplicate semicolon in csum_fold()
Platform support:
Broadcom:
- Enable ZBOOT on BCM47xx
Generic platform:
- Add Ranchu board support, used by Android emulator
- Fix machine compatible string matching for Ranchu
- Support GIC in EIC mode
Ingenic platforms:
- Add DT, defconfig and other support for JZ4770 SoC and GCW Zero
- Support dynamnic machine types (i.e. JZ4740 / JZ4770 / JZ4780)
- Add Ingenic JZ4770 CGU clocks
- General Ingenic clk changes to prepare for JZ4770 SoC support
- Use common command line handling code
- Add DT vendor prefix to GCW (Game Consoles Worldwide)
Loongson:
- Add MAINTAINERS entry for Loongson2 and Loongson3 platforms
- Drop 32-bit support for Loongson 2E/2F devices
- Fix build failures due to multiple use of 'MEM_RESERVED'"
* tag 'mips_4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/mips: (53 commits)
MIPS: Malta: Sanitize mouse and keyboard configuration.
MIPS: Update defconfigs after previous patch.
MIPS: Push ARCH_MIGHT_HAVE_PC_SERIO down to platform level
MIPS: Push ARCH_MIGHT_HAVE_PC_PARPORT down to platform level
MIPS: SMP-CPS: Remove duplicate assignment of core in play_dead
MIPS: Generic: Support GIC in EIC mode
MIPS: generic: Fix Makefile alignment
MIPS: generic: Fix ranchu_of_match[] termination
MIPS: generic: Fix machine compatible matching
MIPS: Loongson fix name confict - MEM_RESERVED
MIPS: bcm47xx: enable ZBOOT support
MIPS: Fix trailing semicolon
MIPS: Watch: Avoid duplication of bits in mips_read_watch_registers
MIPS: Watch: Avoid duplication of bits in mips_install_watch_registers.
MIPS: MSA: Update helpers to use new asm macros
MIPS: XPA: Standardise readx/writex accessors
MIPS: XPA: Allow use of $0 (zero) to MTHC0
MIPS: XPA: Use XPA instructions in assembly
MIPS: VZ: Pass GC0 register names in $n format
MIPS: VZ: Update helpers to use new asm macros
...
77 files changed, 1649 insertions, 553 deletions
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index b1fa64a1d4d0..ae850d6c0ad3 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -125,6 +125,7 @@ focaltech FocalTech Systems Co.,Ltd friendlyarm Guangzhou FriendlyARM Computer Tech Co., Ltd fsl Freescale Semiconductor fujitsu Fujitsu Ltd. +gcw Game Consoles Worldwide ge General Electric Company geekbuying GeekBuying gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. diff --git a/MAINTAINERS b/MAINTAINERS index 7653656e64b2..ba3842a9e73e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9188,6 +9188,7 @@ S: Supported F: Documentation/devicetree/bindings/mips/ F: Documentation/mips/ F: arch/mips/ +F: drivers/platform/mips/ MIPS BOSTON DEVELOPMENT BOARD M: Paul Burton <paul.burton@mips.com> @@ -9215,6 +9216,25 @@ F: arch/mips/include/asm/mach-loongson32/ F: drivers/*/*loongson1* F: drivers/*/*/*loongson1* +MIPS/LOONGSON2 ARCHITECTURE +M: Jiaxun Yang <jiaxun.yang@flygoat.com> +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/loongson64/*{2e/2f}* +F: arch/mips/include/asm/mach-loongson64/ +F: drivers/*/*loongson2* +F: drivers/*/*/*loongson2* + +MIPS/LOONGSON3 ARCHITECTURE +M: Huacai Chen <chenhc@lemote.com> +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/loongson64/ +F: arch/mips/include/asm/mach-loongson64/ +F: drivers/platform/mips/cpu_hwmon.c +F: drivers/*/*loongson3* +F: drivers/*/*/*loongson3* + MIPS RINT INSTRUCTION EMULATION M: Aleksandar Markovic <aleksandar.markovic@mips.com> L: linux-mips@linux-mips.org @@ -11586,6 +11606,13 @@ S: Maintained F: Documentation/blockdev/ramdisk.txt F: drivers/block/brd.c +RANCHU VIRTUAL BOARD FOR MIPS +M: Miodrag Dinic <miodrag.dinic@mips.com> +L: linux-mips@linux-mips.org +S: Supported +F: arch/mips/generic/board-ranchu.c +F: arch/mips/configs/generic/board-ranchu.config + RANDOM NUMBER DRIVER M: "Theodore Ts'o" <tytso@mit.edu> S: Maintained diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index ab98569994f0..449397c60b56 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -7,8 +7,6 @@ config MIPS select ARCH_DISCARD_MEMBLOCK select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST - select ARCH_MIGHT_HAVE_PC_PARPORT - select ARCH_MIGHT_HAVE_PC_SERIO select ARCH_SUPPORTS_UPROBES select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF if 64BIT @@ -119,12 +117,12 @@ config MIPS_GENERIC select SYS_SUPPORTS_MULTITHREADING select SYS_SUPPORTS_RELOCATABLE select SYS_SUPPORTS_SMARTMIPS - select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN - select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN - select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN - select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN - select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN - select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN + select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN select USE_OF help Select this to build a kernel which aims to support multiple boards, @@ -253,6 +251,7 @@ config BCM47XX select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_ZBOOT select SYS_HAS_EARLY_PRINTK select USE_GENERIC_EARLY_PRINTK_8250 select GPIOLIB @@ -341,6 +340,8 @@ config MACH_DECSTATION config MACH_JAZZ bool "Jazz family of machines" + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO select FW_ARC select FW_ARC32 select ARCH_MAY_HAVE_PC_FDC @@ -476,6 +477,8 @@ config MACH_PISTACHIO config MIPS_MALTA bool "MIPS Malta board" select ARCH_MAY_HAVE_PC_FDC + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF32 select BOOT_RAW select BUILTIN_DTB @@ -613,6 +616,7 @@ config SGI_IP22 bool "SGI IP22 (Indy/Indigo2)" select FW_ARC select FW_ARC32 + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF32 select CEVT_R4K select CSRC_R4K @@ -675,6 +679,7 @@ config SGI_IP28 bool "SGI IP28 (Indigo2 R10k)" select FW_ARC select FW_ARC64 + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF64 select CEVT_R4K select CSRC_R4K @@ -824,6 +829,8 @@ config SNI_RM select FW_ARC32 if CPU_LITTLE_ENDIAN select FW_SNIPROM if CPU_BIG_ENDIAN select ARCH_MAY_HAVE_PC_FDC + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF32 select CEVT_R4K select CSRC_R4K diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9f6a26d72f9f..d1ca839c3981 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -216,6 +216,12 @@ cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA endif toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt) cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT +# For -mmicromips, use -Wa,-fatal-warnings to catch unsupported -mxpa which +# only warns +xpa-cflags-y := $(mips-cflags) +xpa-cflags-$(micromips-ase) += -mmicromips -Wa$(comma)-fatal-warnings +toolchain-xpa := $(call cc-option-yn,$(xpa-cflags-y) -mxpa) +cflags-$(toolchain-xpa) += -DTOOLCHAIN_SUPPORTS_XPA # # Firmware support @@ -228,7 +234,7 @@ libs-y += arch/mips/fw/lib/ # # Kernel compression # -ifdef SYS_SUPPORTS_ZBOOT +ifdef CONFIG_SYS_SUPPORTS_ZBOOT COMPRESSION_FNAME = vmlinuz else COMPRESSION_FNAME = vmlinux diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform index 874b7ca4cd11..70783b75fd9d 100644 --- a/arch/mips/bcm47xx/Platform +++ b/arch/mips/bcm47xx/Platform @@ -5,3 +5,4 @@ platform-$(CONFIG_BCM47XX) += bcm47xx/ cflags-$(CONFIG_BCM47XX) += \ -I$(srctree)/arch/mips/include/asm/mach-bcm47xx load-$(CONFIG_BCM47XX) := 0xffffffff80001000 +zload-$(CONFIG_BCM47XX) += 0xffffffff80400000 diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index c675eece389a..adce180f3ee4 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -133,4 +133,8 @@ vmlinuz.srec: vmlinuz uzImage.bin: vmlinuz.bin FORCE $(call if_changed,uimage,none) -clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec} +clean-files += $(objtree)/vmlinuz +clean-files += $(objtree)/vmlinuz.32 +clean-files += $(objtree)/vmlinuz.ecoff +clean-files += $(objtree)/vmlinuz.bin +clean-files += $(objtree)/vmlinuz.srec diff --git a/arch/mips/boot/dts/ingenic/Makefile b/arch/mips/boot/dts/ingenic/Makefile index 6a31759839b4..5b1361a89e02 100644 --- a/arch/mips/boot/dts/ingenic/Makefile +++ b/arch/mips/boot/dts/ingenic/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_JZ4740_QI_LB60) += qi_lb60.dtb +dtb-$(CONFIG_JZ4770_GCW0) += gcw0.dtb dtb-$(CONFIG_JZ4780_CI20) += ci20.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/ingenic/gcw0.dts b/arch/mips/boot/dts/ingenic/gcw0.dts new file mode 100644 index 000000000000..35f0291e8d38 --- /dev/null +++ b/arch/mips/boot/dts/ingenic/gcw0.dts @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "jz4770.dtsi" + +/ { + compatible = "gcw,zero", "ingenic,jz4770"; + model = "GCW Zero"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial2:57600n8"; + }; + + board { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + otg_phy: otg-phy { + compatible = "usb-nop-xceiv"; + clocks = <&cgu JZ4770_CLK_OTG_PHY>; + clock-names = "main_clk"; + }; + }; +}; + +&ext { + clock-frequency = <12000000>; +}; + +&uart2 { + status = "okay"; +}; + +&cgu { + /* Put high-speed peripherals under PLL1, such that we can change the + * PLL0 frequency on demand without having to suspend peripherals. + * We use a rate of 432 MHz, which is the least common multiple of + * 27 MHz (required by TV encoder) and 48 MHz (required by USB host). + */ + assigned-clocks = + <&cgu JZ4770_CLK_PLL1>, + <&cgu JZ4770_CLK_UHC>; + assigned-clock-parents = + <0>, + <&cgu JZ4770_CLK_PLL1>; + assigned-clock-rates = + <432000000>; +}; + +&uhc { + /* The WiFi module is connected to the UHC. */ + status = "okay"; +}; diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi new file mode 100644 index 000000000000..7c2804f3f5f1 --- /dev/null +++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <dt-bindings/clock/jz4770-cgu.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ingenic,jz4770"; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + intc: interrupt-controller@10001000 { + compatible = "ingenic,jz4770-intc"; + reg = <0x10001000 0x40>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + ext: ext { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + osc32k: osc32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + cgu: jz4770-cgu@10000000 { + compatible = "ingenic,jz4770-cgu"; + reg = <0x10000000 0x100>; + + clocks = <&ext>, <&osc32k>; + clock-names = "ext", "osc32k"; + + #clock-cells = <1>; + }; + + pinctrl: pin-controller@10010000 { + compatible = "ingenic,jz4770-pinctrl"; + reg = <0x10010000 0x600>; + + #address-cells = <1>; + #size-cells = <0>; + + gpa: gpio@0 { + compatible = "ingenic,jz4770-gpio"; + reg = <0>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <17>; + }; + + gpb: gpio@1 { + compatible = "ingenic,jz4770-gpio"; + reg = <1>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 32 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <16>; + }; + + gpc: gpio@2 { + compatible = "ingenic,jz4770-gpio"; + reg = <2>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 64 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <15>; + }; + + gpd: gpio@3 { + compatible = "ingenic,jz4770-gpio"; + reg = <3>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 96 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <14>; + }; + + gpe: gpio@4 { + compatible = "ingenic,jz4770-gpio"; + reg = <4>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 128 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <13>; + }; + + gpf: gpio@5 { + compatible = "ingenic,jz4770-gpio"; + reg = <5>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 160 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <12>; + }; + }; + + uart0: serial@10030000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10030000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART0>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <5>; + + status = "disabled"; + }; + + uart1: serial@10031000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10031000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART1>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <4>; + + status = "disabled"; + }; + + uart2: serial@10032000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10032000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART2>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <3>; + + status = "disabled"; + }; + + uart3: serial@10033000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10033000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART3>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <2>; + + status = "disabled"; + }; + + uhc: uhc@13430000 { + compatible = "generic-ohci"; + reg = <0x13430000 0x1000>; + + clocks = <&cgu JZ4770_CLK_UHC>, <&cgu JZ4770_CLK_UHC_PHY>; + assigned-clocks = <&cgu JZ4770_CLK_UHC>; + assigned-clock-rates = <48000000>; + + interrupt-parent = <&intc>; + interrupts = <20>; + + status = "disabled"; + }; +}; diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index a55009edbb29..5e73fe755be6 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -153,7 +153,6 @@ CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y # CONFIG_INPUT is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_RAW=m # CONFIG_VT is not set CONFIG_SERIAL_NONSTANDARD=y diff --git a/arch/mips/configs/gcw0_defconfig b/arch/mips/configs/gcw0_defconfig new file mode 100644 index 000000000000..99ac1fa3b35f --- /dev/null +++ b/arch/mips/configs/gcw0_defconfig @@ -0,0 +1,27 @@ +CONFIG_MACH_INGENIC=y +CONFIG_JZ4770_GCW0=y +CONFIG_HIGHMEM=y +# CONFIG_BOUNCE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_SECCOMP is not set +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_EMBEDDED=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_INGENIC=y +CONFIG_USB=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_TMPFS=y diff --git a/arch/mips/configs/generic/board-ranchu.config b/arch/mips/configs/generic/board-ranchu.config new file mode 100644 index 000000000000..fee9ad4c5598 --- /dev/null +++ b/arch/mips/configs/generic/board-ranchu.config @@ -0,0 +1,30 @@ +CONFIG_VIRT_BOARD_RANCHU=y + +CONFIG_BATTERY_GOLDFISH=y +CONFIG_FB=y +CONFIG_FB_GOLDFISH=y +CONFIG_GOLDFISH=y +CONFIG_STAGING=y +CONFIG_GOLDFISH_AUDIO=y +CONFIG_GOLDFISH_PIC=y +CONFIG_GOLDFISH_PIPE=y +CONFIG_GOLDFISH_TTY=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GOLDFISH=y + +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_GOLDFISH_EVENTS=y + +CONFIG_MAGIC_SYSRQ=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y + +CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +CONFIG_NETDEVICES=y +CONFIG_VIRTIO_NET=y diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index a0d593248668..91a9c13e2c82 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -252,7 +252,6 @@ CONFIG_RT2800PCI=m CONFIG_WL12XX=m CONFIG_WL1251=m # CONFIG_INPUT is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_LIBPS2=m CONFIG_SERIO_RAW=m CONFIG_SERIO_ALTERA_PS2=m diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 1e26e58b9dc3..ebff297328ae 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -75,7 +75,6 @@ CONFIG_DE2104X=m CONFIG_TULIP=m CONFIG_TULIP_MMIO=y CONFIG_INPUT_EVDEV=m -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_MACEPS2=y CONFIG_SERIO_RAW=y # CONFIG_CONSOLE_TRANSLATIONS is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 396408404487..df8a9a15ca83 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -312,9 +312,8 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index 5691673a3327..14df9ef15d40 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -324,9 +324,7 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index e9cadb37d684..25092e344574 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -326,9 +326,7 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig index 77145ecaa23b..210bf609f785 100644 --- a/arch/mips/configs/malta_qemu_32r6_defconfig +++ b/arch/mips/configs/malta_qemu_32r6_defconfig @@ -126,6 +126,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig index cc2687cfdc13..e5934aa98397 100644 --- a/arch/mips/configs/maltaaprp_defconfig +++ b/arch/mips/configs/maltaaprp_defconfig @@ -126,6 +126,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_TOSHIBA is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig index d8c8f5fb8918..cb2ca11c1789 100644 --- a/arch/mips/configs/maltasmvp_defconfig +++ b/arch/mips/configs/maltasmvp_defconfig @@ -127,6 +127,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig index 04827bc9f87f..be29fcec69fc 100644 --- a/arch/mips/configs/maltasmvp_eva_defconfig +++ b/arch/mips/configs/maltasmvp_eva_defconfig @@ -130,6 +130,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig index 7ea7c0ba2666..40462d4c90a0 100644 --- a/arch/mips/configs/maltaup_defconfig +++ b/arch/mips/configs/maltaup_defconfig @@ -125,6 +125,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_TOSHIBA is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig index 2942610e4082..4e50176cb3df 100644 --- a/arch/mips/configs/maltaup_xpa_defconfig +++ b/arch/mips/configs/maltaup_xpa_defconfig @@ -321,9 +321,8 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig index 7357248b3d7a..e8e1dd8e0e99 100644 --- a/arch/mips/configs/nlm_xlp_defconfig +++ b/arch/mips/configs/nlm_xlp_defconfig @@ -399,7 +399,6 @@ CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_RAW=m diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig index 1e18fd7de209..c4477a4d40c1 100644 --- a/arch/mips/configs/nlm_xlr_defconfig +++ b/arch/mips/configs/nlm_xlr_defconfig @@ -332,7 +332,6 @@ CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_RAW=m diff --git a/arch/mips/configs/pnx8335_stb225_defconfig b/arch/mips/configs/pnx8335_stb225_defconfig index 81b5eb89446c..e73cdb08fc6e 100644 --- a/arch/mips/configs/pnx8335_stb225_defconfig +++ b/arch/mips/configs/pnx8335_stb225_defconfig @@ -49,7 +49,6 @@ CONFIG_INPUT_EVDEV=m CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set # CONFIG_VT_CONSOLE is not set CONFIG_SERIAL_PNX8XXX=y CONFIG_SERIAL_PNX8XXX_CONSOLE=y diff --git a/arch/mips/configs/sb1250_swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig index c724bdd6a7e6..1edd8430ad61 100644 --- a/arch/mips/configs/sb1250_swarm_defconfig +++ b/arch/mips/configs/sb1250_swarm_defconfig @@ -65,7 +65,6 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SB1250_MAC=y # CONFIG_INPUT is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_RAW=m # CONFIG_VT is not set # CONFIG_HW_RANDOM is not set diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index 52e0286a1612..2ff3b17bfab1 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -49,4 +49,14 @@ config FIT_IMAGE_FDT_XILFPGA Enable this to include the FDT for the MIPSfpga platform from Imagination Technologies in the FIT kernel image. +config VIRT_BOARD_RANCHU + bool "Support Ranchu platform for Android emulator" + help + This enables support for the platform used by Android emulator. + + Ranchu platform consists of a set of virtual devices. This platform + enables emulation of variety of virtual configurations while using + Android emulator. Android emulator is based on Qemu, and contains + the support for the same set of virtual devices. + endif diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index 874967363dbb..5c31e0c4697d 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile @@ -15,3 +15,4 @@ obj-y += proc.o obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o obj-$(CONFIG_KEXEC) += kexec.o +obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o diff --git a/arch/mips/generic/board-ranchu.c b/arch/mips/generic/board-ranchu.c new file mode 100644 index 000000000000..59a8c18fa2cc --- /dev/null +++ b/arch/mips/generic/board-ranchu.c @@ -0,0 +1,93 @@ +/* + * Support code for virtual Ranchu board for MIPS. + * + * Author: Miodrag Dinic <miodrag.dinic@mips.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/of_address.h> +#include <linux/types.h> + +#include <asm/machine.h> +#include <asm/mipsregs.h> +#include <asm/time.h> + +#define GOLDFISH_TIMER_LOW 0x00 +#define GOLDFISH_TIMER_HIGH 0x04 + +static __init u64 read_rtc_time(void __iomem *base) +{ + u32 time_low; + u32 time_high; + + /* + * Reading the low address latches the high value + * as well so there is no fear that we may read + * inaccurate high value. + */ + time_low = readl(base + GOLDFISH_TIMER_LOW); + time_high = readl(base + GOLDFISH_TIMER_HIGH); + + return ((u64)time_high << 32) | time_low; +} + +static __init unsigned int ranchu_measure_hpt_freq(void) +{ + u64 rtc_start, rtc_current, rtc_delta; + unsigned int start, count; + struct device_node *np; + void __iomem *rtc_base; + + np = of_find_compatible_node(NULL, NULL, "google,goldfish-rtc"); + if (!np) + panic("%s(): Failed to find 'google,goldfish-rtc' dt node!", + __func__); + + rtc_base = of_iomap(np, 0); + if (!rtc_base) + panic("%s(): Failed to ioremap Goldfish RTC base!", __func__); + + /* + * Poll the nanosecond resolution RTC for one + * second to calibrate the CPU frequency. + */ + rtc_start = read_rtc_time(rtc_base); + start = read_c0_count(); + + do { + rtc_current = read_rtc_time(rtc_base); + rtc_delta = rtc_current - rtc_start; + } while (rtc_delta < NSEC_PER_SEC); + + count = read_c0_count() - start; + + /* + * Make sure the frequency will be a round number. + * Without this correction, the returned value may vary + * between subsequent emulation executions. + * + * TODO: Set this value using device tree. + */ + count += 5000; + count -= count % 10000; + + iounmap(rtc_base); + + return count; +} + +static const struct of_device_id ranchu_of_match[] __initconst = { + { + .compatible = "mti,ranchu", + }, + {} +}; + +MIPS_MACHINE(ranchu) = { + .matches = ranchu_of_match, + .measure_hpt_freq = ranchu_measure_hpt_freq, +}; diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c index 394f8161e462..cb7fdaeef426 100644 --- a/arch/mips/generic/irq.c +++ b/arch/mips/generic/irq.c @@ -22,10 +22,10 @@ int get_c0_fdc_int(void) { int mips_cpu_fdc_irq; - if (cpu_has_veic) - panic("Unimplemented!"); - else if (mips_gic_present()) + if (mips_gic_present()) mips_cpu_fdc_irq = gic_get_c0_fdc_int(); + else if (cpu_has_veic) + panic("Unimplemented!"); else if (cp0_fdc_irq >= 0) mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; else @@ -38,10 +38,10 @@ int get_c0_perfcount_int(void) { int mips_cpu_perf_irq; - if (cpu_has_veic) - panic("Unimplemented!"); - else if (mips_gic_present()) + if (mips_gic_present()) mips_cpu_perf_irq = gic_get_c0_perfcount_int(); + else if (cpu_has_veic) + panic("Unimplemented!"); else if (cp0_perfcount_irq >= 0) mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; else @@ -54,10 +54,10 @@ unsigned int get_c0_compare_int(void) { int mips_cpu_timer_irq; - if (cpu_has_veic) - panic("Unimplemented!"); - else if (mips_gic_present()) + if (mips_gic_present()) mips_cpu_timer_irq = gic_get_c0_compare_int(); + else if (cpu_has_veic) + panic("Unimplemented!"); else mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index e26a093bb17a..a301a8f4bc66 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -79,6 +79,8 @@ enum loongson_machine_type { */ #define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */ #define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */ +#define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */ +#define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */ extern char *system_type; const char *get_system_type(void); diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h index 77cad232a1c6..e8161e4dfde7 100644 --- a/arch/mips/include/asm/checksum.h +++ b/arch/mips/include/asm/checksum.h @@ -110,7 +110,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst, */ static inline __sum16 csum_fold(__wsum csum) { - u32 sum = (__force u32)csum;; + u32 sum = (__force u32)csum; sum += (sum << 16); csum = (sum < csum); diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h index 4f69f08717f6..8c286bedff3e 100644 --- a/arch/mips/include/asm/mach-loongson64/boot_param.h +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h @@ -4,7 +4,7 @@ #define SYSTEM_RAM_LOW 1 #define SYSTEM_RAM_HIGH 2 -#define MEM_RESERVED 3 +#define SYSTEM_RAM_RESERVED 3 #define PCI_IO 4 #define PCI_MEM 5 #define LOONGSON_CFG_REG 6 diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h index e0d9b373d415..f83879dadd1e 100644 --- a/arch/mips/include/asm/machine.h +++ b/arch/mips/include/asm/machine.h @@ -52,7 +52,7 @@ mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt) if (!mach->matches) return NULL; - for (match = mach->matches; match->compatible; match++) { + for (match = mach->matches; match->compatible[0]; match++) { if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0) return match; } diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 6b1f1ad0542c..858752dac337 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1181,6 +1181,89 @@ static inline int mm_insn_16bit(u16 insn) #endif /* + * parse_r var, r - Helper assembler macro for parsing register names. + * + * This converts the register name in $n form provided in \r to the + * corresponding register number, which is assigned to the variable \var. It is + * needed to allow explicit encoding of instructions in inline assembly where + * registers are chosen by the compiler in $n form, allowing us to avoid using + * fixed register numbers. + * + * It also allows newer instructions (not implemented by the assembler) to be + * transparently implemented using assembler macros, instead of needing separate + * cases depending on toolchain support. + * + * Simple usage example: + * __asm__ __volatile__("parse_r __rt, %0\n\t" + * ".insn\n\t" + * "# di %0\n\t" + * ".word (0x41606000 | (__rt << 16))" + * : "=r" (status); + */ + +/* Match an individual register number and assign to \var */ +#define _IFC_REG(n) \ + ".ifc \\r, $" #n "\n\t" \ + "\\var = " #n "\n\t" \ + ".endif\n\t" + +__asm__(".macro parse_r var r\n\t" + "\\var = -1\n\t" + _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) + _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) + _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) + _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) + _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) + _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) + _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) + _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) + ".iflt \\var\n\t" + ".error \"Unable to parse register name \\r\"\n\t" + ".endif\n\t" + ".endm"); + +#undef _IFC_REG + +/* + * C macros for generating assembler macros for common instruction formats. + * + * The names of the operands can be chosen by the caller, and the encoding of + * register operand \<Rn> is assigned to __<Rn> where it can be accessed from + * the ENC encodings. + */ + +/* Instructions with no operands */ +#define _ASM_MACRO_0(OP, ENC) \ + __asm__(".macro " #OP "\n\t" \ + ENC \ + ".endm") + +/* Instructions with 2 register operands */ +#define _ASM_MACRO_2R(OP, R1, R2, ENC) \ + __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \ + "parse_r __" #R1 ", \\" #R1 "\n\t" \ + "parse_r __" #R2 ", \\" #R2 "\n\t" \ + ENC \ + ".endm") + +/* Instructions with 3 register operands */ +#define _ASM_MACRO_3R(OP, R1, R2, R3, ENC) \ + __asm__(".macro " #OP " " #R1 ", " #R2 ", " #R3 "\n\t" \ + "parse_r __" #R1 ", \\" #R1 "\n\t" \ + "parse_r __" #R2 ", \\" #R2 "\n\t" \ + "parse_r __" #R3 ", \\" #R3 "\n\t" \ + ENC \ + ".endm") + +/* Instructions with 2 register operands and 1 optional select operand */ +#define _ASM_MACRO_2R_1S(OP, R1, R2, SEL3, ENC) \ + __asm__(".macro " #OP " " #R1 ", " #R2 ", " #SEL3 " = 0\n\t" \ + "parse_r __" #R1 ", \\" #R1 "\n\t" \ + "parse_r __" #R2 ", \\" #R2 "\n\t" \ + ENC \ + ".endm") + +/* * TLB Invalidate Flush */ static inline void tlbinvf(void) @@ -1245,14 +1328,14 @@ do { \ * Macros to access the system control coprocessor */ -#define __read_32bit_c0_register(source, sel) \ +#define ___read_32bit_c0_register(source, sel, vol) \ ({ unsigned int __res; \ if (sel == 0) \ - __asm__ __volatile__( \ + __asm__ vol( \ "mfc0\t%0, " #source "\n\t" \ : "=r" (__res)); \ else \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips32\n\t" \ "mfc0\t%0, " #source ", " #sel "\n\t" \ ".set\tmips0\n\t" \ @@ -1260,18 +1343,18 @@ do { \ __res; \ }) -#define __read_64bit_c0_register(source, sel) \ +#define ___read_64bit_c0_register(source, sel, vol) \ ({ unsigned long long __res; \ if (sizeof(unsigned long) == 4) \ - __res = __read_64bit_c0_split(source, sel); \ + __res = __read_64bit_c0_split(source, sel, vol); \ else if (sel == 0) \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips3\n\t" \ "dmfc0\t%0, " #source "\n\t" \ ".set\tmips0" \ : "=r" (__res)); \ else \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips64\n\t" \ "dmfc0\t%0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ @@ -1279,6 +1362,18 @@ do { \ __res; \ }) +#define __read_32bit_c0_register(source, sel) \ + ___read_32bit_c0_register(source, sel, __volatile__) + +#define __read_const_32bit_c0_register(source, sel) \ + ___read_32bit_c0_register(source, sel,) + +#define __read_64bit_c0_register(source, sel) \ + ___read_64bit_c0_register(source, sel, __volatile__) + +#define __read_const_64bit_c0_register(source, sel) \ + ___read_64bit_c0_register(source, sel,) + #define __write_32bit_c0_register(register, sel, value) \ do { \ if (sel == 0) \ @@ -1316,6 +1411,11 @@ do { \ (unsigned long) __read_32bit_c0_register(reg, sel) : \ (unsigned long) __read_64bit_c0_register(reg, sel)) +#define __read_const_ulong_c0_register(reg, sel) \ + ((sizeof(unsigned long) == 4) ? \ + (unsigned long) __read_const_32bit_c0_register(reg, sel) : \ + (unsigned long) __read_const_64bit_c0_register(reg, sel)) + #define __write_ulong_c0_register(reg, sel, val) \ do { \ if (sizeof(unsigned long) == 4) \ @@ -1346,14 +1446,14 @@ do { \ * These versions are only needed for systems with more than 38 bits of * physical address space running the 32-bit kernel. That's none atm :-) */ -#define __read_64bit_c0_split(source, sel) \ +#define __read_64bit_c0_split(source, sel, vol) \ ({ \ unsigned long long __val; \ unsigned long __flags; \ \ local_irq_save(__flags); \ if (sel == 0) \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips64\n\t" \ "dmfc0\t%L0, " #source "\n\t" \ "dsra\t%M0, %L0, 32\n\t" \ @@ -1361,7 +1461,7 @@ do { \ ".set\tmips0" \ : "=r" (__val)); \ else \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips64\n\t" \ "dmfc0\t%L0, " #source ", " #sel "\n\t" \ "dsra\t%M0, %L0, 32\n\t" \ @@ -1404,37 +1504,43 @@ do { \ local_irq_restore(__flags); \ } while (0) -#define __readx_32bit_c0_register(source) \ +#ifndef TOOLCHAIN_SUPPORTS_XPA +_ASM_MACRO_2R_1S(mfhc0, rt, rs, sel, + _ASM_INSN_IF_MIPS(0x40400000 | __rt << 16 | __rs << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000000f4 | __rt << 21 | __rs << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(mthc0, rt, rd, sel, + _ASM_INSN_IF_MIPS(0x40c00000 | __rt << 16 | __rd << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000002f4 | __rt << 21 | __rd << 16 | \\sel << 11)); +#define _ASM_SET_XPA "" +#else /* !TOOLCHAIN_SUPPORTS_XPA */ +#define _ASM_SET_XPA ".set\txpa\n\t" +#endif + +#define __readx_32bit_c0_register(source, sel) \ ({ \ unsigned int __res; \ \ __asm__ __volatile__( \ " .set push \n" \ - " .set noat \n" \ " .set mips32r2 \n" \ - " # mfhc0 $1, %1 \n" \ - _ASM_INSN_IF_MIPS(0x40410000 | ((%1 & 0x1f) << 11)) \ - _ASM_INSN32_IF_MM(0x002000f4 | ((%1 & 0x1f) << 16)) \ - " move %0, $1 \n" \ + _ASM_SET_XPA \ + " mfhc0 %0, " #source ", %1 \n" \ " .set pop \n" \ : "=r" (__res) \ - : "i" (source)); \ + : "i" (sel)); \ __res; \ }) -#define __writex_32bit_c0_register(register, value) \ +#define __writex_32bit_c0_register(register, sel, value) \ do { \ __asm__ __volatile__( \ " .set push \n" \ - " .set noat \n" \ " .set mips32r2 \n" \ - " move $1, %0 \n" \ - " # mthc0 $1, %1 \n" \ - _ASM_INSN_IF_MIPS(0x40c10000 | ((%1 & 0x1f) << 11)) \ - _ASM_INSN32_IF_MM(0x002002f4 | ((%1 & 0x1f) << 16)) \ + _ASM_SET_XPA \ + " mthc0 %z0, " #register ", %1 \n" \ " .set pop \n" \ : \ - : "r" (value), "i" (register)); \ + : "Jr" (value), "i" (sel)); \ } while (0) #define read_c0_index() __read_32bit_c0_register($0, 0) @@ -1446,14 +1552,14 @@ do { \ #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) -#define readx_c0_entrylo0() __readx_32bit_c0_register(2) -#define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val) +#define readx_c0_entrylo0() __readx_32bit_c0_register($2, 0) +#define writex_c0_entrylo0(val) __writex_32bit_c0_register($2, 0, val) #define read_c0_entrylo1() __read_ulong_c0_register($3, 0) #define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) -#define readx_c0_entrylo1() __readx_32bit_c0_register(3) -#define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val) +#define readx_c0_entrylo1() __readx_32bit_c0_register($3, 0) +#define writex_c0_entrylo1(val) __writex_32bit_c0_register($3, 0, val) #define read_c0_conf() __read_32bit_c0_register($3, 0) #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) @@ -1541,7 +1647,7 @@ do { \ #define read_c0_epc() __read_ulong_c0_register($14, 0) #define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) -#define read_c0_prid() __read_32bit_c0_register($15, 0) +#define read_c0_prid() __read_const_32bit_c0_register($15, 0) #define read_c0_cmgcrbase() __read_ulong_c0_register($15, 3) @@ -1830,18 +1936,44 @@ do { \ * Macros to access the guest system control coprocessor */ -#ifdef TOOLCHAIN_SUPPORTS_VIRT +#ifndef TOOLCHAIN_SUPPORTS_VIRT +_ASM_MACRO_2R_1S(mfgc0, rt, rs, sel, + _ASM_INSN_IF_MIPS(0x40600000 | __rt << 16 | __rs << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000004fc | __rt << 21 | __rs << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(dmfgc0, rt, rs, sel, + _ASM_INSN_IF_MIPS(0x40600100 | __rt << 16 | __rs << 11 | \\sel) + _ASM_INSN32_IF_MM(0x580004fc | __rt << 21 | __rs << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(mtgc0, rt, rd, sel, + _ASM_INSN_IF_MIPS(0x40600200 | __rt << 16 | __rd << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000006fc | __rt << 21 | __rd << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(dmtgc0, rt, rd, sel, + _ASM_INSN_IF_MIPS(0x40600300 | __rt << 16 | __rd << 11 | \\sel) + _ASM_INSN32_IF_MM(0x580006fc | __rt << 21 | __rd << 16 | \\sel << 11)); +_ASM_MACRO_0(tlbgp, _ASM_INSN_IF_MIPS(0x42000010) + _ASM_INSN32_IF_MM(0x0000017c)); +_ASM_MACRO_0(tlbgr, _ASM_INSN_IF_MIPS(0x42000009) + _ASM_INSN32_IF_MM(0x0000117c)); +_ASM_MACRO_0(tlbgwi, _ASM_INSN_IF_MIPS(0x4200000a) + _ASM_INSN32_IF_MM(0x0000217c)); +_ASM_MACRO_0(tlbgwr, _ASM_INSN_IF_MIPS(0x4200000e) + _ASM_INSN32_IF_MM(0x0000317c)); +_ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c) + _ASM_INSN32_IF_MM(0x0000517c)); +#define _ASM_SET_VIRT "" +#else /* !TOOLCHAIN_SUPPORTS_VIRT */ +#define _ASM_SET_VIRT ".set\tvirt\n\t" +#endif #define __read_32bit_gc0_register(source, sel) \ ({ int __res; \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips32r2\n\t" \ - ".set\tvirt\n\t" \ - "mfgc0\t%0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "mfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ : "=r" (__res) \ - : "i" (source), "i" (sel)); \ + : "i" (sel)); \ __res; \ }) @@ -1850,11 +1982,11 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips64r2\n\t" \ - ".set\tvirt\n\t" \ - "dmfgc0\t%0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "dmfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ : "=r" (__res) \ - : "i" (source), "i" (sel)); \ + : "i" (sel)); \ __res; \ }) @@ -1863,11 +1995,11 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips32r2\n\t" \ - ".set\tvirt\n\t" \ - "mtgc0\t%z0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "mtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ : : "Jr" ((unsigned int)(value)), \ - "i" (register), "i" (sel)); \ + "i" (sel)); \ } while (0) #define __write_64bit_gc0_register(register, sel, value) \ @@ -1875,75 +2007,13 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips64r2\n\t" \ - ".set\tvirt\n\t" \ - "dmtgc0\t%z0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "dmtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ : : "Jr" (value), \ - "i" (register), "i" (sel)); \ + "i" (sel)); \ } while (0) -#else /* TOOLCHAIN_SUPPORTS_VIRT */ - -#define __read_32bit_gc0_register(source, sel) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "# mfgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610000 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x002004fc | %1 << 16 | %2 << 11) \ - "move\t%0, $1\n\t" \ - ".set\tpop" \ - : "=r" (__res) \ - : "i" (source), "i" (sel)); \ - __res; \ -}) - -#define __read_64bit_gc0_register(source, sel) \ -({ unsigned long long __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "# dmfgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610100 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x582004fc | %1 << 16 | %2 << 11) \ - "move\t%0, $1\n\t" \ - ".set\tpop" \ - : "=r" (__res) \ - : "i" (source), "i" (sel)); \ - __res; \ -}) - -#define __write_32bit_gc0_register(register, sel, value) \ -do { \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "move\t$1, %z0\n\t" \ - "# mtgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610200 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x002006fc | %1 << 16 | %2 << 11) \ - ".set\tpop" \ - : : "Jr" ((unsigned int)(value)), \ - "i" (register), "i" (sel)); \ -} while (0) - -#define __write_64bit_gc0_register(register, sel, value) \ -do { \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "move\t$1, %z0\n\t" \ - "# dmtgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610300 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x582006fc | %1 << 16 | %2 << 11) \ - ".set\tpop" \ - : : "Jr" (value), \ - "i" (register), "i" (sel)); \ -} while (0) - -#endif /* !TOOLCHAIN_SUPPORTS_VIRT */ - #define __read_ulong_gc0_register(reg, sel) \ ((sizeof(unsigned long) == 4) ? \ (unsigned long) __read_32bit_gc0_register(reg, sel) : \ @@ -1957,207 +2027,207 @@ do { \ __write_64bit_gc0_register(reg, sel, val); \ } while (0) -#define read_gc0_index() __read_32bit_gc0_register(0, 0) -#define write_gc0_index(val) __write_32bit_gc0_register(0, 0, val) +#define read_gc0_index() __read_32bit_gc0_register($0, 0) +#define write_gc0_index(val) __write_32bit_gc0_register($0, 0, val) -#define read_gc0_entrylo0() __read_ulong_gc0_register(2, 0) -#define write_gc0_entrylo0(val) __write_ulong_gc0_register(2, 0, val) +#define read_gc0_entrylo0() __read_ulong_gc0_register($2, 0) +#define write_gc0_entrylo0(val) __write_ulong_gc0_register($2, 0, val) -#define read_gc0_entrylo1() __read_ulong_gc0_register(3, 0) -#define write_gc0_entrylo1(val) __write_ulong_gc0_register(3, 0, val) +#define read_gc0_entrylo1() __read_ulong_gc0_register($3, 0) +#define write_gc0_entrylo1(val) __write_ulong_gc0_register($3, 0, val) -#define read_gc0_context() __read_ulong_gc0_register(4, 0) -#define write_gc0_context(val) __write_ulong_gc0_register(4, 0, val) +#define read_gc0_context() __read_ulong_gc0_register($4, 0) +#define write_gc0_context(val) __write_ulong_gc0_register($4, 0, val) -#define read_gc0_contextconfig() __read_32bit_gc0_register(4, 1) -#define write_gc0_contextconfig(val) __write_32bit_gc0_register(4, 1, val) +#define read_gc0_contextconfig() __read_32bit_gc0_register($4, 1) +#define write_gc0_contextconfig(val) __write_32bit_gc0_register($4, 1, val) -#define read_gc0_userlocal() __read_ulong_gc0_register(4, 2) -#define write_gc0_userlocal(val) __write_ulong_gc0_register(4, 2, val) +#define read_gc0_userlocal() __read_ulong_gc0_register($4, 2) +#define write_gc0_userlocal(val) __write_ulong_gc0_register($4, 2, val) -#define read_gc0_xcontextconfig() __read_ulong_gc0_register(4, 3) -#define write_gc0_xcontextconfig(val) __write_ulong_gc0_register(4, 3, val) +#define read_gc0_xcontextconfig() __read_ulong_gc0_register($4, 3) +#define write_gc0_xcontextconfig(val) __write_ulong_gc0_register($4, 3, val) -#define read_gc0_pagemask() __read_32bit_gc0_register(5, 0) -#define write_gc0_pagemask(val) __write_32bit_gc0_register(5, 0, val) +#define read_gc0_pagemask() __read_32bit_gc0_register($5, 0) +#define write_gc0_pagemask(val) __write_32bit_gc0_register($5, 0, val) -#define read_gc0_pagegrain() __read_32bit_gc0_register(5, 1) -#define write_gc0_pagegrain(val) __write_32bit_gc0_register(5, 1, val) +#define read_gc0_pagegrain() __read_32bit_gc0_register($5, 1) +#define write_gc0_pagegrain(val) __write_32bit_gc0_register($5, 1, val) -#define read_gc0_segctl0() __read_ulong_gc0_register(5, 2) -#define write_gc0_segctl0(val) __write_ulong_gc0_register(5, 2, val) +#define read_gc0_segctl0() __read_ulong_gc0_register($5, 2) +#define write_gc0_segctl0(val) __write_ulong_gc0_register($5, 2, val) -#define read_gc0_segctl1() __read_ulong_gc0_register(5, 3) -#define write_gc0_segctl1(val) __write_ulong_gc0_register(5, 3, val) +#define read_gc0_segctl1() __read_ulong_gc0_register($5, 3) +#define write_gc0_segctl1(val) __write_ulong_gc0_register($5, 3, val) -#define read_gc0_segctl2() __read_ulong_gc0_register(5, 4) -#define write_gc0_segctl2(val) __write_ulong_gc0_register(5, 4, val) +#define read_gc0_segctl2() __read_ulong_gc0_register($5, 4) +#define write_gc0_segctl2(val) __write_ulong_gc0_register($5, 4, val) -#define read_gc0_pwbase() __read_ulong_gc0_register(5, 5) -#define write_gc0_pwbase(val) __write_ulong_gc0_register(5, 5, val) +#define read_gc0_pwbase() __read_ulong_gc0_register($5, 5) +#define write_gc0_pwbase(val) __write_ulong_gc0_register($5, 5, val) -#define read_gc0_pwfield() __read_ulong_gc0_register(5, 6) -#define write_gc0_pwfield(val) __write_ulong_gc0_register(5, 6, val) +#define read_gc0_pwfield() __read_ulong_gc0_register($5, 6) +#define write_gc0_pwfield(val) __write_ulong_gc0_register($5, 6, val) -#define read_gc0_pwsize() __read_ulong_gc0_register(5, 7) -#define write_gc0_pwsize(val) __write_ulong_gc0_register(5, 7, val) +#define read_gc0_pwsize() __read_ulong_gc0_register($5, 7) +#define write_gc0_pwsize(val) __write_ulong_gc0_register($5, 7, val) -#define read_gc0_wired() __read_32bit_gc0_register(6, 0) -#define write_gc0_wired(val) __write_32bit_gc0_register(6, 0, val) +#define read_gc0_wired() __read_32bit_gc0_register($6, 0) +#define write_gc0_wired(val) __write_32bit_gc0_register($6, 0, val) -#define read_gc0_pwctl() __read_32bit_gc0_register(6, 6) -#define write_gc0_pwctl(val) __write_32bit_gc0_register(6, 6, val) - -#define read_gc0_hwrena() __read_32bit_gc0_register(7, 0) -#define write_gc0_hwrena(val) __write_32bit_gc0_register(7, 0, val) - -#define read_gc0_badvaddr() __read_ulong_gc0_register(8, 0) -#define write_gc0_badvaddr(val) __write_ulong_gc0_register(8, 0, val) - -#define read_gc0_badinstr() __read_32bit_gc0_register(8, 1) -#define write_gc0_badinstr(val) __write_32bit_gc0_register(8, 1, val) - -#define read_gc0_badinstrp() __read_32bit_gc0_register(8, 2) -#define write_gc0_badinstrp(val) __write_32bit_gc0_register(8, 2, val) - -#define read_gc0_count() __read_32bit_gc0_register(9, 0) - -#define read_gc0_entryhi() __read_ulong_gc0_register(10, 0) -#define write_gc0_entryhi(val) __write_ulong_gc0_register(10, 0, val) - -#define read_gc0_compare() __read_32bit_gc0_register(11, 0) -#define write_gc0_compare(val) __write_32bit_gc0_register(11, 0, val) - -#define read_gc0_status() __read_32bit_gc0_register(12, 0) -#define write_gc0_status(val) __write_32bit_gc0_register(12, 0, val) - -#define read_gc0_intctl() __read_32bit_gc0_register(12, 1) -#define write_gc0_intctl(val) __write_32bit_gc0_register(12, 1, val) - -#define read_gc0_cause() __read_32bit_gc0_register(13, 0) -#define write_gc0_cause(val) __write_32bit_gc0_register(13, 0, val) - -#define read_gc0_epc() __read_ulong_gc0_register(14, 0) -#define write_gc0_epc(val) __write_ulong_gc0_register(14, 0, val) - -#define read_gc0_prid() __read_32bit_gc0_register(15, 0) - -#define read_gc0_ebase() __read_32bit_gc0_register(15, 1) -#define write_gc0_ebase(val) __write_32bit_gc0_register(15, 1, val) - -#define read_gc0_ebase_64() __read_64bit_gc0_register(15, 1) -#define write_gc0_ebase_64(val) __write_64bit_gc0_register(15, 1, val) - -#define read_gc0_config() __read_32bit_gc0_register(16, 0) -#define read_gc0_config1() __read_32bit_gc0_register(16, 1) -#define read_gc0_config2() __read_32bit_gc0_register(16, 2) -#define read_gc0_config3() __read_32bit_gc0_register(16, 3) -#define read_gc0_config4() __read_32bit_gc0_register(16, 4) -#define read_gc0_config5() __read_32bit_gc0_register(16, 5) -#define read_gc0_config6() __read_32bit_gc0_register(16, 6) -#define read_gc0_config7() __read_32bit_gc0_register(16, 7) -#define write_gc0_config(val) __write_32bit_gc0_register(16, 0, val) -#define write_gc0_config1(val) __write_32bit_gc0_register(16, 1, val) -#define write_gc0_config2(val) __write_32bit_gc0_register(16, 2, val) -#define write_gc0_config3(val) __write_32bit_gc0_register(16, 3, val) -#define write_gc0_config4(val) __write_32bit_gc0_register(16, 4, val) -#define write_gc0_config5(val) __write_32bit_gc0_register(16, 5, val) -#define write_gc0_config6(val) __write_32bit_gc0_register(16, 6, val) -#define write_gc0_config7(val) __write_32bit_gc0_register(16, 7, val) - -#define read_gc0_lladdr() __read_ulong_gc0_register(17, 0) -#define write_gc0_lladdr(val) __write_ulong_gc0_register(17, 0, val) - -#define read_gc0_watchlo0() __read_ulong_gc0_register(18, 0) -#define read_gc0_watchlo1() __read_ulong_gc0_register(18, 1) -#define read_gc0_watchlo2() __read_ulong_gc0_register(18, 2) -#define read_gc0_watchlo3() __read_ulong_gc0_register(18, 3) -#define read_gc0_watchlo4() __read_ulong_gc0_register(18, 4) -#define read_gc0_watchlo5() __read_ulong_gc0_register(18, 5) -#define read_gc0_watchlo6() __read_ulong_gc0_register(18, 6) -#define read_gc0_watchlo7() __read_ulong_gc0_register(18, 7) -#define write_gc0_watchlo0(val) __write_ulong_gc0_register(18, 0, val) -#define write_gc0_watchlo1(val) __write_ulong_gc0_register(18, 1, val) -#define write_gc0_watchlo2(val) __write_ulong_gc0_register(18, 2, val) -#define write_gc0_watchlo3(val) __write_ulong_gc0_register(18, 3, val) -#define write_gc0_watchlo4(val) __write_ulong_gc0_register(18, 4, val) -#define write_gc0_watchlo5(val) __write_ulong_gc0_register(18, 5, val) -#define write_gc0_watchlo6(val) __write_ulong_gc0_register(18, 6, val) -#define write_gc0_watchlo7(val) __write_ulong_gc0_register(18, 7, val) - -#define read_gc0_watchhi0() __read_32bit_gc0_register(19, 0) -#define read_gc0_watchhi1() __read_32bit_gc0_register(19, 1) -#define read_gc0_watchhi2() __read_32bit_gc0_register(19, 2) -#define read_gc0_watchhi3() __read_32bit_gc0_register(19, 3) -#define read_gc0_watchhi4() __read_32bit_gc0_register(19, 4) -#define read_gc0_watchhi5() __read_32bit_gc0_register(19, 5) -#define read_gc0_watchhi6() __read_32bit_gc0_register(19, 6) -#define read_gc0_watchhi7() __read_32bit_gc0_register(19, 7) -#define write_gc0_watchhi0(val) __write_32bit_gc0_register(19, 0, val) -#define write_gc0_watchhi1(val) __write_32bit_gc0_register(19, 1, val) -#define write_gc0_watchhi2(val) __write_32bit_gc0_register(19, 2, val) -#define write_gc0_watchhi3(val) __write_32bit_gc0_register(19, 3, val) -#define write_gc0_watchhi4(val) __write_32bit_gc0_register(19, 4, val) -#define write_gc0_watchhi5(val) __write_32bit_gc0_register(19, 5, val) -#define write_gc0_watchhi6(val) __write_32bit_gc0_register(19, 6, val) -#define write_gc0_watchhi7(val) __write_32bit_gc0_register(19, 7, val) - -#define read_gc0_xcontext() __read_ulong_gc0_register(20, 0) -#define write_gc0_xcontext(val) __write_ulong_gc0_register(20, 0, val) - -#define read_gc0_perfctrl0() __read_32bit_gc0_register(25, 0) -#define write_gc0_perfctrl0(val) __write_32bit_gc0_register(25, 0, val) -#define read_gc0_perfcntr0() __read_32bit_gc0_register(25, 1) -#define write_gc0_perfcntr0(val) __write_32bit_gc0_register(25, 1, val) -#define read_gc0_perfcntr0_64() __read_64bit_gc0_register(25, 1) -#define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register(25, 1, val) -#define read_gc0_perfctrl1() __read_32bit_gc0_register(25, 2) -#define write_gc0_perfctrl1(val) __write_32bit_gc0_register(25, 2, val) -#define read_gc0_perfcntr1() __read_32bit_gc0_register(25, 3) -#define write_gc0_perfcntr1(val) __write_32bit_gc0_register(25, 3, val) -#define read_gc0_perfcntr1_64() __read_64bit_gc0_register(25, 3) -#define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register(25, 3, val) -#define read_gc0_perfctrl2() __read_32bit_gc0_register(25, 4) -#define write_gc0_perfctrl2(val) __write_32bit_gc0_register(25, 4, val) -#define read_gc0_perfcntr2() __read_32bit_gc0_register(25, 5) -#define write_gc0_perfcntr2(val) __write_32bit_gc0_register(25, 5, val) -#define read_gc0_perfcntr2_64() __read_64bit_gc0_register(25, 5) -#define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register(25, 5, val) -#define read_gc0_perfctrl3() __read_32bit_gc0_register(25, 6) -#define write_gc0_perfctrl3(val) __write_32bit_gc0_register(25, 6, val) -#define read_gc0_perfcntr3() __read_32bit_gc0_register(25, 7) -#define write_gc0_perfcntr3(val) __write_32bit_gc0_register(25, 7, val) -#define read_gc0_perfcntr3_64() __read_64bit_gc0_register(25, 7) -#define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register(25, 7, val) - -#define read_gc0_errorepc() __read_ulong_gc0_register(30, 0) -#define write_gc0_errorepc(val) __write_ulong_gc0_register(30, 0, val) - -#define read_gc0_kscratch1() __read_ulong_gc0_register(31, 2) -#define read_gc0_kscratch2() __read_ulong_gc0_register(31, 3) -#define read_gc0_kscratch3() __read_ulong_gc0_register(31, 4) -#define read_gc0_kscratch4() __read_ulong_gc0_register(31, 5) -#define read_gc0_kscratch5() __read_ulong_gc0_register(31, 6) -#define read_gc0_kscratch6() __read_ulong_gc0_register(31, 7) -#define write_gc0_kscratch1(val) __write_ulong_gc0_register(31, 2, val) -#define write_gc0_kscratch2(val) __write_ulong_gc0_register(31, 3, val) -#define write_gc0_kscratch3(val) __write_ulong_gc0_register(31, 4, val) -#define write_gc0_kscratch4(val) __write_ulong_gc0_register(31, 5, val) -#define write_gc0_kscratch5(val) __write_ulong_gc0_register(31, 6, val) -#define write_gc0_kscratch6(val) __write_ulong_gc0_register(31, 7, val) +#define read_gc0_pwctl() __read_32bit_gc0_register($6, 6) +#define write_gc0_pwctl(val) __write_32bit_gc0_register($6, 6, val) + +#define read_gc0_hwrena() __read_32bit_gc0_register($7, 0) +#define write_gc0_hwrena(val) __write_32bit_gc0_register($7, 0, val) + +#define read_gc0_badvaddr() __read_ulong_gc0_register($8, 0) +#define write_gc0_badvaddr(val) __write_ulong_gc0_register($8, 0, val) + +#define read_gc0_badinstr() __read_32bit_gc0_register($8, 1) +#define write_gc0_badinstr(val) __write_32bit_gc0_register($8, 1, val) + +#define read_gc0_badinstrp() __read_32bit_gc0_register($8, 2) +#define write_gc0_badinstrp(val) __write_32bit_gc0_register($8, 2, val) + +#define read_gc0_count() __read_32bit_gc0_register($9, 0) + +#define read_gc0_entryhi() __read_ulong_gc0_register($10, 0) +#define write_gc0_entryhi(val) __write_ulong_gc0_register($10, 0, val) + +#define read_gc0_compare() __read_32bit_gc0_register($11, 0) +#define write_gc0_compare(val) __write_32bit_gc0_register($11, 0, val) + +#define read_gc0_status() __read_32bit_gc0_register($12, 0) +#define write_gc0_status(val) __write_32bit_gc0_register($12, 0, val) + +#define read_gc0_intctl() __read_32bit_gc0_register($12, 1) +#define write_gc0_intctl(val) __write_32bit_gc0_register($12, 1, val) + +#define read_gc0_cause() __read_32bit_gc0_register($13, 0) +#define write_gc0_cause(val) __write_32bit_gc0_register($13, 0, val) + +#define read_gc0_epc() __read_ulong_gc0_register($14, 0) +#define write_gc0_epc(val) __write_ulong_gc0_register($14, 0, val) + +#define read_gc0_prid() __read_32bit_gc0_register($15, 0) + +#define read_gc0_ebase() __read_32bit_gc0_register($15, 1) +#define write_gc0_ebase(val) __write_32bit_gc0_register($15, 1, val) + +#define read_gc0_ebase_64() __read_64bit_gc0_register($15, 1) +#define write_gc0_ebase_64(val) __write_64bit_gc0_register($15, 1, val) + +#define read_gc0_config() __read_32bit_gc0_register($16, 0) +#define read_gc0_config1() __read_32bit_gc0_register($16, 1) +#define read_gc0_config2() __read_32bit_gc0_register($16, 2) +#define read_gc0_config3() __read_32bit_gc0_register($16, 3) +#define read_gc0_config4() __read_32bit_gc0_register($16, 4) +#define read_gc0_config5() __read_32bit_gc0_register($16, 5) +#define read_gc0_config6() __read_32bit_gc0_register($16, 6) +#define read_gc0_config7() __read_32bit_gc0_register($16, 7) +#define write_gc0_config(val) __write_32bit_gc0_register($16, 0, val) +#define write_gc0_config1(val) __write_32bit_gc0_register($16, 1, val) +#define write_gc0_config2(val) __write_32bit_gc0_register($16, 2, val) +#define write_gc0_config3(val) __write_32bit_gc0_register($16, 3, val) +#define write_gc0_config4(val) __write_32bit_gc0_register($16, 4, val) +#define write_gc0_config5(val) __write_32bit_gc0_register($16, 5, val) +#define write_gc0_config6(val) __write_32bit_gc0_register($16, 6, val) +#define write_gc0_config7(val) __write_32bit_gc0_register($16, 7, val) + +#define read_gc0_lladdr() __read_ulong_gc0_register($17, 0) +#define write_gc0_lladdr(val) __write_ulong_gc0_register($17, 0, val) + +#define read_gc0_watchlo0() __read_ulong_gc0_register($18, 0) +#define read_gc0_watchlo1() __read_ulong_gc0_register($18, 1) +#define read_gc0_watchlo2() __read_ulong_gc0_register($18, 2) +#define read_gc0_watchlo3() __read_ulong_gc0_register($18, 3) +#define read_gc0_watchlo4() __read_ulong_gc0_register($18, 4) +#define read_gc0_watchlo5() __read_ulong_gc0_register($18, 5) +#define read_gc0_watchlo6() __read_ulong_gc0_register($18, 6) +#define read_gc0_watchlo7() __read_ulong_gc0_register($18, 7) +#define write_gc0_watchlo0(val) __write_ulong_gc0_register($18, 0, val) +#define write_gc0_watchlo1(val) __write_ulong_gc0_register($18, 1, val) +#define write_gc0_watchlo2(val) __write_ulong_gc0_register($18, 2, val) +#define write_gc0_watchlo3(val) __write_ulong_gc0_register($18, 3, val) +#define write_gc0_watchlo4(val) __write_ulong_gc0_register($18, 4, val) +#define write_gc0_watchlo5(val) __write_ulong_gc0_register($18, 5, val) +#define write_gc0_watchlo6(val) __write_ulong_gc0_register($18, 6, val) +#define write_gc0_watchlo7(val) __write_ulong_gc0_register($18, 7, val) + +#define read_gc0_watchhi0() __read_32bit_gc0_register($19, 0) +#define read_gc0_watchhi1() __read_32bit_gc0_register($19, 1) +#define read_gc0_watchhi2() __read_32bit_gc0_register($19, 2) +#define read_gc0_watchhi3() __read_32bit_gc0_register($19, 3) +#define read_gc0_watchhi4() __read_32bit_gc0_register($19, 4) +#define read_gc0_watchhi5() __read_32bit_gc0_register($19, 5) +#define read_gc0_watchhi6() __read_32bit_gc0_register($19, 6) +#define read_gc0_watchhi7() __read_32bit_gc0_register($19, 7) +#define write_gc0_watchhi0(val) __write_32bit_gc0_register($19, 0, val) +#define write_gc0_watchhi1(val) __write_32bit_gc0_register($19, 1, val) +#define write_gc0_watchhi2(val) __write_32bit_gc0_register($19, 2, val) +#define write_gc0_watchhi3(val) __write_32bit_gc0_register($19, 3, val) +#define write_gc0_watchhi4(val) __write_32bit_gc0_register($19, 4, val) +#define write_gc0_watchhi5(val) __write_32bit_gc0_register($19, 5, val) +#define write_gc0_watchhi6(val) __write_32bit_gc0_register($19, 6, val) +#define write_gc0_watchhi7(val) __write_32bit_gc0_register($19, 7, val) + +#define read_gc0_xcontext() __read_ulong_gc0_register($20, 0) +#define write_gc0_xcontext(val) __write_ulong_gc0_register($20, 0, val) + +#define read_gc0_perfctrl0() __read_32bit_gc0_register($25, 0) +#define write_gc0_perfctrl0(val) __write_32bit_gc0_register($25, 0, val) +#define read_gc0_perfcntr0() __read_32bit_gc0_register($25, 1) +#define write_gc0_perfcntr0(val) __write_32bit_gc0_register($25, 1, val) +#define read_gc0_perfcntr0_64() __read_64bit_gc0_register($25, 1) +#define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register($25, 1, val) +#define read_gc0_perfctrl1() __read_32bit_gc0_register($25, 2) +#define write_gc0_perfctrl1(val) __write_32bit_gc0_register($25, 2, val) +#define read_gc0_perfcntr1() __read_32bit_gc0_register($25, 3) +#define write_gc0_perfcntr1(val) __write_32bit_gc0_register($25, 3, val) +#define read_gc0_perfcntr1_64() __read_64bit_gc0_register($25, 3) +#define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register($25, 3, val) +#define read_gc0_perfctrl2() __read_32bit_gc0_register($25, 4) +#define write_gc0_perfctrl2(val) __write_32bit_gc0_register($25, 4, val) +#define read_gc0_perfcntr2() __read_32bit_gc0_register($25, 5) +#define write_gc0_perfcntr2(val) __write_32bit_gc0_register($25, 5, val) +#define read_gc0_perfcntr2_64() __read_64bit_gc0_register($25, 5) +#define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register($25, 5, val) +#define read_gc0_perfctrl3() __read_32bit_gc0_register($25, 6) +#define write_gc0_perfctrl3(val) __write_32bit_gc0_register($25, 6, val) +#define read_gc0_perfcntr3() __read_32bit_gc0_register($25, 7) +#define write_gc0_perfcntr3(val) __write_32bit_gc0_register($25, 7, val) +#define read_gc0_perfcntr3_64() __read_64bit_gc0_register($25, 7) +#define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register($25, 7, val) + +#define read_gc0_errorepc() __read_ulong_gc0_register($30, 0) +#define write_gc0_errorepc(val) __write_ulong_gc0_register($30, 0, val) + +#define read_gc0_kscratch1() __read_ulong_gc0_register($31, 2) +#define read_gc0_kscratch2() __read_ulong_gc0_register($31, 3) +#define read_gc0_kscratch3() __read_ulong_gc0_register($31, 4) +#define read_gc0_kscratch4() __read_ulong_gc0_register($31, 5) +#define read_gc0_kscratch5() __read_ulong_gc0_register($31, 6) +#define read_gc0_kscratch6() __read_ulong_gc0_register($31, 7) +#define write_gc0_kscratch1(val) __write_ulong_gc0_register($31, 2, val) +#define write_gc0_kscratch2(val) __write_ulong_gc0_register($31, 3, val) +#define write_gc0_kscratch3(val) __write_ulong_gc0_register($31, 4, val) +#define write_gc0_kscratch4(val) __write_ulong_gc0_register($31, 5, val) +#define write_gc0_kscratch5(val) __write_ulong_gc0_register($31, 6, val) +#define write_gc0_kscratch6(val) __write_ulong_gc0_register($31, 7, val) /* Cavium OCTEON (cnMIPS) */ -#define read_gc0_cvmcount() __read_ulong_gc0_register(9, 6) -#define write_gc0_cvmcount(val) __write_ulong_gc0_register(9, 6, val) +#define read_gc0_cvmcount() __read_ulong_gc0_register($9, 6) +#define write_gc0_cvmcount(val) __write_ulong_gc0_register($9, 6, val) -#define read_gc0_cvmctl() __read_64bit_gc0_register(9, 7) -#define write_gc0_cvmctl(val) __write_64bit_gc0_register(9, 7, val) +#define read_gc0_cvmctl() __read_64bit_gc0_register($9, 7) +#define write_gc0_cvmctl(val) __write_64bit_gc0_register($9, 7, val) -#define read_gc0_cvmmemctl() __read_64bit_gc0_register(11, 7) -#define write_gc0_cvmmemctl(val) __write_64bit_gc0_register(11, 7, val) +#define read_gc0_cvmmemctl() __read_64bit_gc0_register($11, 7) +#define write_gc0_cvmmemctl(val) __write_64bit_gc0_register($11, 7, val) -#define read_gc0_cvmmemctl2() __read_64bit_gc0_register(16, 6) -#define write_gc0_cvmmemctl2(val) __write_64bit_gc0_register(16, 6, val) +#define read_gc0_cvmmemctl2() __read_64bit_gc0_register($16, 6) +#define write_gc0_cvmmemctl2(val) __write_64bit_gc0_register($16, 6, val) /* * Macros to access the floating point coprocessor control registers @@ -2581,8 +2651,6 @@ static inline void tlb_write_random(void) ".set reorder"); } -#ifdef TOOLCHAIN_SUPPORTS_VIRT - /* * Guest TLB operations. * @@ -2593,7 +2661,7 @@ static inline void guest_tlb_probe(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgp\n\t" ".set pop"); } @@ -2603,7 +2671,7 @@ static inline void guest_tlb_read(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgr\n\t" ".set pop"); } @@ -2613,7 +2681,7 @@ static inline void guest_tlb_write_indexed(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgwi\n\t" ".set pop"); } @@ -2623,7 +2691,7 @@ static inline void guest_tlb_write_random(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgwr\n\t" ".set pop"); } @@ -2636,63 +2704,11 @@ static inline void guest_tlbinvf(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbginvf\n\t" ".set pop"); } -#else /* TOOLCHAIN_SUPPORTS_VIRT */ - -/* - * Guest TLB operations. - * - * It is responsibility of the caller to take care of any TLB hazards. - */ -static inline void guest_tlb_probe(void) -{ - __asm__ __volatile__( - "# tlbgp\n\t" - _ASM_INSN_IF_MIPS(0x42000010) - _ASM_INSN32_IF_MM(0x0000017c)); -} - -static inline void guest_tlb_read(void) -{ - __asm__ __volatile__( - "# tlbgr\n\t" - _ASM_INSN_IF_MIPS(0x42000009) - _ASM_INSN32_IF_MM(0x0000117c)); -} - -static inline void guest_tlb_write_indexed(void) -{ - __asm__ __volatile__( - "# tlbgwi\n\t" - _ASM_INSN_IF_MIPS(0x4200000a) - _ASM_INSN32_IF_MM(0x0000217c)); -} - -static inline void guest_tlb_write_random(void) -{ - __asm__ __volatile__( - "# tlbgwr\n\t" - _ASM_INSN_IF_MIPS(0x4200000e) - _ASM_INSN32_IF_MM(0x0000317c)); -} - -/* - * Guest TLB Invalidate Flush - */ -static inline void guest_tlbinvf(void) -{ - __asm__ __volatile__( - "# tlbginvf\n\t" - _ASM_INSN_IF_MIPS(0x4200000c) - _ASM_INSN32_IF_MM(0x0000517c)); -} - -#endif /* !TOOLCHAIN_SUPPORTS_VIRT */ - /* * Manipulate bits in a register. */ diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h index b1845102f8f9..b4f9577ed96a 100644 --- a/arch/mips/include/asm/msa.h +++ b/arch/mips/include/asm/msa.h @@ -160,7 +160,23 @@ static inline void init_msa_upper(void) _init_msa_upper(); } -#ifdef TOOLCHAIN_SUPPORTS_MSA +#ifndef TOOLCHAIN_SUPPORTS_MSA +/* + * Define assembler macros using .word for the c[ft]cmsa instructions in order + * to allow compilation with toolchains that do not support MSA. Once all + * toolchains in use support MSA these can be removed. + */ +_ASM_MACRO_2R(cfcmsa, rd, cs, + _ASM_INSN_IF_MIPS(0x787e0019 | __cs << 11 | __rd << 6) + _ASM_INSN32_IF_MM(0x587e0016 | __cs << 11 | __rd << 6)); +_ASM_MACRO_2R(ctcmsa, cd, rs, + _ASM_INSN_IF_MIPS(0x783e0019 | __rs << 11 | __cd << 6) + _ASM_INSN32_IF_MM(0x583e0016 | __rs << 11 | __cd << 6)); +#define _ASM_SET_MSA "" +#else /* TOOLCHAIN_SUPPORTS_MSA */ +#define _ASM_SET_MSA ".set\tfp=64\n\t" \ + ".set\tmsa\n\t" +#endif #define __BUILD_MSA_CTL_REG(name, cs) \ static inline unsigned int read_msa_##name(void) \ @@ -168,8 +184,7 @@ static inline unsigned int read_msa_##name(void) \ unsigned int reg; \ __asm__ __volatile__( \ " .set push\n" \ - " .set fp=64\n" \ - " .set msa\n" \ + _ASM_SET_MSA \ " cfcmsa %0, $" #cs "\n" \ " .set pop\n" \ : "=r"(reg)); \ @@ -180,52 +195,12 @@ static inline void write_msa_##name(unsigned int val) \ { \ __asm__ __volatile__( \ " .set push\n" \ - " .set fp=64\n" \ - " .set msa\n" \ + _ASM_SET_MSA \ " ctcmsa $" #cs ", %0\n" \ " .set pop\n" \ : : "r"(val)); \ } -#else /* !TOOLCHAIN_SUPPORTS_MSA */ - -/* - * Define functions using .word for the c[ft]cmsa instructions in order to - * allow compilation with toolchains that do not support MSA. Once all - * toolchains in use support MSA these can be removed. - */ - -#define __BUILD_MSA_CTL_REG(name, cs) \ -static inline unsigned int read_msa_##name(void) \ -{ \ - unsigned int reg; \ - __asm__ __volatile__( \ - " .set push\n" \ - " .set noat\n" \ - " # cfcmsa $1, $%1\n" \ - _ASM_INSN_IF_MIPS(0x787e0059 | %1 << 11) \ - _ASM_INSN32_IF_MM(0x587e0056 | %1 << 11) \ - " move %0, $1\n" \ - " .set pop\n" \ - : "=r"(reg) : "i"(cs)); \ - return reg; \ -} \ - \ -static inline void write_msa_##name(unsigned int val) \ -{ \ - __asm__ __volatile__( \ - " .set push\n" \ - " .set noat\n" \ - " move $1, %0\n" \ - " # ctcmsa $%1, $1\n" \ - _ASM_INSN_IF_MIPS(0x783e0819 | %1 << 6) \ - _ASM_INSN32_IF_MM(0x583e0816 | %1 << 6) \ - " .set pop\n" \ - : : "r"(val), "i"(cs)); \ -} - -#endif /* !TOOLCHAIN_SUPPORTS_MSA */ - __BUILD_MSA_CTL_REG(ir, 0) __BUILD_MSA_CTL_REG(csr, 1) __BUILD_MSA_CTL_REG(access, 2) diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig index 643af2012e14..4dd0c446ecec 100644 --- a/arch/mips/jz4740/Kconfig +++ b/arch/mips/jz4740/Kconfig @@ -8,6 +8,10 @@ config JZ4740_QI_LB60 bool "Qi Hardware Ben NanoNote" select MACH_JZ4740 +config JZ4770_GCW0 + bool "Game Consoles Worldwide GCW Zero" + select MACH_JZ4770 + config JZ4780_CI20 bool "MIPS Creator CI20" select MACH_JZ4780 @@ -18,6 +22,12 @@ config MACH_JZ4740 bool select SYS_HAS_CPU_MIPS32_R1 +config MACH_JZ4770 + bool + select MIPS_CPU_SCACHE + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_HIGHMEM + config MACH_JZ4780 bool select MIPS_CPU_SCACHE diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c index 47e857194ce6..eb9f2f97bedb 100644 --- a/arch/mips/jz4740/prom.c +++ b/arch/mips/jz4740/prom.c @@ -20,33 +20,12 @@ #include <linux/serial_reg.h> #include <asm/bootinfo.h> +#include <asm/fw/fw.h> #include <asm/mach-jz4740/base.h> -static __init void jz4740_init_cmdline(int argc, char *argv[]) -{ - unsigned int count = COMMAND_LINE_SIZE - 1; - int i; - char *dst = &(arcs_cmdline[0]); - char *src; - - for (i = 1; i < argc && count; ++i) { - src = argv[i]; - while (*src && count) { - *dst++ = *src++; - --count; - } - *dst++ = ' '; - } - if (i > 1) - --dst; - - *dst = 0; -} - void __init prom_init(void) { - jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1); - mips_machtype = MACH_INGENIC_JZ4740; + fw_init_cmdline(); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 6d0152321819..afb40f8bce96 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c @@ -53,6 +53,16 @@ static void __init jz4740_detect_mem(void) add_memory_region(0, size, BOOT_MEM_RAM); } +static unsigned long __init get_board_mach_type(const void *fdt) +{ + if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780")) + return MACH_INGENIC_JZ4780; + if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770")) + return MACH_INGENIC_JZ4770; + + return MACH_INGENIC_JZ4740; +} + void __init plat_mem_setup(void) { int offset; @@ -63,6 +73,8 @@ void __init plat_mem_setup(void) offset = fdt_path_offset(__dtb_start, "/memory"); if (offset < 0) jz4740_detect_mem(); + + mips_machtype = get_board_mach_type(__dtb_start); } void __init device_tree_init(void) @@ -75,10 +87,14 @@ void __init device_tree_init(void) const char *get_system_type(void) { - if (IS_ENABLED(CONFIG_MACH_JZ4780)) + switch (mips_machtype) { + case MACH_INGENIC_JZ4780: return "JZ4780"; - - return "JZ4740"; + case MACH_INGENIC_JZ4770: + return "JZ4770"; + default: + return "JZ4740"; + } } void __init arch_init_irq(void) diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index bb1ad5119da4..2ca9160f642a 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c @@ -113,7 +113,7 @@ static struct clock_event_device jz4740_clockevent = { #ifdef CONFIG_MACH_JZ4740 .irq = JZ4740_IRQ_TCU0, #endif -#ifdef CONFIG_MACH_JZ4780 +#if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780) .irq = JZ4780_IRQ_TCU2, #endif }; diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index b79ed9af9886..e48f6c0a9e4a 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -399,7 +399,7 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs) * * @regs: Pointer to pt_regs * @insn: branch instruction to decode - * @returns: -EFAULT on error and forces SIGILL, and on success + * Return: -EFAULT on error and forces SIGILL, and on success * returns 0 or BRANCH_LIKELY_TAKEN as appropriate after * evaluating the branch. * diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 99285be0e088..7f3dfdbc3657 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -361,7 +361,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra, * If fails when getting the stack address of the non-leaf function's * ra, stop function graph tracer and return */ - if (parent_ra_addr == 0) + if (parent_ra_addr == NULL) goto out; #endif /* *parent_ra_addr = return_hooker; */ diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 702c678de116..85bc601e9a0d 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -826,25 +826,6 @@ static void __init arch_mem_init(char **cmdline_p) struct memblock_region *reg; extern void plat_mem_setup(void); - /* call board setup routine */ - plat_mem_setup(); - - /* - * Make sure all kernel memory is in the maps. The "UP" and - * "DOWN" are opposite for initdata since if it crosses over - * into another memory section you don't want that to be - * freed when the initdata is freed. - */ - arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT, - PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT, - BOOT_MEM_RAM); - arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, - PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, - BOOT_MEM_INIT_RAM); - - pr_info("Determined physical RAM map:\n"); - print_memory_map(); - #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE) strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); #else @@ -872,6 +853,26 @@ static void __init arch_mem_init(char **cmdline_p) } #endif #endif + + /* call board setup routine */ + plat_mem_setup(); + + /* + * Make sure all kernel memory is in the maps. The "UP" and + * "DOWN" are opposite for initdata since if it crosses over + * into another memory section you don't want that to be + * freed when the initdata is freed. + */ + arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT, + PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT, + BOOT_MEM_RAM); + arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, + PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, + BOOT_MEM_INIT_RAM); + + pr_info("Determined physical RAM map:\n"); + print_memory_map(); + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index ecc1a853f48d..03f1026ad148 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -439,8 +439,6 @@ void play_dead(void) pr_debug("CPU%d going offline\n", cpu); if (cpu_has_mipsmt || cpu_has_vp) { - core = cpu_core(&cpu_data[cpu]); - /* Look for another online VPE within the core */ for_each_online_cpu(cpu_death_sibling) { if (!cpus_are_siblings(cpu, cpu_death_sibling)) diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c index 19fcab7348b1..0e61a5b7647f 100644 --- a/arch/mips/kernel/watch.c +++ b/arch/mips/kernel/watch.c @@ -18,27 +18,24 @@ void mips_install_watch_registers(struct task_struct *t) { struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264; + unsigned int watchhi = MIPS_WATCHHI_G | /* Trap all ASIDs */ + MIPS_WATCHHI_IRW; /* Clear result bits */ + switch (current_cpu_data.watch_reg_use_cnt) { default: BUG(); case 4: write_c0_watchlo3(watches->watchlo[3]); - /* Write 1 to the I, R, and W bits to clear them, and - 1 to G so all ASIDs are trapped. */ - write_c0_watchhi3(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[3]); + write_c0_watchhi3(watchhi | watches->watchhi[3]); case 3: write_c0_watchlo2(watches->watchlo[2]); - write_c0_watchhi2(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[2]); + write_c0_watchhi2(watchhi | watches->watchhi[2]); case 2: write_c0_watchlo1(watches->watchlo[1]); - write_c0_watchhi1(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[1]); + write_c0_watchhi1(watchhi | watches->watchhi[1]); case 1: write_c0_watchlo0(watches->watchlo[0]); - write_c0_watchhi0(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[0]); + write_c0_watchhi0(watchhi | watches->watchhi[0]); } } @@ -51,21 +48,19 @@ void mips_read_watch_registers(void) { struct mips3264_watch_reg_state *watches = ¤t->thread.watch.mips3264; + unsigned int watchhi_mask = MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW; + switch (current_cpu_data.watch_reg_use_cnt) { default: BUG(); case 4: - watches->watchhi[3] = (read_c0_watchhi3() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[3] = (read_c0_watchhi3() & watchhi_mask); case 3: - watches->watchhi[2] = (read_c0_watchhi2() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[2] = (read_c0_watchhi2() & watchhi_mask); case 2: - watches->watchhi[1] = (read_c0_watchhi1() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[1] = (read_c0_watchhi1() & watchhi_mask); case 1: - watches->watchhi[0] = (read_c0_watchhi0() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[0] = (read_c0_watchhi0() & watchhi_mask); } if (current_cpu_data.watch_reg_use_cnt == 1 && (watches->watchhi[0] & MIPS_WATCHHI_IRW) == 0) { diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig index 6f109bb54cdb..bc2fdbfa8223 100644 --- a/arch/mips/loongson64/Kconfig +++ b/arch/mips/loongson64/Kconfig @@ -17,7 +17,6 @@ config LEMOTE_FULOONG2E select I8259 select ISA select IRQ_MIPS_CPU - select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM @@ -49,7 +48,6 @@ config LEMOTE_MACH2F select ISA select SYS_HAS_CPU_LOONGSON2F select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_LITTLE_ENDIAN diff --git a/arch/mips/loongson64/common/mem.c b/arch/mips/loongson64/common/mem.c index b01d52473da8..c549e525fc11 100644 --- a/arch/mips/loongson64/common/mem.c +++ b/arch/mips/loongson64/common/mem.c @@ -79,7 +79,7 @@ void __init prom_init_memory(void) (u64)loongson_memmap->map[i].mem_size << 20, BOOT_MEM_RAM); break; - case MEM_RESERVED: + case SYSTEM_RAM_RESERVED: add_memory_region(loongson_memmap->map[i].mem_start, (u64)loongson_memmap->map[i].mem_size << 20, BOOT_MEM_RESERVED); diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c index f17ef520799a..9717106de4a5 100644 --- a/arch/mips/loongson64/loongson-3/numa.c +++ b/arch/mips/loongson64/loongson-3/numa.c @@ -166,7 +166,7 @@ static void __init szmem(unsigned int node) memblock_add_node(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn), node); break; - case MEM_RESERVED: + case SYSTEM_RAM_RESERVED: pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", (u32)node_id, mem_type, mem_start, mem_size); add_memory_region((node_id << 44) + mem_start, diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index da6c1c0c30c1..62deb025970b 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -451,7 +451,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; } - /* Fall through */ + /* fall through */ case jr_op: /* For R6, JR already emulated in jalr_op */ if (NO_R6EMU && insn.r_format.func == jr_op) @@ -471,10 +471,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; - /* Fall through */ + /* fall through */ case bltzl_op: if (NO_R6EMU) break; + /* fall through */ case bltz_op: if ((long)regs->regs[insn.i_format.rs] < 0) *contpc = regs->cp0_epc + @@ -494,10 +495,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; - /* Fall through */ + /* fall through */ case bgezl_op: if (NO_R6EMU) break; + /* fall through */ case bgez_op: if ((long)regs->regs[insn.i_format.rs] >= 0) *contpc = regs->cp0_epc + @@ -512,11 +514,12 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, break; case jalx_op: set_isa16_mode(bit); + /* fall through */ case jal_op: regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; - /* Fall through */ + /* fall through */ case j_op: *contpc = regs->cp0_epc + dec_insn.pc_inc; *contpc >>= 28; @@ -528,6 +531,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case beql_op: if (NO_R6EMU) break; + /* fall through */ case beq_op: if (regs->regs[insn.i_format.rs] == regs->regs[insn.i_format.rt]) @@ -542,6 +546,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case bnel_op: if (NO_R6EMU) break; + /* fall through */ case bne_op: if (regs->regs[insn.i_format.rs] != regs->regs[insn.i_format.rt]) @@ -556,6 +561,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case blezl_op: if (!insn.i_format.rt && NO_R6EMU) break; + /* fall through */ case blez_op: /* @@ -593,6 +599,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case bgtzl_op: if (!insn.i_format.rt && NO_R6EMU) break; + /* fall through */ case bgtz_op: /* * Compact branches for R6 for the @@ -729,7 +736,8 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, return 1; } - /* R2/R6 compatible cop1 instruction. Fall through */ + /* R2/R6 compatible cop1 instruction */ + /* fall through */ case cop2_op: case cop1x_op: if (insn.i_format.rs == bc_op) { @@ -1190,7 +1198,8 @@ emul: if (!cpu_has_mips_r6 || delay_slot(xcp)) return SIGILL; - cond = likely = 0; + likely = 0; + cond = 0; fpr = ¤t->thread.fpu.fpr[MIPSInst_RT(ir)]; bit0 = get_fpr32(fpr, 0) & 0x1; switch (MIPSInst_RS(ir)) { @@ -1220,14 +1229,14 @@ emul: case bcfl_op: if (cpu_has_mips_2_3_4_5_r) likely = 1; - /* Fall through */ + /* fall through */ case bcf_op: cond = !cond; break; case bctl_op: if (cpu_has_mips_2_3_4_5_r) likely = 1; - /* Fall through */ + /* fall through */ case bct_op: break; } @@ -1353,7 +1362,8 @@ branch_common: return SIGILL; /* a real fpu computation instruction */ - if ((sig = fpu_emu(xcp, ctx, ir))) + sig = fpu_emu(xcp, ctx, ir); + if (sig) return sig; } break; diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c index 8954ef031f84..678de20e4cb1 100644 --- a/arch/mips/math-emu/dp_add.c +++ b/arch/mips/math-emu/dp_add.c @@ -104,8 +104,7 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; - - /* FALL THROUGH */ + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c index f4746f7c5f63..3063ae3ab3b9 100644 --- a/arch/mips/math-emu/dp_div.c +++ b/arch/mips/math-emu/dp_div.c @@ -103,6 +103,7 @@ union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c index 5bec64f2884e..d1f984b40344 100644 --- a/arch/mips/math-emu/dp_fmax.c +++ b/arch/mips/math-emu/dp_fmax.c @@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; @@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c index a287b23818d8..f98b96135c8d 100644 --- a/arch/mips/math-emu/dp_fmin.c +++ b/arch/mips/math-emu/dp_fmin.c @@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; @@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c index 7ad79ed411f5..7ea2f8222026 100644 --- a/arch/mips/math-emu/dp_maddf.c +++ b/arch/mips/math-emu/dp_maddf.c @@ -16,7 +16,7 @@ /* 128 bits shift right logical with rounding. */ -void srl128(u64 *hptr, u64 *lptr, int count) +static void srl128(u64 *hptr, u64 *lptr, int count) { u64 low; @@ -157,6 +157,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): if (zc == IEEE754_CLASS_INF) @@ -173,7 +174,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); - /* fall through to real computations */ + /* continue to real computations */ } /* Finally get to do some computation */ @@ -201,9 +202,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm. */ - /* 32 * 32 => 64 */ -#define DPXMULT(x, y) ((u64)(x) * (u64)y) - lxm = xm; hxm = xm >> 32; lym = ym; diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c index 60c8bfe40947..c34a6cdf1b25 100644 --- a/arch/mips/math-emu/dp_mul.c +++ b/arch/mips/math-emu/dp_mul.c @@ -101,6 +101,7 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; @@ -128,9 +129,6 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y) * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. */ - /* 32 * 32 => 64 */ -#define DPXMULT(x, y) ((u64)(x) * (u64)y) - lxm = xm; hxm = xm >> 32; lym = ym; diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c index cea907b83146..1d26c92e5295 100644 --- a/arch/mips/math-emu/dp_sqrt.c +++ b/arch/mips/math-emu/dp_sqrt.c @@ -91,7 +91,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x) scalx -= 256; } - y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); + x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); + y = x; /* magic initial approximation to almost 8 sig. bits */ yh = y.bits >> 32; @@ -108,7 +109,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x) /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */ /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */ - z = t = ieee754dp_mul(y, y); + t = ieee754dp_mul(y, y); + z = t; t.bexp += 0x001; t = ieee754dp_add(t, z); z = ieee754dp_mul(ieee754dp_sub(x, z), y); @@ -140,7 +142,7 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x) switch (oldcsr.rm) { case FPU_CSR_RU: y.bits += 1; - /* drop through */ + /* fall through */ case FPU_CSR_RN: t.bits += 1; break; diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c index fc17a781b9ae..3cc48b86519b 100644 --- a/arch/mips/math-emu/dp_sub.c +++ b/arch/mips/math-emu/dp_sub.c @@ -106,7 +106,7 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; - /* FALL THROUGH */ + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): /* normalize ym,ye */ diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h index 9ba023004eb6..a56707b75282 100644 --- a/arch/mips/math-emu/ieee754dp.h +++ b/arch/mips/math-emu/ieee754dp.h @@ -55,6 +55,9 @@ static inline int ieee754dp_finite(union ieee754dp x) #define XDPSRS1(v) \ (((v) >> 1) | ((v) & 1)) +/* 32bit * 32bit => 64bit unsigned integer multiplication */ +#define DPXMULT(x, y) ((u64)(x) * (u64)y) + /* convert denormal to normalized with extended exponent */ #define DPDNORMx(m,e) \ while ((m >> DP_FBITS) == 0) { m <<= 1; e--; } diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c index c55c0c00bca8..51dced9fbdaf 100644 --- a/arch/mips/math-emu/sp_add.c +++ b/arch/mips/math-emu/sp_add.c @@ -104,8 +104,7 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; - - /* FALL THROUGH */ + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c index 23587b31ca87..5d2904960eb8 100644 --- a/arch/mips/math-emu/sp_div.c +++ b/arch/mips/math-emu/sp_div.c @@ -103,6 +103,7 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c index 5060e8fdcb0b..36a50f9082d1 100644 --- a/arch/mips/math-emu/sp_fdp.c +++ b/arch/mips/math-emu/sp_fdp.c @@ -46,7 +46,8 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x) case IEEE754_CLASS_SNAN: x = ieee754dp_nanxcpt(x); EXPLODEXDP; - /* Fall through. */ + /* fall through */ + case IEEE754_CLASS_QNAN: y = ieee754sp_nan_fdp(xs, xm); if (!ieee754_csr.nan2008) { diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c index 74a5a00d2f22..22019ed691df 100644 --- a/arch/mips/math-emu/sp_fmax.c +++ b/arch/mips/math-emu/sp_fmax.c @@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; @@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c index c51385f46b09..feaec3985cca 100644 --- a/arch/mips/math-emu/sp_fmin.c +++ b/arch/mips/math-emu/sp_fmin.c @@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; @@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c index f823338dbb65..07ba675401e2 100644 --- a/arch/mips/math-emu/sp_maddf.c +++ b/arch/mips/math-emu/sp_maddf.c @@ -126,6 +126,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): if (zc == IEEE754_CLASS_INF) @@ -142,7 +143,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); - /* fall through to real computations */ + /* continue to real computations */ } /* Finally get to do some computation */ diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c index 4015101fbc37..fde71e293ec4 100644 --- a/arch/mips/math-emu/sp_mul.c +++ b/arch/mips/math-emu/sp_mul.c @@ -101,6 +101,7 @@ union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c index 67059c33a250..9cc83f012342 100644 --- a/arch/mips/math-emu/sp_sqrt.c +++ b/arch/mips/math-emu/sp_sqrt.c @@ -82,7 +82,8 @@ union ieee754sp ieee754sp_sqrt(union ieee754sp x) /* generate sqrt(x) bit by bit */ ix += ix; - q = s = 0; /* q = sqrt(x) */ + s = 0; + q = 0; /* q = sqrt(x) */ r = 0x01000000; /* r = moving bit from right to left */ while (r != 0) { diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c index dc998ed47295..9f2ff72c3d6b 100644 --- a/arch/mips/math-emu/sp_sub.c +++ b/arch/mips/math-emu/sp_sub.c @@ -106,6 +106,7 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c index a2450c7e452a..bca5ac995801 100644 --- a/arch/mips/math-emu/sp_tlong.c +++ b/arch/mips/math-emu/sp_tlong.c @@ -20,7 +20,6 @@ */ #include "ieee754sp.h" -#include "ieee754dp.h" s64 ieee754sp_tlong(union ieee754sp x) { diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 237532e89919..dcafa43613b6 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -370,11 +370,6 @@ static void mips_dma_sync_sg_for_device(struct device *dev, } } -static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - return 0; -} - static int mips_dma_supported(struct device *dev, u64 mask) { return plat_dma_supported(dev, mask); @@ -401,7 +396,6 @@ static const struct dma_map_ops mips_default_dma_map_ops = { .sync_single_for_device = mips_dma_sync_single_for_device, .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, .sync_sg_for_device = mips_dma_sync_sg_for_device, - .mapping_error = mips_dma_mapping_error, .dma_supported = mips_dma_supported, .cache_sync = mips_dma_cache_sync, }; diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 548acb7f8557..394673991bab 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -16,6 +16,7 @@ #include <asm/mmu_context.h> #include <asm/r4kcache.h> #include <asm/mips-cps.h> +#include <asm/bootinfo.h> /* * MIPS32/MIPS64 L2 cache handling @@ -220,6 +221,14 @@ static inline int __init mips_sc_probe(void) else return 0; + /* + * According to config2 it would be 5-ways, but that is contradicted + * by all documentation. + */ + if (current_cpu_type() == CPU_JZRISC && + mips_machtype == MACH_INGENIC_JZ4770) + c->scache.ways = 4; + c->scache.waysize = c->scache.sets * c->scache.linesz; c->scache.waybit = __ffs(c->scache.waysize); diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile index cd47b0664c2b..1456e4cdb562 100644 --- a/drivers/clk/ingenic/Makefile +++ b/drivers/clk/ingenic/Makefile @@ -1,3 +1,4 @@ obj-y += cgu.o obj-$(CONFIG_MACH_JZ4740) += jz4740-cgu.o +obj-$(CONFIG_MACH_JZ4770) += jz4770-cgu.o obj-$(CONFIG_MACH_JZ4780) += jz4780-cgu.o diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index ab393637f7b0..56a712c9075f 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -100,15 +100,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) n += pll_info->n_offset; od_enc = ctl >> pll_info->od_shift; od_enc &= GENMASK(pll_info->od_bits - 1, 0); - bypass = !!(ctl & BIT(pll_info->bypass_bit)); + bypass = !pll_info->no_bypass_bit && + !!(ctl & BIT(pll_info->bypass_bit)); enable = !!(ctl & BIT(pll_info->enable_bit)); if (bypass) return parent_rate; - if (!enable) - return 0; - for (od = 0; od < pll_info->od_max; od++) { if (pll_info->od_encoding[od] == od_enc) break; @@ -152,17 +150,25 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info, return div_u64((u64)parent_rate * m, n * od); } -static long -ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate, - unsigned long *prate) +static inline const struct ingenic_cgu_clk_info *to_clk_info( + struct ingenic_clk *ingenic_clk) { - struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); struct ingenic_cgu *cgu = ingenic_clk->cgu; const struct ingenic_cgu_clk_info *clk_info; clk_info = &cgu->clock_info[ingenic_clk->idx]; BUG_ON(clk_info->type != CGU_CLK_PLL); + return clk_info; +} + +static long +ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate, + unsigned long *prate) +{ + struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); + const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); + return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL); } @@ -170,19 +176,14 @@ static int ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate, unsigned long parent_rate) { - const unsigned timeout = 100; struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); struct ingenic_cgu *cgu = ingenic_clk->cgu; - const struct ingenic_cgu_clk_info *clk_info; - const struct ingenic_cgu_pll_info *pll_info; + const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); + const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; unsigned long rate, flags; - unsigned m, n, od, i; + unsigned int m, n, od; u32 ctl; - clk_info = &cgu->clock_info[ingenic_clk->idx]; - BUG_ON(clk_info->type != CGU_CLK_PLL); - pll_info = &clk_info->pll; - rate = ingenic_pll_calc(clk_info, req_rate, parent_rate, &m, &n, &od); if (rate != req_rate) @@ -201,6 +202,26 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate, ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift); ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift; + writel(ctl, cgu->base + pll_info->reg); + spin_unlock_irqrestore(&cgu->lock, flags); + + return 0; +} + +static int ingenic_pll_enable(struct clk_hw *hw) +{ + struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); + struct ingenic_cgu *cgu = ingenic_clk->cgu; + const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); + const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; + const unsigned int timeout = 100; + unsigned long flags; + unsigned int i; + u32 ctl; + + spin_lock_irqsave(&cgu->lock, flags); + ctl = readl(cgu->base + pll_info->reg); + ctl &= ~BIT(pll_info->bypass_bit); ctl |= BIT(pll_info->enable_bit); @@ -222,10 +243,48 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate, return 0; } +static void ingenic_pll_disable(struct clk_hw *hw) +{ + struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); + struct ingenic_cgu *cgu = ingenic_clk->cgu; + const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); + const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; + unsigned long flags; + u32 ctl; + + spin_lock_irqsave(&cgu->lock, flags); + ctl = readl(cgu->base + pll_info->reg); + + ctl &= ~BIT(pll_info->enable_bit); + + writel(ctl, cgu->base + pll_info->reg); + spin_unlock_irqrestore(&cgu->lock, flags); +} + +static int ingenic_pll_is_enabled(struct clk_hw *hw) +{ + struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); + struct ingenic_cgu *cgu = ingenic_clk->cgu; + const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); + const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; + unsigned long flags; + u32 ctl; + + spin_lock_irqsave(&cgu->lock, flags); + ctl = readl(cgu->base + pll_info->reg); + spin_unlock_irqrestore(&cgu->lock, flags); + + return !!(ctl & BIT(pll_info->enable_bit)); +} + static const struct clk_ops ingenic_pll_ops = { .recalc_rate = ingenic_pll_recalc_rate, .round_rate = ingenic_pll_round_rate, .set_rate = ingenic_pll_set_rate, + + .enable = ingenic_pll_enable, + .disable = ingenic_pll_disable, + .is_enabled = ingenic_pll_is_enabled, }; /* @@ -328,6 +387,8 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) div *= clk_info->div.div; rate /= div; + } else if (clk_info->type & CGU_CLK_FIXDIV) { + rate /= clk_info->fixdiv.div; } return rate; @@ -598,6 +659,7 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx) } } else if (caps & CGU_CLK_PLL) { clk_init.ops = &ingenic_pll_ops; + clk_init.flags |= CLK_SET_RATE_GATE; caps &= ~CGU_CLK_PLL; diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h index e78b586536ea..9da34910bd80 100644 --- a/drivers/clk/ingenic/cgu.h +++ b/drivers/clk/ingenic/cgu.h @@ -48,6 +48,7 @@ * @bypass_bit: the index of the bypass bit in the PLL control register * @enable_bit: the index of the enable bit in the PLL control register * @stable_bit: the index of the stable bit in the PLL control register + * @no_bypass_bit: if set, the PLL has no bypass functionality */ struct ingenic_cgu_pll_info { unsigned reg; @@ -58,6 +59,7 @@ struct ingenic_cgu_pll_info { u8 bypass_bit; u8 enable_bit; u8 stable_bit; + bool no_bypass_bit; }; /** @@ -120,7 +122,7 @@ struct ingenic_cgu_gate_info { * @clk_ops: custom clock operation callbacks */ struct ingenic_cgu_custom_info { - struct clk_ops *clk_ops; + const struct clk_ops *clk_ops; }; /** diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c new file mode 100644 index 000000000000..c78d369b9403 --- /dev/null +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -0,0 +1,483 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * JZ4770 SoC CGU driver + * Copyright 2018, Paul Cercueil <paul@crapouillou.net> + */ + +#include <linux/bitops.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/of.h> +#include <linux/syscore_ops.h> +#include <dt-bindings/clock/jz4770-cgu.h> +#include "cgu.h" + +/* + * CPM registers offset address definition + */ +#define CGU_REG_CPCCR 0x00 +#define CGU_REG_LCR 0x04 +#define CGU_REG_CPPCR0 0x10 +#define CGU_REG_CLKGR0 0x20 +#define CGU_REG_OPCR 0x24 +#define CGU_REG_CLKGR1 0x28 +#define CGU_REG_CPPCR1 0x30 +#define CGU_REG_USBPCR1 0x48 +#define CGU_REG_USBCDR 0x50 +#define CGU_REG_I2SCDR 0x60 +#define CGU_REG_LPCDR 0x64 +#define CGU_REG_MSC0CDR 0x68 +#define CGU_REG_UHCCDR 0x6c +#define CGU_REG_SSICDR 0x74 +#define CGU_REG_CIMCDR 0x7c +#define CGU_REG_GPSCDR 0x80 +#define CGU_REG_PCMCDR 0x84 +#define CGU_REG_GPUCDR 0x88 +#define CGU_REG_MSC1CDR 0xA4 +#define CGU_REG_MSC2CDR 0xA8 +#define CGU_REG_BCHCDR 0xAC + +/* bits within the LCR register */ +#define LCR_LPM BIT(0) /* Low Power Mode */ + +/* bits within the OPCR register */ +#define OPCR_SPENDH BIT(5) /* UHC PHY suspend */ +#define OPCR_SPENDN BIT(7) /* OTG PHY suspend */ + +/* bits within the USBPCR1 register */ +#define USBPCR1_UHC_POWER BIT(5) /* UHC PHY power down */ + +static struct ingenic_cgu *cgu; + +static int jz4770_uhc_phy_enable(struct clk_hw *hw) +{ + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; + void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; + + writel(readl(reg_opcr) & ~OPCR_SPENDH, reg_opcr); + writel(readl(reg_usbpcr1) | USBPCR1_UHC_POWER, reg_usbpcr1); + return 0; +} + +static void jz4770_uhc_phy_disable(struct clk_hw *hw) +{ + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; + void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; + + writel(readl(reg_usbpcr1) & ~USBPCR1_UHC_POWER, reg_usbpcr1); + writel(readl(reg_opcr) | OPCR_SPENDH, reg_opcr); +} + +static int jz4770_uhc_phy_is_enabled(struct clk_hw *hw) +{ + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; + void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; + + return !(readl(reg_opcr) & OPCR_SPENDH) && + (readl(reg_usbpcr1) & USBPCR1_UHC_POWER); +} + +static const struct clk_ops jz4770_uhc_phy_ops = { + .enable = jz4770_uhc_phy_enable, + .disable = jz4770_uhc_phy_disable, + .is_enabled = jz4770_uhc_phy_is_enabled, +}; + +static int jz4770_otg_phy_enable(struct clk_hw *hw) +{ + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; + + writel(readl(reg_opcr) | OPCR_SPENDN, reg_opcr); + + /* Wait for the clock to be stable */ + udelay(50); + return 0; +} + +static void jz4770_otg_phy_disable(struct clk_hw *hw) +{ + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; + + writel(readl(reg_opcr) & ~OPCR_SPENDN, reg_opcr); +} + +static int jz4770_otg_phy_is_enabled(struct clk_hw *hw) +{ + void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; + + return !!(readl(reg_opcr) & OPCR_SPENDN); +} + +static const struct clk_ops jz4770_otg_phy_ops = { + .enable = jz4770_otg_phy_enable, + .disable = jz4770_otg_phy_disable, + .is_enabled = jz4770_otg_phy_is_enabled, +}; + +static const s8 pll_od_encoding[8] = { + 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, +}; + +static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { + + /* External clocks */ + + [JZ4770_CLK_EXT] = { "ext", CGU_CLK_EXT }, + [JZ4770_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT }, + + /* PLLs */ + + [JZ4770_CLK_PLL0] = { + "pll0", CGU_CLK_PLL, + .parents = { JZ4770_CLK_EXT }, + .pll = { + .reg = CGU_REG_CPPCR0, + .m_shift = 24, + .m_bits = 7, + .m_offset = 1, + .n_shift = 18, + .n_bits = 5, + .n_offset = 1, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .bypass_bit = 9, + .enable_bit = 8, + .stable_bit = 10, + }, + }, + + [JZ4770_CLK_PLL1] = { + /* TODO: PLL1 can depend on PLL0 */ + "pll1", CGU_CLK_PLL, + .parents = { JZ4770_CLK_EXT }, + .pll = { + .reg = CGU_REG_CPPCR1, + .m_shift = 24, + .m_bits = 7, + .m_offset = 1, + .n_shift = 18, + .n_bits = 5, + .n_offset = 1, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .enable_bit = 7, + .stable_bit = 6, + .no_bypass_bit = true, + }, + }, + + /* Main clocks */ + + [JZ4770_CLK_CCLK] = { + "cclk", CGU_CLK_DIV, + .parents = { JZ4770_CLK_PLL0, }, + .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, + }, + [JZ4770_CLK_H0CLK] = { + "h0clk", CGU_CLK_DIV, + .parents = { JZ4770_CLK_PLL0, }, + .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, + }, + [JZ4770_CLK_H1CLK] = { + "h1clk", CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { JZ4770_CLK_PLL0, }, + .div = { CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1 }, + .gate = { CGU_REG_LCR, 30 }, + }, + [JZ4770_CLK_H2CLK] = { + "h2clk", CGU_CLK_DIV, + .parents = { JZ4770_CLK_PLL0, }, + .div = { CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1 }, + }, + [JZ4770_CLK_C1CLK] = { + "c1clk", CGU_CLK_DIV, + .parents = { JZ4770_CLK_PLL0, }, + .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 }, + }, + [JZ4770_CLK_PCLK] = { + "pclk", CGU_CLK_DIV, + .parents = { JZ4770_CLK_PLL0, }, + .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 }, + }, + + /* Those divided clocks can connect to PLL0 or PLL1 */ + + [JZ4770_CLK_MMC0_MUX] = { + "mmc0_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_MSC0CDR, 30, 1 }, + .div = { CGU_REG_MSC0CDR, 0, 1, 7, -1, -1, 31 }, + .gate = { CGU_REG_MSC0CDR, 31 }, + }, + [JZ4770_CLK_MMC1_MUX] = { + "mmc1_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_MSC1CDR, 30, 1 }, + .div = { CGU_REG_MSC1CDR, 0, 1, 7, -1, -1, 31 }, + .gate = { CGU_REG_MSC1CDR, 31 }, + }, + [JZ4770_CLK_MMC2_MUX] = { + "mmc2_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_MSC2CDR, 30, 1 }, + .div = { CGU_REG_MSC2CDR, 0, 1, 7, -1, -1, 31 }, + .gate = { CGU_REG_MSC2CDR, 31 }, + }, + [JZ4770_CLK_CIM] = { + "cim", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_CIMCDR, 31, 1 }, + .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 26 }, + }, + [JZ4770_CLK_UHC] = { + "uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_UHCCDR, 29, 1 }, + .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 24 }, + }, + [JZ4770_CLK_GPU] = { + "gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, -1 }, + .mux = { CGU_REG_GPUCDR, 31, 1 }, + .div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR1, 9 }, + }, + [JZ4770_CLK_BCH] = { + "bch", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_BCHCDR, 31, 1 }, + .div = { CGU_REG_BCHCDR, 0, 1, 3, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 1 }, + }, + [JZ4770_CLK_LPCLK_MUX] = { + "lpclk", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_LPCDR, 29, 1 }, + .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 28 }, + }, + [JZ4770_CLK_GPS] = { + "gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, + .mux = { CGU_REG_GPSCDR, 31, 1 }, + .div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 22 }, + }, + + /* Those divided clocks can connect to EXT, PLL0 or PLL1 */ + + [JZ4770_CLK_SSI_MUX] = { + "ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX, + .parents = { JZ4770_CLK_EXT, -1, + JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, + .mux = { CGU_REG_SSICDR, 30, 2 }, + .div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1 }, + }, + [JZ4770_CLK_PCM_MUX] = { + "pcm_mux", CGU_CLK_DIV | CGU_CLK_MUX, + .parents = { JZ4770_CLK_EXT, -1, + JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, + .mux = { CGU_REG_PCMCDR, 30, 2 }, + .div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1 }, + }, + [JZ4770_CLK_I2S] = { + "i2s", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_EXT, -1, + JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, + .mux = { CGU_REG_I2SCDR, 30, 2 }, + .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR1, 13 }, + }, + [JZ4770_CLK_OTG] = { + "usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4770_CLK_EXT, -1, + JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, + .mux = { CGU_REG_USBCDR, 30, 2 }, + .div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 2 }, + }, + + /* Gate-only clocks */ + + [JZ4770_CLK_SSI0] = { + "ssi0", CGU_CLK_GATE, + .parents = { JZ4770_CLK_SSI_MUX, }, + .gate = { CGU_REG_CLKGR0, 4 }, + }, + [JZ4770_CLK_SSI1] = { + "ssi1", CGU_CLK_GATE, + .parents = { JZ4770_CLK_SSI_MUX, }, + .gate = { CGU_REG_CLKGR0, 19 }, + }, + [JZ4770_CLK_SSI2] = { + "ssi2", CGU_CLK_GATE, + .parents = { JZ4770_CLK_SSI_MUX, }, + .gate = { CGU_REG_CLKGR0, 20 }, + }, + [JZ4770_CLK_PCM0] = { + "pcm0", CGU_CLK_GATE, + .parents = { JZ4770_CLK_PCM_MUX, }, + .gate = { CGU_REG_CLKGR1, 8 }, + }, + [JZ4770_CLK_PCM1] = { + "pcm1", CGU_CLK_GATE, + .parents = { JZ4770_CLK_PCM_MUX, }, + .gate = { CGU_REG_CLKGR1, 10 }, + }, + [JZ4770_CLK_DMA] = { + "dma", CGU_CLK_GATE, + .parents = { JZ4770_CLK_H2CLK, }, + .gate = { CGU_REG_CLKGR0, 21 }, + }, + [JZ4770_CLK_I2C0] = { + "i2c0", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 5 }, + }, + [JZ4770_CLK_I2C1] = { + "i2c1", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 6 }, + }, + [JZ4770_CLK_I2C2] = { + "i2c2", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR1, 15 }, + }, + [JZ4770_CLK_UART0] = { + "uart0", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 15 }, + }, + [JZ4770_CLK_UART1] = { + "uart1", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 16 }, + }, + [JZ4770_CLK_UART2] = { + "uart2", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 17 }, + }, + [JZ4770_CLK_UART3] = { + "uart3", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 18 }, + }, + [JZ4770_CLK_IPU] = { + "ipu", CGU_CLK_GATE, + .parents = { JZ4770_CLK_H0CLK, }, + .gate = { CGU_REG_CLKGR0, 29 }, + }, + [JZ4770_CLK_ADC] = { + "adc", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 14 }, + }, + [JZ4770_CLK_AIC] = { + "aic", CGU_CLK_GATE, + .parents = { JZ4770_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 8 }, + }, + [JZ4770_CLK_AUX] = { + "aux", CGU_CLK_GATE, + .parents = { JZ4770_CLK_C1CLK, }, + .gate = { CGU_REG_CLKGR1, 14 }, + }, + [JZ4770_CLK_VPU] = { + "vpu", CGU_CLK_GATE, + .parents = { JZ4770_CLK_H1CLK, }, + .gate = { CGU_REG_CLKGR1, 7 }, + }, + [JZ4770_CLK_MMC0] = { + "mmc0", CGU_CLK_GATE, + .parents = { JZ4770_CLK_MMC0_MUX, }, + .gate = { CGU_REG_CLKGR0, 3 }, + }, + [JZ4770_CLK_MMC1] = { + "mmc1", CGU_CLK_GATE, + .parents = { JZ4770_CLK_MMC1_MUX, }, + .gate = { CGU_REG_CLKGR0, 11 }, + }, + [JZ4770_CLK_MMC2] = { + "mmc2", CGU_CLK_GATE, + .parents = { JZ4770_CLK_MMC2_MUX, }, + .gate = { CGU_REG_CLKGR0, 12 }, + }, + + /* Custom clocks */ + + [JZ4770_CLK_UHC_PHY] = { + "uhc_phy", CGU_CLK_CUSTOM, + .parents = { JZ4770_CLK_UHC, -1, -1, -1 }, + .custom = { &jz4770_uhc_phy_ops }, + }, + [JZ4770_CLK_OTG_PHY] = { + "usb_phy", CGU_CLK_CUSTOM, + .parents = { JZ4770_CLK_OTG, -1, -1, -1 }, + .custom = { &jz4770_otg_phy_ops }, + }, + + [JZ4770_CLK_EXT512] = { + "ext/512", CGU_CLK_FIXDIV, + .parents = { JZ4770_CLK_EXT }, + .fixdiv = { 512 }, + }, + + [JZ4770_CLK_RTC] = { + "rtc", CGU_CLK_MUX, + .parents = { JZ4770_CLK_EXT512, JZ4770_CLK_OSC32K, }, + .mux = { CGU_REG_OPCR, 2, 1}, + }, +}; + +#if IS_ENABLED(CONFIG_PM_SLEEP) +static int jz4770_cgu_pm_suspend(void) +{ + u32 val; + + val = readl(cgu->base + CGU_REG_LCR); + writel(val | LCR_LPM, cgu->base + CGU_REG_LCR); + return 0; +} + +static void jz4770_cgu_pm_resume(void) +{ + u32 val; + + val = readl(cgu->base + CGU_REG_LCR); + writel(val & ~LCR_LPM, cgu->base + CGU_REG_LCR); +} + +static struct syscore_ops jz4770_cgu_pm_ops = { + .suspend = jz4770_cgu_pm_suspend, + .resume = jz4770_cgu_pm_resume, +}; +#endif /* CONFIG_PM_SLEEP */ + +static void __init jz4770_cgu_init(struct device_node *np) +{ + int retval; + + cgu = ingenic_cgu_new(jz4770_cgu_clocks, + ARRAY_SIZE(jz4770_cgu_clocks), np); + if (!cgu) + pr_err("%s: failed to initialise CGU\n", __func__); + + retval = ingenic_cgu_register_clocks(cgu); + if (retval) + pr_err("%s: failed to register CGU Clocks\n", __func__); + +#if IS_ENABLED(CONFIG_PM_SLEEP) + register_syscore_ops(&jz4770_cgu_pm_ops); +#endif +} + +/* We only probe via devicetree, no need for a platform driver */ +CLK_OF_DECLARE(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init); diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index ac3585ed8228..6427be117ff1 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -203,7 +203,7 @@ static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, return 0; } -static struct clk_ops jz4780_otg_phy_ops = { +static const struct clk_ops jz4780_otg_phy_ops = { .get_parent = jz4780_otg_phy_get_parent, .set_parent = jz4780_otg_phy_set_parent, diff --git a/include/dt-bindings/clock/jz4770-cgu.h b/include/dt-bindings/clock/jz4770-cgu.h new file mode 100644 index 000000000000..d68a7695a1f8 --- /dev/null +++ b/include/dt-bindings/clock/jz4770-cgu.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This header provides clock numbers for the ingenic,jz4770-cgu DT binding. + */ + +#ifndef __DT_BINDINGS_CLOCK_JZ4770_CGU_H__ +#define __DT_BINDINGS_CLOCK_JZ4770_CGU_H__ + +#define JZ4770_CLK_EXT 0 +#define JZ4770_CLK_OSC32K 1 +#define JZ4770_CLK_PLL0 2 +#define JZ4770_CLK_PLL1 3 +#define JZ4770_CLK_CCLK 4 +#define JZ4770_CLK_H0CLK 5 +#define JZ4770_CLK_H1CLK 6 +#define JZ4770_CLK_H2CLK 7 +#define JZ4770_CLK_C1CLK 8 +#define JZ4770_CLK_PCLK 9 +#define JZ4770_CLK_MMC0_MUX 10 +#define JZ4770_CLK_MMC0 11 +#define JZ4770_CLK_MMC1_MUX 12 +#define JZ4770_CLK_MMC1 13 +#define JZ4770_CLK_MMC2_MUX 14 +#define JZ4770_CLK_MMC2 15 +#define JZ4770_CLK_CIM 16 +#define JZ4770_CLK_UHC 17 +#define JZ4770_CLK_GPU 18 +#define JZ4770_CLK_BCH 19 +#define JZ4770_CLK_LPCLK_MUX 20 +#define JZ4770_CLK_GPS 21 +#define JZ4770_CLK_SSI_MUX 22 +#define JZ4770_CLK_PCM_MUX 23 +#define JZ4770_CLK_I2S 24 +#define JZ4770_CLK_OTG 25 +#define JZ4770_CLK_SSI0 26 +#define JZ4770_CLK_SSI1 27 +#define JZ4770_CLK_SSI2 28 +#define JZ4770_CLK_PCM0 29 +#define JZ4770_CLK_PCM1 30 +#define JZ4770_CLK_DMA 31 +#define JZ4770_CLK_I2C0 32 +#define JZ4770_CLK_I2C1 33 +#define JZ4770_CLK_I2C2 34 +#define JZ4770_CLK_UART0 35 +#define JZ4770_CLK_UART1 36 +#define JZ4770_CLK_UART2 37 +#define JZ4770_CLK_UART3 38 +#define JZ4770_CLK_IPU 39 +#define JZ4770_CLK_ADC 40 +#define JZ4770_CLK_AIC 41 +#define JZ4770_CLK_AUX 42 +#define JZ4770_CLK_VPU 43 +#define JZ4770_CLK_UHC_PHY 44 +#define JZ4770_CLK_OTG_PHY 45 +#define JZ4770_CLK_EXT512 46 +#define JZ4770_CLK_RTC 47 + +#endif /* __DT_BINDINGS_CLOCK_JZ4770_CGU_H__ */ |