Hi,
This RFC patch series adds all the necessary code
to successfully boot Linux on the Realtek RTL8186 SoC.
Boot log with this series applied (+one DT patch that adds partitions) is available here:
https://gist.github.com/yashac3/483decfa8db014edfb055ba5a1f9996e
Network drivers and other misc drivers are not included
in this patch set (they will be sent in the future).
This patch series includes:
- Patch 1: Lexra LX5280 CPU support (MIPS)
- Patches 2-4: DT bindings for hardware supported in patch 5
- Patch 5: RTL8186 SoC support (MIPS code, timer driver, irqchip, device tree)
What's still missing:
1) Upstream toolchain support for the Lexra LX5280 CPU.
(Still WIP) GCC and binutils patches are available at [1][2].
Buildroot with these patches applied is available at [3].
The toolchain work is still WIP and I'm planning to send it
for review when it will be ready.
Still, feel free to comment on this work too.
2) Reading the TLB size from device tree:
(The reason there's no DT bindings for the LX5280 in this series)
As there's no way to get the TLB size from the hardware,
is must be passed in the DT.
Currently in arch/mips, the FDT is not available in the cpu_probe()
stage, where the 'tlbsize' field of the cpu data is set.
Any ideas/suggestions on how to solve that?
This patch series is on top of v4.18 + 5 prerequisite patches that
are in mips-next for 4.20. [4][5].
This patch series is also available at:
https://github.com/yashac3/linux-rtl8186/commits/rtl8186-porting-for-upstream-4.18
Please review.
Thanks,
Yasha
[1] https://github.com/yashac3/gcc/commits/lx5280-gcc-8_2_0
[2] https://github.com/yashac3/binutils-gdb/commits/lx5280-porting-master
[3] https://github.com/yashac3/buildroot/commits/lx5280_master
[4] https://www.linux-mips.org/archives/linux-mips/2018-09/msg00769.html
[5] https://www.linux-mips.org/archives/linux-mips/2018-09/msg00775.html
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: James Hogan <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Jason Cooper <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Daniel Lezcano <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Yasha Cherikovsky (5):
MIPS: Add support for the Lexra LX5280 CPU
dt-binding: timer: Document RTL8186 SoC DT bindings
dt-binding: interrupt-controller: Document RTL8186 SoC DT bindings
dt-binding: mips: Document Realtek SoC DT bindings
MIPS: Add Realtek RTL8186 SoC support
.../interrupt-controller/realtek,rtl8186-intc | 18 ++
.../devicetree/bindings/mips/realtek.txt | 9 +
.../bindings/timer/realtek,rtl8186-timer.txt | 17 ++
arch/mips/Kbuild.platforms | 1 +
arch/mips/Kconfig | 47 +++-
arch/mips/Makefile | 1 +
arch/mips/boot/compressed/uart-16550.c | 5 +
arch/mips/boot/dts/Makefile | 1 +
arch/mips/boot/dts/realtek/Makefile | 4 +
arch/mips/boot/dts/realtek/rtl8186.dtsi | 86 ++++++
.../dts/realtek/rtl8186_edimax_br_6204wg.dts | 45 ++++
arch/mips/configs/rtl8186_defconfig | 112 ++++++++
arch/mips/include/asm/cpu-features.h | 3 +
arch/mips/include/asm/cpu-type.h | 4 +
arch/mips/include/asm/cpu.h | 9 +
arch/mips/include/asm/isadep.h | 3 +-
arch/mips/include/asm/mach-rtl8186/rtl8186.h | 37 +++
arch/mips/include/asm/mipsregs.h | 10 +
arch/mips/include/asm/module.h | 2 +
arch/mips/include/asm/pgtable-32.h | 7 +-
arch/mips/include/asm/pgtable-bits.h | 9 +-
arch/mips/include/asm/pgtable.h | 6 +-
arch/mips/include/asm/stackframe.h | 9 +-
arch/mips/include/asm/traps.h | 2 +
arch/mips/kernel/Makefile | 2 +
arch/mips/kernel/cpu-probe.c | 6 +
arch/mips/kernel/entry.S | 3 +-
arch/mips/kernel/genex.S | 6 +-
arch/mips/kernel/idle.c | 10 +
arch/mips/kernel/process.c | 3 +-
arch/mips/kernel/traps.c | 42 +++
arch/mips/lib/Makefile | 1 +
arch/mips/mm/Makefile | 1 +
arch/mips/mm/c-lx5280.c | 251 ++++++++++++++++++
arch/mips/mm/cache.c | 6 +
arch/mips/mm/fault.c | 4 +
arch/mips/mm/tlbex.c | 1 +
arch/mips/rtl8186/Makefile | 2 +
arch/mips/rtl8186/Platform | 7 +
arch/mips/rtl8186/irq.c | 8 +
arch/mips/rtl8186/prom.c | 15 ++
arch/mips/rtl8186/setup.c | 80 ++++++
arch/mips/rtl8186/time.c | 10 +
drivers/clocksource/Kconfig | 9 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/timer-rtl8186.c | 220 +++++++++++++++
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-rtl8186.c | 107 ++++++++
49 files changed, 1225 insertions(+), 23 deletions(-)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/realtek,rtl8186-intc
create mode 100644 Documentation/devicetree/bindings/mips/realtek.txt
create mode 100644 Documentation/devicetree/bindings/timer/realtek,rtl8186-timer.txt
create mode 100644 arch/mips/boot/dts/realtek/Makefile
create mode 100644 arch/mips/boot/dts/realtek/rtl8186.dtsi
create mode 100644 arch/mips/boot/dts/realtek/rtl8186_edimax_br_6204wg.dts
create mode 100644 arch/mips/configs/rtl8186_defconfig
create mode 100644 arch/mips/include/asm/mach-rtl8186/rtl8186.h
create mode 100644 arch/mips/mm/c-lx5280.c
create mode 100644 arch/mips/rtl8186/Makefile
create mode 100644 arch/mips/rtl8186/Platform
create mode 100644 arch/mips/rtl8186/irq.c
create mode 100644 arch/mips/rtl8186/prom.c
create mode 100644 arch/mips/rtl8186/setup.c
create mode 100644 arch/mips/rtl8186/time.c
create mode 100644 drivers/clocksource/timer-rtl8186.c
create mode 100644 drivers/irqchip/irq-rtl8186.c
--
2.19.0
This patch adds device tree binding doc for the
Realtek RTL8186 SoC timer controller.
Signed-off-by: Yasha Cherikovsky <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Daniel Lezcano <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: James Hogan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
.../bindings/timer/realtek,rtl8186-timer.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/realtek,rtl8186-timer.txt
diff --git a/Documentation/devicetree/bindings/timer/realtek,rtl8186-timer.txt b/Documentation/devicetree/bindings/timer/realtek,rtl8186-timer.txt
new file mode 100644
index 000000000000..eaa6292c16e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/realtek,rtl8186-timer.txt
@@ -0,0 +1,17 @@
+Realtek RTL8186 SoC timer
+
+Required properties:
+
+- compatible : Should be "realtek,rtl8186-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : The interrupt number of the timer.
+- clocks: phandle to the source clock (usually a 22 MHz fixed clock)
+
+Example:
+
+timer {
+ compatible = "realtek,rtl8186-timer";
+ reg = <0x1d010050 0x30>;
+ interrupts = <0>;
+ clocks = <&sysclk>;
+};
--
2.19.0
The Realtek RTL8186 SoC is a MIPS based SoC
used in some home routers [1][2].
The hardware includes Lexra LX5280 CPU with a TLB,
two Ethernet controllers, a WLAN controller and more.
With this patch, it is possible to successfully boot
the kernel and load userspace on the Edimax BR-6204Wg
router.
Network drivers support will come in future patches.
This patch includes:
- New MIPS rtl8186 platform
- Core platform setup code (mostly DT based)
- New Kconfig option
- defconfig file
- MIPS zboot UART support
- RTL8186 interrupt controller driver
- RTL8186 timer driver
- Device tree files for the RTL8186 SoC and Edimax BR-6204Wg
router
[1] https://www.linux-mips.org/wiki/Realtek_SOC#Realtek_RTL8186
[2] https://wikidevi.com/wiki/Realtek_RTL8186
Signed-off-by: Yasha Cherikovsky <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: James Hogan <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Jason Cooper <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Daniel Lezcano <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
arch/mips/Kbuild.platforms | 1 +
arch/mips/Kconfig | 17 ++
arch/mips/boot/compressed/uart-16550.c | 5 +
arch/mips/boot/dts/Makefile | 1 +
arch/mips/boot/dts/realtek/Makefile | 4 +
arch/mips/boot/dts/realtek/rtl8186.dtsi | 86 +++++++
.../dts/realtek/rtl8186_edimax_br_6204wg.dts | 45 ++++
arch/mips/configs/rtl8186_defconfig | 112 +++++++++
arch/mips/include/asm/mach-rtl8186/rtl8186.h | 37 +++
arch/mips/rtl8186/Makefile | 2 +
arch/mips/rtl8186/Platform | 7 +
arch/mips/rtl8186/irq.c | 8 +
arch/mips/rtl8186/prom.c | 15 ++
arch/mips/rtl8186/setup.c | 80 +++++++
arch/mips/rtl8186/time.c | 10 +
drivers/clocksource/Kconfig | 9 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/timer-rtl8186.c | 220 ++++++++++++++++++
drivers/irqchip/Kconfig | 5 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-rtl8186.c | 107 +++++++++
21 files changed, 773 insertions(+)
create mode 100644 arch/mips/boot/dts/realtek/Makefile
create mode 100644 arch/mips/boot/dts/realtek/rtl8186.dtsi
create mode 100644 arch/mips/boot/dts/realtek/rtl8186_edimax_br_6204wg.dts
create mode 100644 arch/mips/configs/rtl8186_defconfig
create mode 100644 arch/mips/include/asm/mach-rtl8186/rtl8186.h
create mode 100644 arch/mips/rtl8186/Makefile
create mode 100644 arch/mips/rtl8186/Platform
create mode 100644 arch/mips/rtl8186/irq.c
create mode 100644 arch/mips/rtl8186/prom.c
create mode 100644 arch/mips/rtl8186/setup.c
create mode 100644 arch/mips/rtl8186/time.c
create mode 100644 drivers/clocksource/timer-rtl8186.c
create mode 100644 drivers/irqchip/irq-rtl8186.c
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index ac7ad54f984f..2793741f05e5 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -27,6 +27,7 @@ platforms += pmcs-msp71xx
platforms += pnx833x
platforms += ralink
platforms += rb532
+platforms += rtl8186
platforms += sgi-ip22
platforms += sgi-ip27
platforms += sgi-ip32
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index bbeabd6b0a80..2f2ef09a1961 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -344,6 +344,23 @@ config MACH_DECSTATION
otherwise choose R3000.
+config MACH_RTL8186
+ bool "Realtek RTL8186 SoC"
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_HAS_CPU_LX5280
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_ZBOOT_UART16550
+ select SYS_HAS_EARLY_PRINTK
+ select USE_GENERIC_EARLY_PRINTK_8250
+ select USE_OF
+ select COMMON_CLK
+ select RTL8186_IRQ
+ select RTL8186_TIMER
+ select BUILTIN_DTB
+ help
+ Realtek RTL8186 SoC support.
+
config MACH_JAZZ
bool "Jazz family of machines"
select ARCH_MIGHT_HAVE_PC_PARPORT
diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c
index aee8d7b8f091..99314df48718 100644
--- a/arch/mips/boot/compressed/uart-16550.c
+++ b/arch/mips/boot/compressed/uart-16550.c
@@ -35,6 +35,11 @@
#define IOTYPE unsigned int
#endif
+#ifdef CONFIG_MACH_RTL8186
+#define UART0_BASE 0xbd0100c3
+#define PORT(offset) (UART0_BASE + (4 * offset))
+#endif
+
#ifndef IOTYPE
#define IOTYPE char
#endif
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index 1e79cab8e269..50dc192bbde5 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -11,6 +11,7 @@ subdir-y += ni
subdir-y += pic32
subdir-y += qca
subdir-y += ralink
+subdir-y += realtek
subdir-y += xilfpga
obj-$(CONFIG_BUILTIN_DTB) := $(addsuffix /, $(subdir-y))
diff --git a/arch/mips/boot/dts/realtek/Makefile b/arch/mips/boot/dts/realtek/Makefile
new file mode 100644
index 000000000000..654c3a8da574
--- /dev/null
+++ b/arch/mips/boot/dts/realtek/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_MACH_RTL8186) += rtl8186_edimax_br_6204wg.dtb
+
+obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
diff --git a/arch/mips/boot/dts/realtek/rtl8186.dtsi b/arch/mips/boot/dts/realtek/rtl8186.dtsi
new file mode 100644
index 000000000000..d172999a42a6
--- /dev/null
+++ b/arch/mips/boot/dts/realtek/rtl8186.dtsi
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "realtek,rtl8186-soc";
+
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "lexra,lx5280";
+ reg = <0>;
+ clocks = <&cpu_clk>;
+ d-cache-size = <8192>;
+ i-cache-size = <8192>;
+ d-cache-line-size = <16>;
+ i-cache-line-size = <16>;
+ tlb-entries = <16>;
+ };
+ };
+
+ cpu_clk: cpu_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>; /* Stub. Varies with boards */
+ };
+
+ sysclk: sysclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <22000000>; /* 22MHz */
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x1d010000 0x1000>;
+
+ intc: interrupt-controller@1d010000 {
+ compatible = "realtek,rtl8186-intc";
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ reg = <0x0 0x8>;
+ };
+
+ timer {
+ compatible = "realtek,rtl8186-timer";
+ interrupts = <0>;
+ clocks = <&sysclk>;
+
+ reg = <0x50 0x30>;
+ };
+
+ uart0: serial@1d0100c3 {
+ compatible = "ns16550a";
+ reg = <0xc3 0x20>;
+ reg-io-width = <1>;
+ reg-shift = <2>;
+ interrupts = <3>;
+ clocks = <&cpu_clk>;
+ fifo-size = <16>;
+
+ status = "disabled";
+ };
+
+ uart1: serial@1d0100e3 {
+ compatible = "ns16550a";
+ reg = <0xe3 0x20>;
+ reg-io-width = <1>;
+ reg-shift = <2>;
+ interrupts = <3>;
+ clocks = <&cpu_clk>;
+ fifo-size = <16>;
+
+ status = "disabled";
+ };
+ };
+};
+
diff --git a/arch/mips/boot/dts/realtek/rtl8186_edimax_br_6204wg.dts b/arch/mips/boot/dts/realtek/rtl8186_edimax_br_6204wg.dts
new file mode 100644
index 000000000000..c28edb83de4e
--- /dev/null
+++ b/arch/mips/boot/dts/realtek/rtl8186_edimax_br_6204wg.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+/include/ "rtl8186.dtsi"
+
+/ {
+ compatible = "edimax,br-6204wg", "realtek,rtl8186-soc";
+ model = "Edimax BR-6204Wg";
+
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x00000000 0x01000000>; /* 16MB */
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,38400n8";
+ };
+
+ flash0: flash@1e000000 {
+ compatible = "cfi-flash";
+ reg = <0x1e000000 0x200000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+
+ partition@0 {
+ label = "bootloader+defaults";
+ reg = <0x0 0x8000>;
+ read-only;
+ };
+ partition@8000 {
+ label = "settings";
+ reg = <0x8000 0x8000>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&cpu_clk {
+ clock-frequency = <180000000>; /* 180MHz */
+};
diff --git a/arch/mips/configs/rtl8186_defconfig b/arch/mips/configs/rtl8186_defconfig
new file mode 100644
index 000000000000..03be44de770d
--- /dev/null
+++ b/arch/mips/configs/rtl8186_defconfig
@@ -0,0 +1,112 @@
+CONFIG_MACH_RTL8186=y
+CONFIG_HZ_100=y
+CONFIG_MIPS_ELF_APPENDED_DTB=y
+CONFIG_KERNEL_XZ=y
+# CONFIG_SWAP is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_SGETMASK_SYSCALL is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_SHMEM is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_STACKPROTECTOR_STRONG is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_NET_FOU=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+# CONFIG_NETFILTER_INGRESS is not set
+CONFIG_NF_CONNTRACK=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
+# CONFIG_NF_CT_PROTO_DCCP is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_SYNPROXY=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FQ_CODEL=y
+CONFIG_NET_SCH_DEFAULT=y
+CONFIG_DEFAULT_FQ_CODEL=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK_RO=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CORE is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+# CONFIG_SQUASHFS_ZLIB is not set
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_DEBUG_INFO_SPLIT=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_PANIC_TIMEOUT=10
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+# CONFIG_CRYPTO_ECHAINIV is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_ARM is not set
+# CONFIG_XZ_DEC_ARMTHUMB is not set
+# CONFIG_XZ_DEC_SPARC is not set
diff --git a/arch/mips/include/asm/mach-rtl8186/rtl8186.h b/arch/mips/include/asm/mach-rtl8186/rtl8186.h
new file mode 100644
index 000000000000..d699b25c7854
--- /dev/null
+++ b/arch/mips/include/asm/mach-rtl8186/rtl8186.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_RTL8186_H
+#define __ASM_RTL8186_H
+
+#include <linux/compiler.h>
+
+#define RTL8186_REG_BASE ((void __iomem *)0xbd010000)
+#define RTL8186_REGISTER(offset) (RTL8186_REG_BASE + offset)
+
+/* Watchdog registers */
+#define RTL8186_CDBR RTL8186_REGISTER(0x58)
+#define RTL8186_WDTCNR RTL8186_REGISTER(0x5C)
+
+/* UART addresses */
+#define RTL8186_UART0_BASE RTL8186_REGISTER(0xC3)
+#define RTL8186_UART1_BASE RTL8186_REGISTER(0xE3)
+
+/* GPIO registers */
+#define RTL8186_GPABDATA RTL8186_REGISTER(0x120)
+#define RTL8186_GPABDIR RTL8186_REGISTER(0x124)
+#define RTL8186_GPABIMR RTL8186_REGISTER(0x128)
+#define RTL8186_GPABISR RTL8186_REGISTER(0x12C)
+#define RTL8186_GPCDDATA RTL8186_REGISTER(0x130)
+#define RTL8186_GPCDDIR RTL8186_REGISTER(0x134)
+#define RTL8186_GPCDIMR RTL8186_REGISTER(0x138)
+#define RTL8186_GPCDISR RTL8186_REGISTER(0x13C)
+#define RTL8186_GPEFDATA RTL8186_REGISTER(0x140)
+#define RTL8186_GPEFDIR RTL8186_REGISTER(0x144)
+#define RTL8186_GPEFIMR RTL8186_REGISTER(0x148)
+#define RTL8186_GPEFISR RTL8186_REGISTER(0x14C)
+#define RTL8186_GPGDATA RTL8186_REGISTER(0x150)
+#define RTL8186_GPGDIR RTL8186_REGISTER(0x154)
+#define RTL8186_GPGIMR RTL8186_REGISTER(0x158)
+#define RTL8186_GPGISR RTL8186_REGISTER(0x15C)
+
+
+#endif /* __ASM_RTL8186_H */
diff --git a/arch/mips/rtl8186/Makefile b/arch/mips/rtl8186/Makefile
new file mode 100644
index 000000000000..010f38349aa6
--- /dev/null
+++ b/arch/mips/rtl8186/Makefile
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+obj-y := prom.o setup.o irq.o time.o
diff --git a/arch/mips/rtl8186/Platform b/arch/mips/rtl8186/Platform
new file mode 100644
index 000000000000..5c23cfbffc62
--- /dev/null
+++ b/arch/mips/rtl8186/Platform
@@ -0,0 +1,7 @@
+#
+# RTL8186
+#
+platform-$(CONFIG_MACH_RTL8186) += rtl8186/
+cflags-$(CONFIG_MACH_RTL8186) += -I$(srctree)/arch/mips/include/asm/mach-rtl8186
+load-$(CONFIG_MACH_RTL8186) += 0xffffffff80010000
+zload-$(CONFIG_MACH_RTL8186) += 0xffffffff80800000
diff --git a/arch/mips/rtl8186/irq.c b/arch/mips/rtl8186/irq.c
new file mode 100644
index 000000000000..f158bfe25bca
--- /dev/null
+++ b/arch/mips/rtl8186/irq.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+#include <linux/irqchip.h>
+
+void __init arch_init_irq(void)
+{
+ irqchip_init();
+}
diff --git a/arch/mips/rtl8186/prom.c b/arch/mips/rtl8186/prom.c
new file mode 100644
index 000000000000..0ec7979a23f9
--- /dev/null
+++ b/arch/mips/rtl8186/prom.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/mach-rtl8186/rtl8186.h>
+
+void __init prom_init(void)
+{
+ setup_8250_early_printk_port((unsigned long)RTL8186_UART0_BASE, 2,
+ 10000);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/rtl8186/setup.c b/arch/mips/rtl8186/setup.c
new file mode 100644
index 000000000000..ac3a0e982493
--- /dev/null
+++ b/arch/mips/rtl8186/setup.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
+
+#include <asm/reboot.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/bootinfo.h>
+
+#include <asm/mach-rtl8186/rtl8186.h>
+
+const char *get_system_type(void)
+{
+ return "Realtek RTL8186";
+}
+
+void rtl8186_machine_restart(char *command)
+{
+ /* Disable all interrupts */
+ local_irq_disable();
+
+ /* Use watchdog to reset the system */
+ writel(0x10, RTL8186_CDBR);
+ writel(0x00, RTL8186_WDTCNR);
+
+ for (;;)
+ ;
+}
+
+#define GPIO_A2 BIT(2)
+#define GPIO_A3 BIT(3)
+#define GPIO_A7 BIT(7)
+#define GPIO_A8 BIT(8)
+
+/* Temporary hack until rtl8186-gpio driver is implemented */
+void __init rtl8186_edimax_br6204wg_setup_leds(void)
+{
+ unsigned int gpabdir, gpabdata;
+
+ gpabdir = readl(RTL8186_GPABDIR);
+ gpabdata = readl(RTL8186_GPABDATA);
+
+ writel(gpabdir | (GPIO_A2 | GPIO_A3), RTL8186_GPABDIR);
+
+ gpabdata &= ~GPIO_A2; /* Turn on A2 - green PWR */
+ gpabdata |= GPIO_A3; /* Turn off A3 - orange WLAN */
+ writel(gpabdata, RTL8186_GPABDATA);
+}
+
+void __init *plat_get_fdt(void)
+{
+ if (fw_passed_dtb)
+ return (void *)fw_passed_dtb;
+
+ return NULL;
+}
+
+void __init plat_mem_setup(void)
+{
+ void *dtb;
+
+ _machine_restart = rtl8186_machine_restart;
+
+ dtb = plat_get_fdt();
+ if (!dtb)
+ panic("no dtb found");
+
+ __dt_setup_arch(dtb);
+}
+
+void __init device_tree_init(void)
+{
+ unflatten_and_copy_device_tree();
+
+ if (of_machine_is_compatible("edimax,br-6204wg"))
+ rtl8186_edimax_br6204wg_setup_leds();
+}
diff --git a/arch/mips/rtl8186/time.c b/arch/mips/rtl8186/time.c
new file mode 100644
index 000000000000..78062b588bb3
--- /dev/null
+++ b/arch/mips/rtl8186/time.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+#include <linux/clocksource.h>
+#include <linux/of_clk.h>
+
+void __init plat_time_init(void)
+{
+ of_clk_init(NULL);
+ timer_probe();
+}
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index dec0dd88ec15..da87f73d0631 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -609,4 +609,13 @@ config ATCPIT100_TIMER
help
This option enables support for the Andestech ATCPIT100 timers.
+config RTL8186_TIMER
+ bool "RTL8186 timer driver"
+ depends on MACH_RTL8186
+ depends on COMMON_CLK
+ select TIMER_OF
+ select CLKSRC_MMIO
+ help
+ Enables support for the RTL8186 timer driver.
+
endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 00caf37e52f9..734e8566e1b6 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -78,3 +78,4 @@ obj-$(CONFIG_H8300_TPU) += h8300_tpu.o
obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
obj-$(CONFIG_ATCPIT100_TIMER) += timer-atcpit100.o
+obj-$(CONFIG_RTL8186_TIMER) += timer-rtl8186.o
diff --git a/drivers/clocksource/timer-rtl8186.c b/drivers/clocksource/timer-rtl8186.c
new file mode 100644
index 000000000000..47ef4b09ad27
--- /dev/null
+++ b/drivers/clocksource/timer-rtl8186.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Realtek RTL8186 SoC timer driver.
+ *
+ * Timer0 (24bit): Unused
+ * Timer1 (24bit): Unused
+ * Timer2 (32bit): Used as clocksource
+ * Timer3 (32bit): Used as clock event device
+ *
+ * Copyright (C) 2018 Yasha Cherikovsky
+ */
+
+#include <linux/init.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/sched_clock.h>
+#include <linux/of_clk.h>
+#include <linux/io.h>
+
+#include <asm/time.h>
+#include <asm/idle.h>
+
+#include "timer-of.h"
+
+/* Timer registers */
+#define TCCNR 0x0
+#define TCIR 0x4
+#define TC_DATA(t) (0x10 + 4 * (t))
+#define TC_CNT(t) (0x20 + 4 * (t))
+
+/* TCCNR register bits */
+#define TCCNR_TC_EN_BIT(t) BIT((t) * 2)
+#define TCCNR_TC_MODE_BIT(t) BIT((t) * 2 + 1)
+#define TCCNR_TC_SRC_BIT(t) BIT((t) + 8)
+
+/* TCIR register bits */
+#define TCIR_TC_IE_BIT(t) BIT(t)
+#define TCIR_TC_IP_BIT(t) BIT((t) + 4)
+
+
+/* Forward declaration */
+static struct timer_of to;
+
+static void __iomem *base;
+
+
+#define RTL8186_TIMER_MODE_COUNTER 0
+#define RTL8186_TIMER_MODE_TIMER 1
+
+static void rtl8186_set_enable_bit(int timer, int enabled)
+{
+ u16 tccnr;
+
+ tccnr = readl(base + TCCNR);
+ tccnr &= ~(TCCNR_TC_EN_BIT(timer));
+
+ if (enabled)
+ tccnr |= TCCNR_TC_EN_BIT(timer);
+
+ writel(tccnr, base + TCCNR);
+}
+
+static void rtl8186_set_mode_bit(int timer, int mode)
+{
+ u16 tccnr;
+
+ tccnr = readl(base + TCCNR);
+ tccnr &= ~(TCCNR_TC_MODE_BIT(timer));
+
+ if (mode)
+ tccnr |= TCCNR_TC_MODE_BIT(timer);
+
+ writel(tccnr, base + TCCNR);
+}
+
+
+static irqreturn_t rtl8186_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = dev_id;
+ int status;
+
+ status = readl(base + TCIR);
+ writel(status, base + TCIR); /* Clear all interrupts */
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static int rtl8186_clockevent_set_next(unsigned long evt,
+ struct clock_event_device *cd)
+{
+ rtl8186_set_enable_bit(3, 0);
+ writel(evt, base + TC_DATA(3));
+ writel(evt, base + TC_CNT(3));
+ rtl8186_set_enable_bit(3, 1);
+ return 0;
+}
+
+static int rtl8186_set_state_periodic(struct clock_event_device *cd)
+{
+ unsigned long period = timer_of_period(to_timer_of(cd));
+
+ rtl8186_set_enable_bit(3, 0);
+ rtl8186_set_mode_bit(3, RTL8186_TIMER_MODE_TIMER);
+
+ /* This timer should reach zero each jiffy */
+ writel(period, base + TC_DATA(3));
+ writel(period, base + TC_CNT(3));
+
+ rtl8186_set_enable_bit(3, 1);
+ return 0;
+}
+
+static int rtl8186_set_state_oneshot(struct clock_event_device *cd)
+{
+ rtl8186_set_enable_bit(3, 0);
+ rtl8186_set_mode_bit(3, RTL8186_TIMER_MODE_COUNTER);
+ return 0;
+}
+
+static int rtl8186_set_state_shutdown(struct clock_event_device *cd)
+{
+ rtl8186_set_enable_bit(3, 0);
+ return 0;
+}
+
+static void rtl8186_timer_init_hw(void)
+{
+ /* Disable all timers */
+ writel(0, base + TCCNR);
+
+ /* Clear and disable all timer interrupts */
+ writel(0xf0, base + TCIR);
+
+ /* Reset all timers timeouts */
+ writel(0, base + TC_DATA(0));
+ writel(0, base + TC_DATA(1));
+ writel(0, base + TC_DATA(2));
+ writel(0, base + TC_DATA(3));
+
+ /* Reset all counters */
+ writel(0, base + TC_CNT(0));
+ writel(0, base + TC_CNT(1));
+ writel(0, base + TC_CNT(2));
+ writel(0, base + TC_CNT(3));
+}
+
+static u64 notrace rtl8186_timer_sched_read(void)
+{
+ return ~readl(base + TC_CNT(2));
+}
+
+static int rtl8186_start_clksrc(void)
+{
+ /* We use Timer2 as a clocksource (monotonic counter). */
+ writel(0xFFFFFFFF, base + TC_DATA(2));
+ writel(0xFFFFFFFF, base + TC_CNT(2));
+
+ rtl8186_set_mode_bit(2, RTL8186_TIMER_MODE_TIMER);
+ rtl8186_set_enable_bit(2, 1);
+
+ sched_clock_register(rtl8186_timer_sched_read, 32, timer_of_rate(&to));
+
+ return clocksource_mmio_init(base + TC_CNT(2), "rtl8186-clksrc",
+ timer_of_rate(&to), 500, 32,
+ clocksource_mmio_readl_down);
+}
+
+static struct timer_of to = {
+ .flags = TIMER_OF_BASE | TIMER_OF_CLOCK | TIMER_OF_IRQ,
+
+ .clkevt = {
+ .name = "rtl8186_tick",
+ .rating = 200,
+ .features = CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_PERIODIC,
+ .set_next_event = rtl8186_clockevent_set_next,
+ .cpumask = cpu_possible_mask,
+ .set_state_periodic = rtl8186_set_state_periodic,
+ .set_state_oneshot = rtl8186_set_state_oneshot,
+ .set_state_shutdown = rtl8186_set_state_shutdown,
+ },
+
+ .of_irq = {
+ .handler = rtl8186_timer_interrupt,
+ .flags = IRQF_TIMER,
+ },
+};
+
+static int __init rtl8186_timer_init(struct device_node *node)
+{
+ int ret;
+
+ ret = timer_of_init(node, &to);
+ if (ret)
+ return ret;
+
+ base = timer_of_base(&to);
+
+ rtl8186_timer_init_hw();
+
+ ret = rtl8186_start_clksrc();
+ if (ret) {
+ pr_err("Failed to register clocksource\n");
+ return ret;
+ }
+
+ clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), 100,
+ 0xffffffff);
+
+ /* Enable interrupts for Timer3. Disable interrupts for others */
+ writel(TCIR_TC_IE_BIT(3), base + TCIR);
+
+ return 0;
+}
+
+TIMER_OF_DECLARE(rtl8186_timer, "realtek,rtl8186-timer", rtl8186_timer_init);
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index e9233db16e03..83099905a871 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -371,4 +371,9 @@ config QCOM_PDC
Power Domain Controller driver to manage and configure wakeup
IRQs for Qualcomm Technologies Inc (QTI) mobile chips.
+config RTL8186_IRQ
+ bool
+ depends on MACH_RTL8186
+ select IRQ_DOMAIN
+
endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 15f268f646bf..2e0bb859a8f4 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -87,3 +87,4 @@ obj-$(CONFIG_MESON_IRQ_GPIO) += irq-meson-gpio.o
obj-$(CONFIG_GOLDFISH_PIC) += irq-goldfish-pic.o
obj-$(CONFIG_NDS32) += irq-ativic32.o
obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o
+obj-$(CONFIG_RTL8186_IRQ) += irq-rtl8186.o
diff --git a/drivers/irqchip/irq-rtl8186.c b/drivers/irqchip/irq-rtl8186.c
new file mode 100644
index 000000000000..3eb6b947d5a0
--- /dev/null
+++ b/drivers/irqchip/irq-rtl8186.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Realtek RTL8186 SoC interrupt controller driver.
+ *
+ * Copyright (C) 2018 Yasha Cherikovsky
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define RTL8186_NR_IRQS 11
+
+#define GIMR 0x00
+#define GISR 0x04
+
+static struct {
+ void __iomem *base;
+ struct irq_domain *domain;
+} intc;
+
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ u32 hwirq, virq;
+ u32 gimr = readl(intc.base + GIMR);
+ u32 gisr = readl(intc.base + GISR);
+ u32 pending = gimr & gisr & ((1 << RTL8186_NR_IRQS) - 1);
+
+ if (!pending) {
+ spurious_interrupt();
+ return;
+ }
+
+ while (pending) {
+ hwirq = fls(pending) - 1;
+ virq = irq_linear_revmap(intc.domain, hwirq);
+ do_IRQ(virq);
+ pending &= ~BIT(hwirq);
+ }
+}
+
+static void rtl8186_irq_mask(struct irq_data *data)
+{
+ unsigned long irq = data->hwirq;
+
+ writel(readl(intc.base + GIMR) & (~(BIT(irq))), intc.base + GIMR);
+}
+
+static void rtl8186_irq_unmask(struct irq_data *data)
+{
+ unsigned long irq = data->hwirq;
+
+ writel((readl(intc.base + GIMR) | (BIT(irq))), intc.base + GIMR);
+}
+
+static struct irq_chip rtl8186_irq_chip = {
+ .name = "RTL8186",
+ .irq_mask = rtl8186_irq_mask,
+ .irq_unmask = rtl8186_irq_unmask,
+};
+
+static int rtl8186_intc_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(virq, &rtl8186_irq_chip, handle_level_irq);
+ return 0;
+}
+
+static const struct irq_domain_ops rtl8186_irq_ops = {
+ .map = rtl8186_intc_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static int __init rtl8186_intc_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ intc.base = of_io_request_and_map(node, 0, of_node_full_name(node));
+
+ if (IS_ERR(intc.base))
+ panic("%pOF: unable to map resource", node);
+
+ intc.domain = irq_domain_add_linear(node, RTL8186_NR_IRQS,
+ &rtl8186_irq_ops, NULL);
+
+ if (!intc.domain)
+ panic("%pOF: unable to create IRQ domain\n", node);
+
+ /* Start with all interrupts disabled */
+ writel(0, intc.base + GIMR);
+
+ /*
+ * Enable all hardware interrupts in CP0 status register.
+ * Software interrupts are disabled.
+ */
+ set_c0_status(ST0_IM);
+ clear_c0_status(STATUSF_IP0 | STATUSF_IP1);
+ clear_c0_cause(CAUSEF_IP);
+
+ return 0;
+}
+
+IRQCHIP_DECLARE(rtl8186_intc, "realtek,rtl8186-intc", rtl8186_intc_of_init);
--
2.19.0
This patch adds device tree binding doc for Realtek MIPS SoCs.
It includes a compatible string for the Realtek RTL8186 SoC.
Signed-off-by: Yasha Cherikovsky <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: James Hogan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
Documentation/devicetree/bindings/mips/realtek.txt | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mips/realtek.txt
diff --git a/Documentation/devicetree/bindings/mips/realtek.txt b/Documentation/devicetree/bindings/mips/realtek.txt
new file mode 100644
index 000000000000..09d19758168a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/realtek.txt
@@ -0,0 +1,9 @@
+Realtek MIPS SoC device tree bindings
+
+1. SoCs
+
+Each device tree must specify a compatible value for the Realtek SoC
+it uses in the compatible property of the root node. The compatible
+value must be one of the following values:
+
+ realtek,rtl8186-soc
--
2.19.0
This patch adds device tree binding doc for the
Realtek RTL8186 SoC interrupt controller.
Signed-off-by: Yasha Cherikovsky <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Jason Cooper <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: James Hogan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
.../interrupt-controller/realtek,rtl8186-intc | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/realtek,rtl8186-intc
diff --git a/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl8186-intc b/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl8186-intc
new file mode 100644
index 000000000000..21956d210021
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/realtek,rtl8186-intc
@@ -0,0 +1,18 @@
+Realtek RTL8186 SoC interrupt controller
+
+Required properties:
+
+- compatible : should be "realtek,rtl8186-intc"
+- interrupt-controller : Identifies the node as an interrupt controller.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source. The value shall be 1.
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+intc: interrupt-controller@1d010000 {
+ compatible = "realtek,rtl8186-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x1d010000 0x8>;
+};
--
2.19.0
The Lexra LX5280 CPU [1][2] implements the MIPS-I ISA,
without unaligned load/store instructions (lwl, lwr, swl, swr).
The programming model of this CPU is very similar
to the R3000 programming model, with a few differences.
The Realtek RTL8186 SoC has this CPU, so this patch is required
for future RTL8186 SoC support.
The LX5280 CPU has no documented TLB unit (only SMMU, a simple MMU unit
which is not enough for usual Linux).
However, the RTL8186 SoC does include a TLB unit with the CPU
(programmed like R3000 TLB).
So this patch adds support *only* for LX5280s that have a TLB unit.
This patch includes:
- Adding Kconfig entries for LX5280
- Adding CPU_LX5280 to the cpu_type_enum
- Passing -march=lx5280 to the compiler
- Using existing R3000 code/behavior where possible
- Wait instruction support (for better idle power consuption)
- RDHWR instruction emulation from the page fault handler
(more details in a code comment)
[1] https://www.linux-mips.org/wiki/Lexra
[2] https://wikidevi.com/wiki/Lexra_LX5280
Signed-off-by: Yasha Cherikovsky <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: James Hogan <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
arch/mips/Kconfig | 30 +++-
arch/mips/Makefile | 1 +
arch/mips/include/asm/cpu-features.h | 3 +
arch/mips/include/asm/cpu-type.h | 4 +
arch/mips/include/asm/cpu.h | 9 +
arch/mips/include/asm/isadep.h | 3 +-
arch/mips/include/asm/mipsregs.h | 10 ++
arch/mips/include/asm/module.h | 2 +
arch/mips/include/asm/pgtable-32.h | 7 +-
arch/mips/include/asm/pgtable-bits.h | 9 +-
arch/mips/include/asm/pgtable.h | 6 +-
arch/mips/include/asm/stackframe.h | 9 +-
arch/mips/include/asm/traps.h | 2 +
arch/mips/kernel/Makefile | 2 +
arch/mips/kernel/cpu-probe.c | 6 +
arch/mips/kernel/entry.S | 3 +-
arch/mips/kernel/genex.S | 6 +-
arch/mips/kernel/idle.c | 10 ++
arch/mips/kernel/process.c | 3 +-
arch/mips/kernel/traps.c | 42 +++++
arch/mips/lib/Makefile | 1 +
arch/mips/mm/Makefile | 1 +
arch/mips/mm/c-lx5280.c | 251 +++++++++++++++++++++++++++
arch/mips/mm/cache.c | 6 +
arch/mips/mm/fault.c | 4 +
arch/mips/mm/tlbex.c | 1 +
26 files changed, 408 insertions(+), 23 deletions(-)
create mode 100644 arch/mips/mm/c-lx5280.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a6b0391996ea..bbeabd6b0a80 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1558,6 +1558,17 @@ config CPU_R3000
might be a safe bet. If the resulting kernel does not work,
try to recompile with R3000.
+config CPU_LX5280
+ bool "LX5280"
+ depends on SYS_HAS_CPU_LX5280
+ select CPU_SUPPORTS_32BIT_KERNEL
+ help
+ Choose this option to build a kernel for the Lexra LX5280 CPU.
+ Lexra LX5280 implements the MIPS-I instruction set, without
+ unaligned load and store instructions (lwl, lwr, swl, swr).
+ Only LX5280 CPUs with a TLB unit are supported.
+
+
config CPU_TX39XX
bool "R39XX"
depends on SYS_HAS_CPU_TX39XX
@@ -1939,6 +1950,9 @@ config SYS_HAS_CPU_R3000
config SYS_HAS_CPU_TX39XX
bool
+config SYS_HAS_CPU_LX5280
+ bool
+
config SYS_HAS_CPU_VR41XX
bool
@@ -2169,7 +2183,7 @@ config PAGE_SIZE_8KB
config PAGE_SIZE_16KB
bool "16kB"
- depends on !CPU_R3000 && !CPU_TX39XX
+ depends on !CPU_R3000 && !CPU_TX39XX && !CPU_LX5280
help
Using 16kB page size will result in higher performance kernel at
the price of higher memory consumption. This option is available on
@@ -2188,7 +2202,7 @@ config PAGE_SIZE_32KB
config PAGE_SIZE_64KB
bool "64kB"
- depends on !CPU_R3000 && !CPU_TX39XX
+ depends on !CPU_R3000 && !CPU_TX39XX && !CPU_LX5280
help
Using 64kB page size will result in higher performance kernel at
the price of higher memory consumption. This option is available on
@@ -2256,15 +2270,15 @@ config CPU_HAS_PREFETCH
config CPU_GENERIC_DUMP_TLB
bool
- default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
+ default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX || CPU_LX5280)
config CPU_R4K_FPU
bool
- default y if !(CPU_R3000 || CPU_TX39XX)
+ default y if !(CPU_R3000 || CPU_TX39XX || CPU_LX5280)
config CPU_R4K_CACHE_TLB
bool
- default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+ default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON || CPU_LX5280)
config MIPS_MT_SMP
bool "MIPS MT SMP support (1 TC on each available VPE)"
@@ -2501,7 +2515,7 @@ config CPU_MIPSR2_IRQ_EI
config CPU_HAS_SYNC
bool
- depends on !CPU_R3000
+ depends on !(CPU_R3000 || CPU_LX5280)
default y
#
@@ -2519,14 +2533,14 @@ config CPU_R4400_WORKAROUNDS
config MIPS_ASID_SHIFT
int
- default 6 if CPU_R3000 || CPU_TX39XX
+ default 6 if CPU_R3000 || CPU_TX39XX || CPU_LX5280
default 4 if CPU_R8000
default 0
config MIPS_ASID_BITS
int
default 0 if MIPS_ASID_BITS_VARIABLE
- default 6 if CPU_R3000 || CPU_TX39XX
+ default 6 if CPU_R3000 || CPU_TX39XX || CPU_LX5280
default 8
config MIPS_ASID_BITS_VARIABLE
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index e2122cca4ae2..293403f38ffe 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -151,6 +151,7 @@ cflags-y += -fno-stack-check
#
cflags-$(CONFIG_CPU_R3000) += -march=r3000
cflags-$(CONFIG_CPU_TX39XX) += -march=r3900
+cflags-$(CONFIG_CPU_LX5280) += -march=lx5280
cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 9cdb4e4ce258..118e0ff4b54a 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -75,6 +75,9 @@
#ifndef cpu_has_octeon_cache
#define cpu_has_octeon_cache 0
#endif
+#ifndef cpu_has_lx5280_cache
+#define cpu_has_lx5280_cache (cpu_data[0].options & MIPS_CPU_LX5280_CACHE)
+#endif
/* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work. */
#ifndef cpu_has_fpu
#define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU)
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h
index a45af3de075d..bd837232196d 100644
--- a/arch/mips/include/asm/cpu-type.h
+++ b/arch/mips/include/asm/cpu-type.h
@@ -105,6 +105,10 @@ static inline int __pure __get_cpu_type(const int cpu_type)
case CPU_TX3927:
#endif
+#ifdef CONFIG_SYS_HAS_CPU_LX5280
+ case CPU_LX5280:
+#endif
+
#ifdef CONFIG_SYS_HAS_CPU_VR41XX
case CPU_VR41XX:
case CPU_VR4111:
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 5b9d02ef4f60..970a263b52d9 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -90,6 +90,7 @@
#define PRID_IMP_R5432 0x5400
#define PRID_IMP_R5500 0x5500
#define PRID_IMP_LOONGSON_64 0x6300 /* Loongson-2/3 */
+#define PRID_IMP_LX5280 0xC600
#define PRID_IMP_UNKNOWN 0xff00
@@ -306,6 +307,11 @@ enum cpu_type_enum {
*/
CPU_TX3912, CPU_TX3922, CPU_TX3927,
+ /*
+ * Lexra processors
+ */
+ CPU_LX5280,
+
/*
* MIPS32 class processors
*/
@@ -420,6 +426,9 @@ enum cpu_type_enum {
MBIT_ULL(55) /* CPU shares FTLB entries with another */
#define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \
MBIT_ULL(56) /* CPU has perf counters implemented per TC (MIPSMT ASE) */
+#define MIPS_CPU_LX5280_CACHE \
+ MBIT_ULL(57)
+
/*
* CPU ASE encodings
diff --git a/arch/mips/include/asm/isadep.h b/arch/mips/include/asm/isadep.h
index d1683202399b..e725bec9a8ab 100644
--- a/arch/mips/include/asm/isadep.h
+++ b/arch/mips/include/asm/isadep.h
@@ -10,7 +10,8 @@
#ifndef __ASM_ISADEP_H
#define __ASM_ISADEP_H
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
/*
* R2000 or R3000
*/
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index ae461d91cd1f..d3d025d08f3d 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -81,6 +81,7 @@
#define CP0_WATCHLO $18
#define CP0_WATCHHI $19
#define CP0_XCONTEXT $20
+#define CP0_LX5280_CCTL $20
#define CP0_FRAMEMASK $21
#define CP0_DIAGNOSTIC $22
#define CP0_DEBUG $23
@@ -562,6 +563,12 @@
#define MIPS_CONF_AT (_ULCAST_(3) << 13)
#define MIPS_CONF_M (_ULCAST_(1) << 31)
+/* Bits specific to the Lexra LX5280 CPU. */
+#define LX5280_CCTL_DINVAL (_ULCAST_(1) << 0)
+#define LX5280_CCTL_IINVAL (_ULCAST_(1) << 1)
+#define LX5280_CCTL_IMEMFILL (_ULCAST_(1) << 4)
+#define LX5280_CCTL_IMEMOFF (_ULCAST_(1) << 5)
+
/*
* Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
*/
@@ -1725,6 +1732,9 @@ do { \
#define read_c0_xcontext() __read_ulong_c0_register($20, 0)
#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val)
+#define read_c0_lx5280_cctl() __read_ulong_c0_register($20, 0)
+#define write_c0_lx5280_cctl(val) __write_ulong_c0_register($20, 0, val)
+
#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20)
#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val)
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index 6dc0b21b8acd..8547620e20b1 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -137,6 +137,8 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "XLR "
#elif defined CONFIG_CPU_XLP
#define MODULE_PROC_FAMILY "XLP "
+#elif defined CONFIG_CPU_LX5280
+#define MODULE_PROC_FAMILY "LX5280 "
#else
#error MODULE_PROC_FAMILY undefined for your processor configuration
#endif
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index 74afe8c76bdd..54000c0dc56e 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -175,7 +175,8 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_unmap(pte) ((void)(pte))
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
/* Swap entries must have VALID bit cleared. */
#define __swp_type(x) (((x).val >> 10) & 0x1f)
@@ -220,6 +221,8 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
-#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */
+#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ * defined(CONFIG_CPU_LX5280)
+ */
#endif /* _ASM_PGTABLE_32_H */
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index f88a48cd68b2..75bb141f308d 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -80,7 +80,8 @@ enum pgtable_bits {
_PAGE_MODIFIED_SHIFT,
};
-#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
/* Page table bits used for r3k systems */
enum pgtable_bits {
@@ -146,7 +147,8 @@ enum pgtable_bits {
#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
# define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT)
# define _CACHE_MASK _CACHE_UNCACHED
# define _PFN_SHIFT PAGE_SHIFT
@@ -204,7 +206,8 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
/*
* Cache attributes
*/
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
#define _CACHE_CACHABLE_NONCOHERENT 0
#define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 129e0328367f..688ac35441ab 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -197,7 +197,8 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
static inline void set_pte(pte_t *ptep, pte_t pteval)
{
*ptep = pteval;
-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
+#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) && \
+ !defined(CONFIG_CPU_LX5280)
if (pte_val(pteval) & _PAGE_GLOBAL) {
pte_t *buddy = ptep_buddy(ptep);
/*
@@ -256,7 +257,8 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
htw_stop();
-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
+#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) && \
+ !defined(CONFIG_CPU_LX5280)
/* Preserve global status for the pair */
if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL));
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index 2161357cc68f..698e635f7afc 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -42,7 +42,8 @@
cfi_restore \reg \offset \docfi
.endm
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
#define STATMASK 0x3f
#else
#define STATMASK 0x1f
@@ -349,7 +350,8 @@
cfi_ld sp, PT_R29, \docfi
.endm
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
.macro RESTORE_SOME docfi=0
.set push
@@ -477,7 +479,8 @@
.macro KMODE
mfc0 t0, CP0_STATUS
li t1, ST0_CU0 | (STATMASK & ~1)
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
andi t2, t0, ST0_IEP
srl t2, 2
or t0, t2
diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h
index f41cf3ee82a7..e611a3d0ac99 100644
--- a/arch/mips/include/asm/traps.h
+++ b/arch/mips/include/asm/traps.h
@@ -39,4 +39,6 @@ extern int register_nmi_notifier(struct notifier_block *nb);
register_nmi_notifier(&fn##_nb); \
})
+int simulate_rdhwr_in_page_fault(struct pt_regs *regs);
+
#endif /* _ASM_TRAPS_H */
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index f10e1e15e1c6..7fe3f3d4d4b4 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -39,12 +39,14 @@ obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
sw-y := r4k_switch.o
sw-$(CONFIG_CPU_R3000) := r2300_switch.o
sw-$(CONFIG_CPU_TX39XX) := r2300_switch.o
+sw-$(CONFIG_CPU_LX5280) := r2300_switch.o
sw-$(CONFIG_CPU_CAVIUM_OCTEON) := octeon_switch.o
obj-y += $(sw-y)
obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o
obj-$(CONFIG_CPU_R3000) += r2300_fpu.o
obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o
+obj-$(CONFIG_CPU_LX5280) += r2300_fpu.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP_UP) += smp-up.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index b2509c19cfb5..d7e39635fbe7 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1516,6 +1516,12 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
break;
}
+ break;
+ case PRID_IMP_LX5280:
+ c->cputype = CPU_LX5280;
+ __cpu_name[cpu] = "Lexra LX5280";
+ c->options = MIPS_CPU_TLB | MIPS_CPU_LX5280_CACHE;
+ c->tlbsize = 16; // TODO Lexra: RTL8186 only. use dt?
break;
}
}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index d7de8adcfcc8..ab4cb33020c5 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -102,7 +102,8 @@ restore_partial: # restore partial frame
SAVE_AT
SAVE_TEMP
LONG_L v0, PT_STATUS(sp)
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
and v0, ST0_IEP
#else
and v0, ST0_IE
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 37b9383eacd3..7d789e20e6ea 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -165,7 +165,8 @@ NESTED(handle_int, PT_SIZE, sp)
.set push
.set noat
mfc0 k0, CP0_STATUS
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
and k0, ST0_IEP
bnez k0, 1f
@@ -584,7 +585,8 @@ isrdhwr:
get_saved_sp /* k1 := current_thread_info */
.set noreorder
MFC0 k0, CP0_EPC
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
ori k1, _THREAD_MASK
xori k1, _THREAD_MASK
LONG_L v1, TI_TP_VALUE(k1)
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
index 7c246b69c545..336d1498a175 100644
--- a/arch/mips/kernel/idle.c
+++ b/arch/mips/kernel/idle.c
@@ -115,6 +115,13 @@ static void au1k_wait(void)
: : "r" (au1k_wait), "r" (c0status));
}
+static void lx5280_wait(void)
+{
+ /* Execute LX5280 'sleep' instruction */
+ asm volatile(".word 0x42000038");
+ local_irq_enable();
+}
+
static int __initdata nowait;
static int __init wait_disable(char *s)
@@ -249,6 +256,9 @@ void __init check_wait(void)
cpu_wait = r4k_wait;
*/
break;
+ case CPU_LX5280:
+ cpu_wait = lx5280_wait;
+ break;
default:
break;
}
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 9670e70139fd..2f92f203dcd0 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -138,7 +138,8 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
p->thread.reg17 = kthread_arg;
p->thread.reg29 = childksp;
p->thread.reg31 = (unsigned long) ret_from_kernel_thread;
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || \
+ defined(CONFIG_CPU_LX5280)
status = (status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) |
((status & (ST0_KUC | ST0_IEC)) << 2);
#else
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 8d505a21396e..dda828c4e955 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -686,6 +686,48 @@ static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned int opcode)
return -1;
}
+/*
+ * When most MIPS CPUs hit 'rdwhr' instruction, they raise a 'reserved
+ * instruction' exception if the instruction is unsupported.
+ * This is not the case with the LX5280 CPU, on which
+ * 'rdhwr' instruction raises a page fault.
+ * So for LX5280, we must do the 'rdhwr' simulation in the
+ * page fault handler.
+ *
+ * Returns 0 on successful simulation.
+ * Register state is not affected on failure.
+ */
+int simulate_rdhwr_in_page_fault(struct pt_regs *regs)
+{
+#ifdef CONFIG_CPU_LX5280
+ unsigned long old_epc = regs->cp0_epc;
+ unsigned long old31 = regs->regs[31];
+ unsigned int opcode = 0;
+ unsigned int __user *epc;
+
+ if (get_isa16_mode(regs->cp0_epc))
+ goto err;
+
+ epc = (unsigned int __user *)exception_epc(regs);
+ if (unlikely(get_user(opcode, epc)))
+ goto err;
+
+ if (unlikely(compute_return_epc(regs) < 0))
+ goto err;
+
+ if (!simulate_rdhwr_normal(regs, opcode))
+ return 0; /* Success */
+
+err:
+ regs->cp0_epc = old_epc; /* Undo skip-over. */
+ regs->regs[31] = old31;
+
+ return -1;
+#else /* !CONFIG_CPU_LX5280 */
+ return -1;
+#endif
+}
+
static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
{
if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) {
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 6537e022ef62..7d44d11ed9bc 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -14,6 +14,7 @@ lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y))
obj-$(CONFIG_CPU_GENERIC_DUMP_TLB) += dump_tlb.o
obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
+obj-$(CONFIG_CPU_LX5280) += r3k_dump_tlb.o
# libgcc-style stuff needed in the kernel
obj-y += bswapsi.o bswapdi.o multi3.o
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index c463bdad45c7..1b3e55c26012 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o
+obj-$(CONFIG_CPU_LX5280) += c-lx5280.o tlb-r3k.o
obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o
obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o
diff --git a/arch/mips/mm/c-lx5280.c b/arch/mips/mm/c-lx5280.c
new file mode 100644
index 000000000000..c974be564906
--- /dev/null
+++ b/arch/mips/mm/c-lx5280.c
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * c-lx5280.c: Lexra LX5280 CPU cache code.
+ *
+ * Copyright (C) 2018 Yasha Cherikovsky
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/of.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+static unsigned int icache_size, dcache_size; /* Size in bytes */
+static unsigned int icache_lsize, dcache_lsize; /* Size in bytes */
+
+
+#define _nop() \
+do { \
+ __asm__ __volatile__("nop"); \
+} while (0)
+
+
+static inline void __lx5280_flush_dcache_internal(void)
+{
+ unsigned long cctl;
+
+ cctl = read_c0_lx5280_cctl();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ write_c0_lx5280_cctl(cctl & (~LX5280_CCTL_DINVAL));
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ write_c0_lx5280_cctl(cctl | (LX5280_CCTL_DINVAL));
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+}
+
+static inline void __lx5280_flush_icache_internal(void)
+{
+ unsigned long cctl;
+
+ cctl = read_c0_lx5280_cctl();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ write_c0_lx5280_cctl(cctl & (~LX5280_CCTL_IINVAL));
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ write_c0_lx5280_cctl(cctl | (LX5280_CCTL_IINVAL));
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+ _nop();
+}
+
+static void __lx5280_flush_icache(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __lx5280_flush_icache_internal();
+ local_irq_restore(flags);
+}
+
+static void __lx5280_flush_dcache(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __lx5280_flush_dcache_internal();
+ local_irq_restore(flags);
+}
+
+static void lx5280_flush_icache_range(unsigned long start, unsigned long end)
+{
+ __lx5280_flush_icache();
+}
+
+static void lx5280_flush_dcache_range(unsigned long start, unsigned long end)
+{
+ __lx5280_flush_dcache();
+}
+
+static void lx5280___flush_cache_all(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __lx5280_flush_dcache_internal();
+ __lx5280_flush_icache_internal();
+ local_irq_restore(flags);
+}
+
+static void lx5280_flush_cache_all(void)
+{
+ lx5280___flush_cache_all();
+}
+
+static void lx5280_flush_cache_mm(struct mm_struct *mm)
+{
+ lx5280_flush_cache_all();
+}
+
+static void lx5280_flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ lx5280_flush_cache_all();
+}
+
+static void lx5280_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
+{
+ unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT);
+ struct mm_struct *mm = vma->vm_mm;
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ pr_debug("cpage[%08lx,%08lx]\n",
+ cpu_context(smp_processor_id(), mm), addr);
+
+ /* No ASID => no such page in the cache. */
+ if (cpu_context(smp_processor_id(), mm) == 0)
+ return;
+
+ pgdp = pgd_offset(mm, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
+ ptep = pte_offset(pmdp, addr);
+
+ /* Invalid => no such page in the cache. */
+ if (!(pte_val(*ptep) & _PAGE_PRESENT))
+ return;
+
+ lx5280_flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
+ lx5280_flush_icache_range(kaddr, kaddr + PAGE_SIZE);
+}
+
+static void local_lx5280_flush_data_cache_page(void *addr)
+{
+ __lx5280_flush_dcache();
+}
+
+static void lx5280_flush_data_cache_page(unsigned long addr)
+{
+ __lx5280_flush_dcache();
+}
+
+static void lx5280_flush_cache_sigtramp(unsigned long addr)
+{
+ lx5280_flush_cache_all();
+}
+
+static void lx5280_flush_kernel_vmap_range(unsigned long vaddr, int size)
+{
+ lx5280_flush_cache_all();
+}
+
+static void lx5280_dma_cache_wback_inv(unsigned long start, unsigned long size)
+{
+ lx5280_flush_dcache_range(start, start + size);
+}
+
+static u32 of_property_read_u32_or_panic(struct device_node *np,
+ const char *propname)
+{
+ u32 out_value;
+
+ if (of_property_read_u32(np, propname, &out_value))
+ panic("Unable to get %s from devicetree", propname);
+ return out_value;
+}
+
+void lx5280_cache_init(void)
+{
+ extern void build_clear_page(void);
+ extern void build_copy_page(void);
+ struct device_node *np;
+
+ np = of_get_cpu_node(0, NULL);
+ if (!np)
+ panic("Unable to find cpu node in devicetree");
+
+ dcache_size = of_property_read_u32_or_panic(np, "d-cache-size");
+ icache_size = of_property_read_u32_or_panic(np, "i-cache-size");
+ dcache_lsize = of_property_read_u32_or_panic(np, "d-cache-line-size");
+ icache_lsize = of_property_read_u32_or_panic(np, "i-cache-line-size");
+
+ of_node_put(np);
+
+ current_cpu_data.dcache.linesz = dcache_lsize;
+ current_cpu_data.icache.linesz = icache_lsize;
+
+ flush_cache_all = lx5280_flush_cache_all;
+ __flush_cache_all = lx5280___flush_cache_all;
+ flush_cache_mm = lx5280_flush_cache_mm;
+ flush_cache_range = lx5280_flush_cache_range;
+ flush_cache_page = lx5280_flush_cache_page;
+ flush_icache_range = lx5280_flush_icache_range;
+ local_flush_icache_range = lx5280_flush_icache_range;
+ __flush_icache_user_range = lx5280_flush_icache_range;
+ __local_flush_icache_user_range = lx5280_flush_icache_range;
+
+ __flush_kernel_vmap_range = lx5280_flush_kernel_vmap_range;
+
+ flush_cache_sigtramp = lx5280_flush_cache_sigtramp;
+ local_flush_data_cache_page = local_lx5280_flush_data_cache_page;
+ flush_data_cache_page = lx5280_flush_data_cache_page;
+
+ _dma_cache_wback_inv = lx5280_dma_cache_wback_inv;
+ _dma_cache_wback = lx5280_dma_cache_wback_inv;
+ _dma_cache_inv = lx5280_dma_cache_wback_inv;
+
+ pr_info("Primary instruction cache %dkB, linesize %d bytes.\n",
+ icache_size >> 10, icache_lsize);
+ pr_info("Primary data cache %dkB, linesize %d bytes.\n",
+ dcache_size >> 10, dcache_lsize);
+
+ build_clear_page();
+ build_copy_page();
+}
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 0d3c656feba0..873e62cfc821 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -234,6 +234,12 @@ void cpu_cache_init(void)
octeon_cache_init();
}
+ if (cpu_has_lx5280_cache) {
+ extern void __weak lx5280_cache_init(void);
+
+ lx5280_cache_init();
+ }
+
setup_protection_map();
}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 5f71f2b903b7..159fd009f5bd 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -26,6 +26,7 @@
#include <asm/mmu_context.h>
#include <asm/ptrace.h>
#include <asm/highmem.h> /* For VMALLOC_END */
+#include <asm/traps.h>
#include <linux/kdebug.h>
int show_unhandled_signals = 1;
@@ -204,6 +205,9 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
if (user_mode(regs)) {
+ if (!simulate_rdhwr_in_page_fault(regs))
+ return;
+
tsk->thread.cp0_badvaddr = address;
tsk->thread.error_code = write;
if (show_unhandled_signals &&
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 79b9f2ad3ff5..95e745795724 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -2616,6 +2616,7 @@ void build_tlb_refill_handler(void)
case CPU_TX3912:
case CPU_TX3922:
case CPU_TX3927:
+ case CPU_LX5280:
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
if (cpu_has_local_ebase)
build_r3000_tlb_refill_handler();
--
2.19.0
Hi Yasha,
On 30/09/18 15:15, Yasha Cherikovsky wrote:
> The Realtek RTL8186 SoC is a MIPS based SoC
> used in some home routers [1][2].
>
> The hardware includes Lexra LX5280 CPU with a TLB,
> two Ethernet controllers, a WLAN controller and more.
>
> With this patch, it is possible to successfully boot
> the kernel and load userspace on the Edimax BR-6204Wg
> router.
> Network drivers support will come in future patches.
>
> This patch includes:
> - New MIPS rtl8186 platform
> - Core platform setup code (mostly DT based)
> - New Kconfig option
> - defconfig file
> - MIPS zboot UART support
> - RTL8186 interrupt controller driver
> - RTL8186 timer driver
> - Device tree files for the RTL8186 SoC and Edimax BR-6204Wg
> router
>
> [1] https://www.linux-mips.org/wiki/Realtek_SOC#Realtek_RTL8186
> [2] https://wikidevi.com/wiki/Realtek_RTL8186
>
> Signed-off-by: Yasha Cherikovsky <[email protected]>
> Cc: Ralf Baechle <[email protected]>
> Cc: Paul Burton <[email protected]>
> Cc: James Hogan <[email protected]>
> Cc: Thomas Gleixner <[email protected]>
> Cc: Jason Cooper <[email protected]>
> Cc: Marc Zyngier <[email protected]>
> Cc: Daniel Lezcano <[email protected]>
> Cc: Rob Herring <[email protected]>
> Cc: Mark Rutland <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> arch/mips/Kbuild.platforms | 1 +
> arch/mips/Kconfig | 17 ++
> arch/mips/boot/compressed/uart-16550.c | 5 +
> arch/mips/boot/dts/Makefile | 1 +
> arch/mips/boot/dts/realtek/Makefile | 4 +
> arch/mips/boot/dts/realtek/rtl8186.dtsi | 86 +++++++
> .../dts/realtek/rtl8186_edimax_br_6204wg.dts | 45 ++++
> arch/mips/configs/rtl8186_defconfig | 112 +++++++++
> arch/mips/include/asm/mach-rtl8186/rtl8186.h | 37 +++
> arch/mips/rtl8186/Makefile | 2 +
> arch/mips/rtl8186/Platform | 7 +
> arch/mips/rtl8186/irq.c | 8 +
> arch/mips/rtl8186/prom.c | 15 ++
> arch/mips/rtl8186/setup.c | 80 +++++++
> arch/mips/rtl8186/time.c | 10 +
> drivers/clocksource/Kconfig | 9 +
> drivers/clocksource/Makefile | 1 +
> drivers/clocksource/timer-rtl8186.c | 220 ++++++++++++++++++
> drivers/irqchip/Kconfig | 5 +
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-rtl8186.c | 107 +++++++++
Could you please split this into at least three patches (arch code,
clocksource, irqchip) to ease the review?
Thanks,
M.
--
Jazz is not dead. It just smells funny...
Hi Marc,
On Mon, 2018-10-01 at 09:19 +0100, Marc Zyngier wrote:
> Hi Yasha,
>
> On 30/09/18 15:15, Yasha Cherikovsky wrote:
> > The Realtek RTL8186 SoC is a MIPS based SoC
> > used in some home routers [1][2].
> >
> > The hardware includes Lexra LX5280 CPU with a TLB,
> > two Ethernet controllers, a WLAN controller and more.
> >
> > With this patch, it is possible to successfully boot
> > the kernel and load userspace on the Edimax BR-6204Wg
> > router.
> > Network drivers support will come in future patches.
> >
> > This patch includes:
> > - New MIPS rtl8186 platform
> > - Core platform setup code (mostly DT based)
> > - New Kconfig option
> > - defconfig file
> > - MIPS zboot UART support
> > - RTL8186 interrupt controller driver
> > - RTL8186 timer driver
> > - Device tree files for the RTL8186 SoC and Edimax BR-6204Wg
> > router
> >
> > [1] https://www.linux-mips.org/wiki/Realtek_SOC#Realtek_RTL8186
> > [2] https://wikidevi.com/wiki/Realtek_RTL8186
> >
> > Signed-off-by: Yasha Cherikovsky <[email protected]>
> > Cc: Ralf Baechle <[email protected]>
> > Cc: Paul Burton <[email protected]>
> > Cc: James Hogan <[email protected]>
> > Cc: Thomas Gleixner <[email protected]>
> > Cc: Jason Cooper <[email protected]>
> > Cc: Marc Zyngier <[email protected]>
> > Cc: Daniel Lezcano <[email protected]>
> > Cc: Rob Herring <[email protected]>
> > Cc: Mark Rutland <[email protected]>
> > Cc: [email protected]
> > Cc: [email protected]
> > Cc: [email protected]
> > ---
> > arch/mips/Kbuild.platforms | 1 +
> > arch/mips/Kconfig | 17 ++
> > arch/mips/boot/compressed/uart-16550.c | 5 +
> > arch/mips/boot/dts/Makefile | 1 +
> > arch/mips/boot/dts/realtek/Makefile | 4 +
> > arch/mips/boot/dts/realtek/rtl8186.dtsi | 86 +++++++
> > .../dts/realtek/rtl8186_edimax_br_6204wg.dts | 45 ++++
> > arch/mips/configs/rtl8186_defconfig | 112 +++++++++
> > arch/mips/include/asm/mach-rtl8186/rtl8186.h | 37 +++
> > arch/mips/rtl8186/Makefile | 2 +
> > arch/mips/rtl8186/Platform | 7 +
> > arch/mips/rtl8186/irq.c | 8 +
> > arch/mips/rtl8186/prom.c | 15 ++
> > arch/mips/rtl8186/setup.c | 80 +++++++
> > arch/mips/rtl8186/time.c | 10 +
> > drivers/clocksource/Kconfig | 9 +
> > drivers/clocksource/Makefile | 1 +
> > drivers/clocksource/timer-rtl8186.c | 220
> > ++++++++++++++++++
> > drivers/irqchip/Kconfig | 5 +
> > drivers/irqchip/Makefile | 1 +
> > drivers/irqchip/irq-rtl8186.c | 107 +++++++++
>
> Could you please split this into at least three patches (arch code,
> clocksource, irqchip) to ease the review?
>
> Thanks,
>
> M.
Currently the RTL8186_IRQ and the RTL8186_TIMER Kconfig entries depend on
MACH_RTL8186 (which is added in the MIPS portion of the same patch).
Also, MACH_RTL8186 in MIPS selects these two options.
What is the best way to split that?
Thanks,
Yasha
On 01/10/18 09:48, Yasha Cherikovsky wrote:
> Hi Marc,
>
> On Mon, 2018-10-01 at 09:19 +0100, Marc Zyngier wrote:
>> Hi Yasha,
>>
>> On 30/09/18 15:15, Yasha Cherikovsky wrote:
>>> The Realtek RTL8186 SoC is a MIPS based SoC
>>> used in some home routers [1][2].
>>>
>>> The hardware includes Lexra LX5280 CPU with a TLB,
>>> two Ethernet controllers, a WLAN controller and more.
>>>
>>> With this patch, it is possible to successfully boot
>>> the kernel and load userspace on the Edimax BR-6204Wg
>>> router.
>>> Network drivers support will come in future patches.
>>>
>>> This patch includes:
>>> - New MIPS rtl8186 platform
>>> - Core platform setup code (mostly DT based)
>>> - New Kconfig option
>>> - defconfig file
>>> - MIPS zboot UART support
>>> - RTL8186 interrupt controller driver
>>> - RTL8186 timer driver
>>> - Device tree files for the RTL8186 SoC and Edimax BR-6204Wg
>>> router
>>>
>>> [1] https://www.linux-mips.org/wiki/Realtek_SOC#Realtek_RTL8186
>>> [2] https://wikidevi.com/wiki/Realtek_RTL8186
>>>
>>> Signed-off-by: Yasha Cherikovsky <[email protected]>
>>> Cc: Ralf Baechle <[email protected]>
>>> Cc: Paul Burton <[email protected]>
>>> Cc: James Hogan <[email protected]>
>>> Cc: Thomas Gleixner <[email protected]>
>>> Cc: Jason Cooper <[email protected]>
>>> Cc: Marc Zyngier <[email protected]>
>>> Cc: Daniel Lezcano <[email protected]>
>>> Cc: Rob Herring <[email protected]>
>>> Cc: Mark Rutland <[email protected]>
>>> Cc: [email protected]
>>> Cc: [email protected]
>>> Cc: [email protected]
>>> ---
>>> arch/mips/Kbuild.platforms | 1 +
>>> arch/mips/Kconfig | 17 ++
>>> arch/mips/boot/compressed/uart-16550.c | 5 +
>>> arch/mips/boot/dts/Makefile | 1 +
>>> arch/mips/boot/dts/realtek/Makefile | 4 +
>>> arch/mips/boot/dts/realtek/rtl8186.dtsi | 86 +++++++
>>> .../dts/realtek/rtl8186_edimax_br_6204wg.dts | 45 ++++
>>> arch/mips/configs/rtl8186_defconfig | 112 +++++++++
>>> arch/mips/include/asm/mach-rtl8186/rtl8186.h | 37 +++
>>> arch/mips/rtl8186/Makefile | 2 +
>>> arch/mips/rtl8186/Platform | 7 +
>>> arch/mips/rtl8186/irq.c | 8 +
>>> arch/mips/rtl8186/prom.c | 15 ++
>>> arch/mips/rtl8186/setup.c | 80 +++++++
>>> arch/mips/rtl8186/time.c | 10 +
>>> drivers/clocksource/Kconfig | 9 +
>>> drivers/clocksource/Makefile | 1 +
>>> drivers/clocksource/timer-rtl8186.c | 220
>>> ++++++++++++++++++
>>> drivers/irqchip/Kconfig | 5 +
>>> drivers/irqchip/Makefile | 1 +
>>> drivers/irqchip/irq-rtl8186.c | 107 +++++++++
>>
>> Could you please split this into at least three patches (arch code,
>> clocksource, irqchip) to ease the review?
>>
>> Thanks,
>>
>> M.
>
> Currently the RTL8186_IRQ and the RTL8186_TIMER Kconfig entries depend on
> MACH_RTL8186 (which is added in the MIPS portion of the same patch).
> Also, MACH_RTL8186 in MIPS selects these two options.
>
> What is the best way to split that?
It is absolutely fine to have something depending on a non-selectable
config option, which would allow you to split things up as finely as you
want. Just have the patch enabling the config option last.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
On Mon, 2018-10-01 at 10:15 +0100, Marc Zyngier wrote:
> On 01/10/18 09:48, Yasha Cherikovsky wrote:
> > Hi Marc,
> >
> > On Mon, 2018-10-01 at 09:19 +0100, Marc Zyngier wrote:
> > > Hi Yasha,
> > >
> > > On 30/09/18 15:15, Yasha Cherikovsky wrote:
> > > > The Realtek RTL8186 SoC is a MIPS based SoC
> > > > used in some home routers [1][2].
> > > >
> > > > The hardware includes Lexra LX5280 CPU with a TLB,
> > > > two Ethernet controllers, a WLAN controller and more.
> > > >
> > > > With this patch, it is possible to successfully boot
> > > > the kernel and load userspace on the Edimax BR-6204Wg
> > > > router.
> > > > Network drivers support will come in future patches.
> > > >
> > > > This patch includes:
> > > > - New MIPS rtl8186 platform
> > > > - Core platform setup code (mostly DT based)
> > > > - New Kconfig option
> > > > - defconfig file
> > > > - MIPS zboot UART support
> > > > - RTL8186 interrupt controller driver
> > > > - RTL8186 timer driver
> > > > - Device tree files for the RTL8186 SoC and Edimax BR-6204Wg
> > > > router
> > > >
> > > > [1] https://www.linux-mips.org/wiki/Realtek_SOC#Realtek_RTL8186
> > > > [2] https://wikidevi.com/wiki/Realtek_RTL8186
> > > >
> > > > Signed-off-by: Yasha Cherikovsky <[email protected]>
> > > > Cc: Ralf Baechle <[email protected]>
> > > > Cc: Paul Burton <[email protected]>
> > > > Cc: James Hogan <[email protected]>
> > > > Cc: Thomas Gleixner <[email protected]>
> > > > Cc: Jason Cooper <[email protected]>
> > > > Cc: Marc Zyngier <[email protected]>
> > > > Cc: Daniel Lezcano <[email protected]>
> > > > Cc: Rob Herring <[email protected]>
> > > > Cc: Mark Rutland <[email protected]>
> > > > Cc: [email protected]
> > > > Cc: [email protected]
> > > > Cc: [email protected]
> > > > ---
> > > > arch/mips/Kbuild.platforms | 1 +
> > > > arch/mips/Kconfig | 17 ++
> > > > arch/mips/boot/compressed/uart-16550.c | 5 +
> > > > arch/mips/boot/dts/Makefile | 1 +
> > > > arch/mips/boot/dts/realtek/Makefile | 4 +
> > > > arch/mips/boot/dts/realtek/rtl8186.dtsi | 86 +++++++
> > > > .../dts/realtek/rtl8186_edimax_br_6204wg.dts | 45 ++++
> > > > arch/mips/configs/rtl8186_defconfig | 112 +++++++++
> > > > arch/mips/include/asm/mach-rtl8186/rtl8186.h | 37 +++
> > > > arch/mips/rtl8186/Makefile | 2 +
> > > > arch/mips/rtl8186/Platform | 7 +
> > > > arch/mips/rtl8186/irq.c | 8 +
> > > > arch/mips/rtl8186/prom.c | 15 ++
> > > > arch/mips/rtl8186/setup.c | 80 +++++++
> > > > arch/mips/rtl8186/time.c | 10 +
> > > > drivers/clocksource/Kconfig | 9 +
> > > > drivers/clocksource/Makefile | 1 +
> > > > drivers/clocksource/timer-rtl8186.c | 220
> > > > ++++++++++++++++++
> > > > drivers/irqchip/Kconfig | 5 +
> > > > drivers/irqchip/Makefile | 1 +
> > > > drivers/irqchip/irq-rtl8186.c | 107 +++++++++
> > >
> > > Could you please split this into at least three patches (arch code,
> > > clocksource, irqchip) to ease the review?
> > >
> > > Thanks,
> > >
> > > M.
> >
> > Currently the RTL8186_IRQ and the RTL8186_TIMER Kconfig entries depend
> > on
> > MACH_RTL8186 (which is added in the MIPS portion of the same patch).
> > Also, MACH_RTL8186 in MIPS selects these two options.
> >
> > What is the best way to split that?
>
> It is absolutely fine to have something depending on a non-selectable
> config option, which would allow you to split things up as finely as you
> want. Just have the patch enabling the config option last.
>
> Thanks,
>
> M.
Good to know, thanks.
I'll send a v2 soon.
Yasha