提交 85789536 编写于 作者: L Linus Torvalds

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
  ...
......@@ -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.
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......@@ -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
# 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))
// 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";
};
// 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";
};
};
......@@ -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
......
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
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
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......@@ -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
/*
* 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,
};
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
}
......
此差异已折叠。
......@@ -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)
......
......@@ -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
......
......@@ -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)
......
......@@ -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)
......
......@@ -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
};
......
......@@ -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.
*
......
......@@ -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; */
......
......@@ -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;
......
......@@ -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))
......
......@@ -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 =
&current->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) {
......
......@@ -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
......
......@@ -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);
......
......@@ -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,
......
......@@ -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 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
if (!cpu_has_mips_r6 || delay_slot(xcp))
return SIGILL;
cond = likely = 0;
likely = 0;
cond = 0;
fpr = &current->thread.fpu.fpr[MIPSInst_RT(ir)];
bit0 = get_fpr32(fpr, 0) & 0x1;
switch (MIPSInst_RS(ir)) {
......@@ -1220,14 +1229,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
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 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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--; }
......
......@@ -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;
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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;
......
......@@ -20,7 +20,6 @@
*/
#include "ieee754sp.h"
#include "ieee754dp.h"
s64 ieee754sp_tlong(union ieee754sp x)
{
......
......@@ -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,
};
......
......@@ -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);
......
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
......@@ -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;
......
......@@ -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;
};
/**
......
// 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);
......@@ -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,
......
/* 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__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册