* [RFC 1/5] MIPS: Add support for the Lexra LX5280 CPU
2018-09-30 14:15 [RFC 0/5] MIPS: Lexra LX5280 CPU + Realtek RTL8186 SoC support Yasha Cherikovsky
@ 2018-09-30 14:15 ` Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 2/5] dt-binding: timer: Document RTL8186 SoC DT bindings Yasha Cherikovsky
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Yasha Cherikovsky @ 2018-09-30 14:15 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Yasha Cherikovsky, linux-kernel
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 <yasha.che3@gmail.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
---
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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC 2/5] dt-binding: timer: Document RTL8186 SoC DT bindings
2018-09-30 14:15 [RFC 0/5] MIPS: Lexra LX5280 CPU + Realtek RTL8186 SoC support Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 1/5] MIPS: Add support for the Lexra LX5280 CPU Yasha Cherikovsky
@ 2018-09-30 14:15 ` Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 3/5] dt-binding: interrupt-controller: " Yasha Cherikovsky
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Yasha Cherikovsky @ 2018-09-30 14:15 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Yasha Cherikovsky, Rob Herring, Mark Rutland, Daniel Lezcano,
Thomas Gleixner, devicetree, linux-kernel
This patch adds device tree binding doc for the
Realtek RTL8186 SoC timer controller.
Signed-off-by: Yasha Cherikovsky <yasha.che3@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
---
.../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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC 3/5] dt-binding: interrupt-controller: Document RTL8186 SoC DT bindings
2018-09-30 14:15 [RFC 0/5] MIPS: Lexra LX5280 CPU + Realtek RTL8186 SoC support Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 1/5] MIPS: Add support for the Lexra LX5280 CPU Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 2/5] dt-binding: timer: Document RTL8186 SoC DT bindings Yasha Cherikovsky
@ 2018-09-30 14:15 ` Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 4/5] dt-binding: mips: Document Realtek " Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support Yasha Cherikovsky
4 siblings, 0 replies; 10+ messages in thread
From: Yasha Cherikovsky @ 2018-09-30 14:15 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Yasha Cherikovsky, Rob Herring, Mark Rutland, Thomas Gleixner,
Jason Cooper, Marc Zyngier, devicetree, linux-kernel
This patch adds device tree binding doc for the
Realtek RTL8186 SoC interrupt controller.
Signed-off-by: Yasha Cherikovsky <yasha.che3@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
---
.../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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC 4/5] dt-binding: mips: Document Realtek SoC DT bindings
2018-09-30 14:15 [RFC 0/5] MIPS: Lexra LX5280 CPU + Realtek RTL8186 SoC support Yasha Cherikovsky
` (2 preceding siblings ...)
2018-09-30 14:15 ` [RFC 3/5] dt-binding: interrupt-controller: " Yasha Cherikovsky
@ 2018-09-30 14:15 ` Yasha Cherikovsky
2018-09-30 14:15 ` [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support Yasha Cherikovsky
4 siblings, 0 replies; 10+ messages in thread
From: Yasha Cherikovsky @ 2018-09-30 14:15 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Yasha Cherikovsky, Rob Herring, Mark Rutland, devicetree, linux-kernel
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 <yasha.che3@gmail.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
---
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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support
2018-09-30 14:15 [RFC 0/5] MIPS: Lexra LX5280 CPU + Realtek RTL8186 SoC support Yasha Cherikovsky
` (3 preceding siblings ...)
2018-09-30 14:15 ` [RFC 4/5] dt-binding: mips: Document Realtek " Yasha Cherikovsky
@ 2018-09-30 14:15 ` Yasha Cherikovsky
2018-10-01 8:19 ` Marc Zyngier
4 siblings, 1 reply; 10+ messages in thread
From: Yasha Cherikovsky @ 2018-09-30 14:15 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Yasha Cherikovsky, Thomas Gleixner, Jason Cooper, Marc Zyngier,
Daniel Lezcano, Rob Herring, Mark Rutland, devicetree,
linux-kernel
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 <yasha.che3@gmail.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-mips@linux-mips.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support
2018-09-30 14:15 ` [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support Yasha Cherikovsky
@ 2018-10-01 8:19 ` Marc Zyngier
2018-10-01 8:48 ` Yasha Cherikovsky
0 siblings, 1 reply; 10+ messages in thread
From: Marc Zyngier @ 2018-10-01 8:19 UTC (permalink / raw)
To: Yasha Cherikovsky, Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Thomas Gleixner, Jason Cooper, Daniel Lezcano, Rob Herring,
Mark Rutland, devicetree, linux-kernel
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 <yasha.che3@gmail.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Paul Burton <paul.burton@mips.com>
> Cc: James Hogan <jhogan@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: linux-mips@linux-mips.org
> Cc: devicetree@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> 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...
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support
2018-10-01 8:19 ` Marc Zyngier
@ 2018-10-01 8:48 ` Yasha Cherikovsky
2018-10-01 9:15 ` Marc Zyngier
0 siblings, 1 reply; 10+ messages in thread
From: Yasha Cherikovsky @ 2018-10-01 8:48 UTC (permalink / raw)
To: Marc Zyngier, Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Thomas Gleixner, Jason Cooper, Daniel Lezcano, Rob Herring,
Mark Rutland, devicetree, linux-kernel
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 <yasha.che3@gmail.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Paul Burton <paul.burton@mips.com>
> > Cc: James Hogan <jhogan@kernel.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Jason Cooper <jason@lakedaemon.net>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: linux-mips@linux-mips.org
> > Cc: devicetree@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org
> > ---
> > 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
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support
2018-10-01 8:48 ` Yasha Cherikovsky
@ 2018-10-01 9:15 ` Marc Zyngier
2018-10-01 9:24 ` Yasha Cherikovsky
0 siblings, 1 reply; 10+ messages in thread
From: Marc Zyngier @ 2018-10-01 9:15 UTC (permalink / raw)
To: Yasha Cherikovsky, Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Thomas Gleixner, Jason Cooper, Daniel Lezcano, Rob Herring,
Mark Rutland, devicetree, linux-kernel
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 <yasha.che3@gmail.com>
>>> Cc: Ralf Baechle <ralf@linux-mips.org>
>>> Cc: Paul Burton <paul.burton@mips.com>
>>> Cc: James Hogan <jhogan@kernel.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: Jason Cooper <jason@lakedaemon.net>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
>>> Cc: Rob Herring <robh+dt@kernel.org>
>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>> Cc: linux-mips@linux-mips.org
>>> Cc: devicetree@vger.kernel.org
>>> Cc: linux-kernel@vger.kernel.org
>>> ---
>>> 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...
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC 5/5] MIPS: Add Realtek RTL8186 SoC support
2018-10-01 9:15 ` Marc Zyngier
@ 2018-10-01 9:24 ` Yasha Cherikovsky
0 siblings, 0 replies; 10+ messages in thread
From: Yasha Cherikovsky @ 2018-10-01 9:24 UTC (permalink / raw)
To: Marc Zyngier, Ralf Baechle, Paul Burton, James Hogan, linux-mips
Cc: Thomas Gleixner, Jason Cooper, Daniel Lezcano, Rob Herring,
Mark Rutland, devicetree, linux-kernel
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 <yasha.che3@gmail.com>
> > > > Cc: Ralf Baechle <ralf@linux-mips.org>
> > > > Cc: Paul Burton <paul.burton@mips.com>
> > > > Cc: James Hogan <jhogan@kernel.org>
> > > > Cc: Thomas Gleixner <tglx@linutronix.de>
> > > > Cc: Jason Cooper <jason@lakedaemon.net>
> > > > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > > > Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> > > > Cc: Rob Herring <robh+dt@kernel.org>
> > > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > > Cc: linux-mips@linux-mips.org
> > > > Cc: devicetree@vger.kernel.org
> > > > Cc: linux-kernel@vger.kernel.org
> > > > ---
> > > > 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
^ permalink raw reply [flat|nested] 10+ messages in thread