diff mbox series

[2/6] mips: Add N64 machine type

Message ID 20210104154357.6cf126150407ba4839630177@gmx.com (mailing list archive)
State Superseded
Headers show
Series [1/6] Revert "MIPS: Remove unused R4300 CPU support" | expand

Commit Message

Lauri Kasanen Jan. 4, 2021, 1:43 p.m. UTC
Signed-off-by: Lauri Kasanen <cand@gmx.com>
---
 arch/mips/Kbuild.platforms           |   1 +
 arch/mips/Kconfig                    |  12 ++++
 arch/mips/include/asm/mach-n64/irq.h |   9 +++
 arch/mips/include/asm/n64/irq.h      |  26 ++++++++
 arch/mips/n64/Makefile               |   6 ++
 arch/mips/n64/Platform               |   7 +++
 arch/mips/n64/init.c                 | 119 +++++++++++++++++++++++++++++++++++
 arch/mips/n64/irq.c                  |  16 +++++
 8 files changed, 196 insertions(+)
 create mode 100644 arch/mips/include/asm/mach-n64/irq.h
 create mode 100644 arch/mips/include/asm/n64/irq.h
 create mode 100644 arch/mips/n64/Makefile
 create mode 100644 arch/mips/n64/Platform
 create mode 100644 arch/mips/n64/init.c
 create mode 100644 arch/mips/n64/irq.c

--
2.6.2

Comments

Thomas Bogendoerfer Jan. 7, 2021, 5:10 p.m. UTC | #1
On Mon, Jan 04, 2021 at 03:43:57PM +0200, Lauri Kasanen wrote:
> [..]
>  	select GPIOLIB
> 
> +config MACH_NINTENDO64
> +	bool "Nintendo 64 console"
> +	select CEVT_R4K
> +	select CSRC_R4K
> +	select SYS_HAS_CPU_R4300
> +	select SYS_SUPPORTS_BIG_ENDIAN
> +	select SYS_SUPPORTS_ZBOOT
> +	select SYS_SUPPORTS_32BIT_KERNEL

32BIT kernel don't compile, because you use TO_UNCAC which only
exists for 64bit kernels. One solution would be to use CKSEG1 to
convert from physical to an uncached address. But I'd prefer if
you add resources to your platform device and do ioremap in device
drivers. This way there is also no need to export the interrupt
defines outside.

> diff --git a/arch/mips/include/asm/mach-n64/irq.h b/arch/mips/include/asm/mach-n64/irq.h
> new file mode 100644
> index 0000000..4d4a1ea
> --- /dev/null
> +++ b/arch/mips/include/asm/mach-n64/irq.h
> @@ -0,0 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_MACH_N64_IRQ_H
> +#define __ASM_MACH_N64_IRQ_H
> +
> +#include <asm/n64/irq.h> /* for MIPS_CPU_IRQ_BASE */

the only thing, which should be here is the override of NR_IRQS

> +#define MIPS_CPU_IRQ_BASE	0

that's default, no need to define.

> +#define MIPS_CPU_IRQ(x)		(MIPS_CPU_IRQ_BASE + (x))
> +#define MIPS_SOFTINT0_IRQ	MIPS_CPU_IRQ(0)
> +#define MIPS_SOFTINT1_IRQ	MIPS_CPU_IRQ(1)

I doubt you need the SOFTINT defines

> +#define RCP_IRQ			MIPS_CPU_IRQ(2)
> +#define CART_IRQ		MIPS_CPU_IRQ(3)
> +#define PRENMI_IRQ		MIPS_CPU_IRQ(4)
> +#define RDBR_IRQ		MIPS_CPU_IRQ(5)
> +#define RDBW_IRQ		MIPS_CPU_IRQ(6)
> +#define TIMER_IRQ		MIPS_CPU_IRQ(7)

and this IMHO also unsed, so no need to define it.

With the approach of using a platform irq resource you don't
even need this header file as there is only a single plays,
which deals with irq assignment.

> +void __init prom_free_prom_memory(void)
> +{
> +}
> +

you can drop that now with current mips-next.

> +void __init plat_time_init(void)
> +{
> +	// 93.75 MHz cpu, count register runs at half rate

no C++ comments please.

> +	mips_hpt_frequency = 93750000 / 2;
> +}
Lauri Kasanen Jan. 8, 2021, 7:04 a.m. UTC | #2
On Thu, 7 Jan 2021 18:10:35 +0100
Thomas Bogendoerfer <tsbogend@alpha.franken.de> wrote:

> 32BIT kernel don't compile, because you use TO_UNCAC which only
> exists for 64bit kernels. One solution would be to use CKSEG1 to
> convert from physical to an uncached address. But I'd prefer if
> you add resources to your platform device and do ioremap in device
> drivers. This way there is also no need to export the interrupt
> defines outside.

:( Jiaxun told me to use TO_UNCAC because CKSEG1 was unclear to him...

I will change back to CKSEG1. ioremap seems much needless overhead.

> > +#define RCP_IRQ			MIPS_CPU_IRQ(2)
> > +#define CART_IRQ		MIPS_CPU_IRQ(3)
> > +#define PRENMI_IRQ		MIPS_CPU_IRQ(4)
> > +#define RDBR_IRQ		MIPS_CPU_IRQ(5)
> > +#define RDBW_IRQ		MIPS_CPU_IRQ(6)
> > +#define TIMER_IRQ		MIPS_CPU_IRQ(7)
>
> and this IMHO also unsed, so no need to define it.

The sound driver uses the RCP IRQ; the machine-specific names are
defined because they're much more clear.

- Lauri
Thomas Bogendoerfer Jan. 8, 2021, 8:40 a.m. UTC | #3
On Fri, Jan 08, 2021 at 09:04:34AM +0200, Lauri Kasanen wrote:
> On Thu, 7 Jan 2021 18:10:35 +0100
> Thomas Bogendoerfer <tsbogend@alpha.franken.de> wrote:
> 
> > 32BIT kernel don't compile, because you use TO_UNCAC which only
> > exists for 64bit kernels. One solution would be to use CKSEG1 to
> > convert from physical to an uncached address. But I'd prefer if
> > you add resources to your platform device and do ioremap in device
> > drivers. This way there is also no need to export the interrupt
> > defines outside.
> 
> :( Jiaxun told me to use TO_UNCAC because CKSEG1 was unclear to him...
> 
> I will change back to CKSEG1. ioremap seems much needless overhead.

ok, let me put it that way: Using ioremap is not a wish. To get your code
integrated use ioremap and platform resources. IMHO driver maintainers
will appreciate that as well. 

> > > +#define RCP_IRQ			MIPS_CPU_IRQ(2)
> > > +#define CART_IRQ		MIPS_CPU_IRQ(3)
> > > +#define PRENMI_IRQ		MIPS_CPU_IRQ(4)
> > > +#define RDBR_IRQ		MIPS_CPU_IRQ(5)
> > > +#define RDBW_IRQ		MIPS_CPU_IRQ(6)
> > > +#define TIMER_IRQ		MIPS_CPU_IRQ(7)
> >
> > and this IMHO also unsed, so no need to define it.
> 
> The sound driver uses the RCP IRQ; the machine-specific names are
> defined because they're much more clear.

you can keep the defines, but no need to have it in an #include when
you move it to n64/init.c. From there you pass it via platform irq
resource to drivers. Background is that I want to keep stuff in
mach-xxx at the bear minimum.

Thomas.
Jiaxun Yang Jan. 8, 2021, 11:28 a.m. UTC | #4
在 2021/1/8 下午3:04, Lauri Kasanen 写道:
> On Thu, 7 Jan 2021 18:10:35 +0100
> Thomas Bogendoerfer <tsbogend@alpha.franken.de> wrote:
>
>> 32BIT kernel don't compile, because you use TO_UNCAC which only
>> exists for 64bit kernels. One solution would be to use CKSEG1 to
>> convert from physical to an uncached address. But I'd prefer if
>> you add resources to your platform device and do ioremap in device
>> drivers. This way there is also no need to export the interrupt
>> defines outside.
> :( Jiaxun told me to use TO_UNCAC because CKSEG1 was unclear to him...
>
> I will change back to CKSEG1. ioremap seems much needless overhead.


Sorry, ignored that you have 32-bit kernel as well.

- Jiaxun
diff mbox series

Patch

diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 5483e38..e4f6e49 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -18,6 +18,7 @@  platform-$(CONFIG_MACH_LOONGSON2EF)	+= loongson2ef/
 platform-$(CONFIG_MACH_LOONGSON32)	+= loongson32/
 platform-$(CONFIG_MACH_LOONGSON64)	+= loongson64/
 platform-$(CONFIG_MIPS_MALTA)		+= mti-malta/
+platform-$(CONFIG_MACH_NINTENDO64)	+= n64/
 platform-$(CONFIG_NLM_COMMON)		+= netlogic/
 platform-$(CONFIG_PIC32MZDA)		+= pic32/
 platform-$(CONFIG_MACH_PISTACHIO)	+= pistachio/
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4b52588..1b0aae0 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -605,6 +605,18 @@  config MACH_VR41XX
 	select SYS_SUPPORTS_MIPS16
 	select GPIOLIB

+config MACH_NINTENDO64
+	bool "Nintendo 64 console"
+	select CEVT_R4K
+	select CSRC_R4K
+	select SYS_HAS_CPU_R4300
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_ZBOOT
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL
+	select DMA_NONCOHERENT
+	select IRQ_MIPS_CPU
+
 config RALINK
 	bool "Ralink based machines"
 	select CEVT_R4K
diff --git a/arch/mips/include/asm/mach-n64/irq.h b/arch/mips/include/asm/mach-n64/irq.h
new file mode 100644
index 0000000..4d4a1ea
--- /dev/null
+++ b/arch/mips/include/asm/mach-n64/irq.h
@@ -0,0 +1,9 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MACH_N64_IRQ_H
+#define __ASM_MACH_N64_IRQ_H
+
+#include <asm/n64/irq.h> /* for MIPS_CPU_IRQ_BASE */
+
+#include <asm/mach-generic/irq.h>
+
+#endif /* __ASM_MACH_N64_IRQ_H */
diff --git a/arch/mips/include/asm/n64/irq.h b/arch/mips/include/asm/n64/irq.h
new file mode 100644
index 0000000..00f89ca
--- /dev/null
+++ b/arch/mips/include/asm/n64/irq.h
@@ -0,0 +1,26 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Interrupt numbers for N64
+ *
+ * Copyright (C) 2020 Lauri Kasanen
+ */
+#ifndef __N64_IRQ_H
+#define __N64_IRQ_H
+
+#define NR_IRQS 8
+
+/*
+ * CPU core Interrupt Numbers
+ */
+#define MIPS_CPU_IRQ_BASE	0
+#define MIPS_CPU_IRQ(x)		(MIPS_CPU_IRQ_BASE + (x))
+#define MIPS_SOFTINT0_IRQ	MIPS_CPU_IRQ(0)
+#define MIPS_SOFTINT1_IRQ	MIPS_CPU_IRQ(1)
+#define RCP_IRQ			MIPS_CPU_IRQ(2)
+#define CART_IRQ		MIPS_CPU_IRQ(3)
+#define PRENMI_IRQ		MIPS_CPU_IRQ(4)
+#define RDBR_IRQ		MIPS_CPU_IRQ(5)
+#define RDBW_IRQ		MIPS_CPU_IRQ(6)
+#define TIMER_IRQ		MIPS_CPU_IRQ(7)
+
+#endif /* __N64_IRQ_H */
diff --git a/arch/mips/n64/Makefile b/arch/mips/n64/Makefile
new file mode 100644
index 0000000..b64a05a
--- /dev/null
+++ b/arch/mips/n64/Makefile
@@ -0,0 +1,6 @@ 
+# SPDX-License-Identifier: GPL-2.0
+#
+# Nintendo 64
+#
+
+obj-y := init.o irq.o
diff --git a/arch/mips/n64/Platform b/arch/mips/n64/Platform
new file mode 100644
index 0000000..2464783
--- /dev/null
+++ b/arch/mips/n64/Platform
@@ -0,0 +1,7 @@ 
+# SPDX-License-Identifier: GPL-2.0
+#
+# Nintendo 64
+#
+
+cflags-$(CONFIG_MACH_NINTENDO64)    += -I$(srctree)/arch/mips/include/asm/mach-n64
+load-$(CONFIG_MACH_NINTENDO64)      += 0xffffffff80101000
diff --git a/arch/mips/n64/init.c b/arch/mips/n64/init.c
new file mode 100644
index 0000000..47f29d6
--- /dev/null
+++ b/arch/mips/n64/init.c
@@ -0,0 +1,119 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Nintendo 64 init.
+ *
+ *  Copyright (C) 2020	Lauri Kasanen
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/simplefb.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/fw/fw.h>
+#include <asm/time.h>
+
+#define IO_MEM_RESOURCE_START	0UL
+#define IO_MEM_RESOURCE_END	0x1fffffffUL
+
+static void __init iomem_resource_init(void)
+{
+	iomem_resource.start = IO_MEM_RESOURCE_START;
+	iomem_resource.end = IO_MEM_RESOURCE_END;
+}
+
+const char *get_system_type(void)
+{
+	return "Nintendo 64";
+}
+
+void __init prom_init(void)
+{
+	fw_init_cmdline();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+#define W 320
+#define H 240
+#define REG_BASE ((u32 *) TO_UNCAC(0x4400000))
+
+static void __init n64rdp_write_reg(const u8 reg, const u32 value)
+{
+	__raw_writel(value, REG_BASE + reg);
+}
+
+#undef REG_BASE
+
+static const u32 ntsc_320[] __initconst = {
+	0x00013212, 0x00000000, 0x00000140, 0x00000200,
+	0x00000000, 0x03e52239, 0x0000020d, 0x00000c15,
+	0x0c150c15, 0x006c02ec, 0x002501ff, 0x000e0204,
+	0x00000200, 0x00000400
+};
+
+static int __init n64_platform_init(void)
+{
+	static const char simplefb_resname[] = "FB";
+	static const struct simplefb_platform_data mode = {
+		.width = W,
+		.height = H,
+		.stride = W * 2,
+		.format = "r5g5b5a1"
+	};
+	struct resource res;
+	void *orig;
+	unsigned long phys;
+	unsigned i;
+
+	platform_device_register_simple("n64audio", -1, NULL, 0);
+
+	/* The framebuffer needs 64-byte alignment */
+	orig = kzalloc(W * H * 2 + 63, GFP_DMA | GFP_KERNEL);
+	if (!orig)
+		return -ENOMEM;
+	phys = virt_to_phys(orig);
+	phys += 63;
+	phys &= ~63;
+
+	for (i = 0; i < ARRAY_SIZE(ntsc_320); i++) {
+		if (i == 1)
+			n64rdp_write_reg(i, phys);
+		else
+			n64rdp_write_reg(i, ntsc_320[i]);
+	}
+
+	/* setup IORESOURCE_MEM as framebuffer memory */
+	memset(&res, 0, sizeof(res));
+	res.flags = IORESOURCE_MEM;
+	res.name = simplefb_resname;
+	res.start = phys;
+	res.end = phys + W * H * 2 - 1;
+
+	platform_device_register_resndata(NULL, "simple-framebuffer", 0,
+					  &res, 1, &mode, sizeof(mode));
+
+	return 0;
+}
+
+#undef W
+#undef H
+
+arch_initcall(n64_platform_init);
+
+void __init plat_mem_setup(void)
+{
+	iomem_resource_init();
+	memblock_add(0x0, 8 * 1024 * 1024); // Bootloader blocks the 4mb config
+}
+
+void __init plat_time_init(void)
+{
+	// 93.75 MHz cpu, count register runs at half rate
+	mips_hpt_frequency = 93750000 / 2;
+}
diff --git a/arch/mips/n64/irq.c b/arch/mips/n64/irq.c
new file mode 100644
index 0000000..9f833cb
--- /dev/null
+++ b/arch/mips/n64/irq.c
@@ -0,0 +1,16 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  N64 IRQ
+ *
+ *  Copyright (C) 2020 Lauri Kasanen
+ */
+#include <linux/export.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+
+void __init arch_init_irq(void)
+{
+	mips_cpu_irq_init();
+}