From patchwork Fri Dec 25 16:59:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lauri Kasanen X-Patchwork-Id: 11990149 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2123FC433DB for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D3C4022285 for ; Fri, 25 Dec 2020 17:05:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726082AbgLYRFk (ORCPT ); Fri, 25 Dec 2020 12:05:40 -0500 Received: from mout.gmx.net ([212.227.17.21]:41009 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725995AbgLYRFj (ORCPT ); Fri, 25 Dec 2020 12:05:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608915847; bh=3lrL2kD5QITsCXXonPHpntTbamWvnsVUUWloW0XvODk=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject; b=Qk0fRjU8bW9uSrip85EMhYJFWNPy5dBqvfhyV4tBtp4LrgBrAqr66clxBfxIo54/r VzcR9RtRiLVVvWUtmrYMi3z0sNjCe4/ydkJg3sk/z05fqH/gl9JqLyZaggyUH23pFp 3z2UpOsz/puk8UDwi1mT+CbuxqgDWy/qIpWX8YG8= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Valinor ([82.128.181.212]) by mail.gmx.com (mrgmx104 [212.227.17.174]) with ESMTPSA (Nemesis) id 1MOA3F-1kiADn3O4P-00OZGk; Fri, 25 Dec 2020 18:04:06 +0100 Date: Fri, 25 Dec 2020 18:59:46 +0200 From: Lauri Kasanen To: linux-mips@vger.kernel.org Cc: tsbogend@alpha.franken.de Subject: [PATCH 1/6] Revert "MIPS: Remove unused R4300 CPU support" Message-Id: <20201225185946.d67607fe16e324c56f9a2f46@gmx.com> X-Mailer: Sylpheed 3.5.0 (GTK+ 2.18.6; x86_64-unknown-linux-gnu) Mime-Version: 1.0 X-Provags-ID: V03:K1:VI7Mn/LMsDzqQ2ZY6gB48XhjLQRFSL5W14/uOZEdG1xZWK3Uf7G uvOD3hrpLj2qsgtfYaXJYPlndbF4sULHq026MuKM+gA0VEyPFaMqOsIkZOtRrjsWBH/ssXj l/KPcGE0GnExzypYpXYOu6zwrhMSFrkPIZdfVhTPZMS5jURixyzYes1qSwvHyasZdX9G15N ghyXQilBZrm2V09GxS83Q== X-UI-Out-Filterresults: notjunk:1;V03:K0:kiSofw0U+bs=:/EONNZnPzgJ9nzqaIgMVb3 T2zwGz35JiE9XAu26NeMlvq+SbkW6GStwDmCq4zG25uhCwhwBymDvZ1WcSv4KH7BD3IcFNmC4 jREU9sHpvjvdtVHJY65GifXoiRDO9LPDnY+/AZevFf7EhDemBxy3uSUDhagIfLeP7vaPlgPqF twe93KL6zfQjLCE+pWIQsJ5pEdsrNrSufh13iZhcBgRYjnAaa7CIcghPh7Wvlj8+xNaf8DYAB cJ4r6YQm1bh7g8PtFUMmJmSCrS40BrJQd0S8Zdk709SD9vQW77hvoUT1RxDUo7JF1UZQaVex9 jFssT2VxpQg6ERKboV2redHWWJz0Brh5AZtspA5MhlKr9GT5Cg7WC4D8VnbOUKtVKFFJ3rztk R+tWLz/OXGfcqWxuQ7BGeX7/n8ydAlSjujxGJXmxb9Q2IyUfHFZWQpmQAUqwnnOjtOT8SdWa6 VDHVKmPSeYVtSjCH/ftbnO9VL0Pkca1onYqhcvsgeIP3TYq997kf9ZrasJ1Cxc14oj1tlog9C h0phFg4BdXGS3/v4lOiwZd4kjGJK5duKI7kFF/Nz+WNNepL/7AiLpiU5ajDM02MF3g//+87qu Hj90AsHJUVmfPQu+4BmjBV+CcRQlJeYk32bz6/pdxka0Tu24Q3syH0StZ4tnLmeAVVcSxVIie CS4FRAfg/wsws9+w0HVOJAmOkqXNUxGQJ2RaKxxahiv/aj5+QiWI3gDa29yUqVrd7MaMO2qon f1kbKJ8oIzKKACwpnlS0QzLil0nS1IGXuO1jYC657qzT3hj5P2B8L8tXBuagi/qP8ScDWKSv4 c/7A2Bx8AXu6ykaAD/q3RMzxhxGyKUsce+khQZFChN9Sytg5xoE2PM2YJqcOmUqWfVNtS1cWK DZa1+rpmC81det08tPqg== Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org This reverts commit f9065b54d437c4660e3d974ad9ce5188c068cd76. Signed-off-by: Lauri Kasanen --- arch/mips/Kconfig | 12 ++++++++++++ arch/mips/Makefile | 1 + arch/mips/include/asm/cpu-type.h | 5 +++++ arch/mips/include/asm/cpu.h | 2 +- arch/mips/include/asm/vermagic.h | 2 ++ arch/mips/kernel/cpu-probe.c | 9 +++++++++ arch/mips/kernel/idle.c | 1 + arch/mips/mm/c-r4k.c | 1 + arch/mips/mm/tlbex.c | 1 + 9 files changed, 33 insertions(+), 1 deletion(-) -- 2.6.2 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2000bb2..4b52588 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1661,6 +1661,15 @@ config CPU_VR41XX kernel built with this option will not run on any other type of processor or vice versa. +config CPU_R4300 + bool "R4300" + depends on SYS_HAS_CPU_R4300 + select CPU_SUPPORTS_32BIT_KERNEL + select CPU_SUPPORTS_64BIT_KERNEL + select CPU_HAS_LOAD_STORE_LR + help + MIPS Technologies R4300-series processors. + config CPU_R4X00 bool "R4x00" depends on SYS_HAS_CPU_R4X00 @@ -1995,6 +2004,9 @@ config SYS_HAS_CPU_TX39XX config SYS_HAS_CPU_VR41XX bool +config SYS_HAS_CPU_R4300 + bool + config SYS_HAS_CPU_R4X00 bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 0d0f29d..d7d8c20 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -141,6 +141,7 @@ cflags-y += -fno-stack-check # cflags-$(CONFIG_CPU_R3000) += -march=r3000 cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 +cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index 3288cef..2be5d7b 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -122,6 +122,11 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_VR4181A: #endif +#ifdef CONFIG_SYS_HAS_CPU_R4300 + case CPU_R4300: + case CPU_R4310: +#endif + #ifdef CONFIG_SYS_HAS_CPU_R4X00 case CPU_R4000PC: case CPU_R4000SC: diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index c9222cc..9e6211e 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -302,7 +302,7 @@ enum cpu_type_enum { /* * R4000 class processors */ - CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, + CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310, CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650, CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R10000, CPU_R12000, CPU_R14000, CPU_R16000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, diff --git a/arch/mips/include/asm/vermagic.h b/arch/mips/include/asm/vermagic.h index 4d2dae0..371c187 100644 --- a/arch/mips/include/asm/vermagic.h +++ b/arch/mips/include/asm/vermagic.h @@ -26,6 +26,8 @@ #define MODULE_PROC_FAMILY "TX39XX " #elif defined CONFIG_CPU_VR41XX #define MODULE_PROC_FAMILY "VR41XX " +#elif defined CONFIG_CPU_R4300 +#define MODULE_PROC_FAMILY "R4300 " #elif defined CONFIG_CPU_R4X00 #define MODULE_PROC_FAMILY "R4X00 " #elif defined CONFIG_CPU_TX49XX diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index e685369..84f7034 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1154,6 +1154,15 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) break; } break; + case PRID_IMP_R4300: + c->cputype = CPU_R4300; + __cpu_name[cpu] = "R4300"; + set_isa(c, MIPS_CPU_ISA_III); + c->fpu_msk31 |= FPU_CSR_CONDX; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; case PRID_IMP_R4600: c->cputype = CPU_R4600; __cpu_name[cpu] = "R4600"; diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 18e69eb..1aca3b4 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -151,6 +151,7 @@ void __init check_wait(void) cpu_wait = r39xx_wait; break; case CPU_R4200: +/* case CPU_R4300: */ case CPU_R4600: case CPU_R4640: case CPU_R4650: diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 9cede7c..da7796e 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1164,6 +1164,7 @@ static void probe_pcache(void) case CPU_R4400PC: case CPU_R4400SC: case CPU_R4400MC: + case CPU_R4300: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); c->icache.ways = 1; diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index a7521b8..0fb1db8 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -549,6 +549,7 @@ void build_tlb_write_entry(u32 **p, struct uasm_label **l, tlbw(p); break; + case CPU_R4300: case CPU_5KC: case CPU_TX49XX: case CPU_PR4450: From patchwork Fri Dec 25 17:00:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lauri Kasanen X-Patchwork-Id: 11990147 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FCE8C433E0 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EDE2A224B1 for ; Fri, 25 Dec 2020 17:05:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725995AbgLYRFl (ORCPT ); Fri, 25 Dec 2020 12:05:41 -0500 Received: from mout.gmx.net ([212.227.15.19]:38059 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725910AbgLYRFl (ORCPT ); Fri, 25 Dec 2020 12:05:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608915848; bh=/U79Em2ctFJzT+fmzS0aMR6P888RscDzAKcJlKZEkMI=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject; b=OfwXZD3VDU6ppsOJUFsMo6jDlAd0HZlCiHkD87fbUtjHSjoULl23LjlHm4v5Wexlm 4ClKIoenMia4BKqOodq+2ExTc9DjZnHnCCGgt5k3jBZSrps5lXaUCqacnXiMnq2vCO t7i9IQktTFW6cnWprNVaVvLxcd4apPFJGjbrRKsU= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Valinor ([82.128.181.212]) by mail.gmx.com (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MUGe1-1kSGz52YrL-00RIyr; Fri, 25 Dec 2020 18:04:08 +0100 Date: Fri, 25 Dec 2020 19:00:16 +0200 From: Lauri Kasanen To: linux-mips@vger.kernel.org Cc: tsbogend@alpha.franken.de Subject: [PATCH 2/6] mips: Add N64 machine type Message-Id: <20201225190016.286a0dfe49385f2bc39d04d4@gmx.com> X-Mailer: Sylpheed 3.5.0 (GTK+ 2.18.6; x86_64-unknown-linux-gnu) Mime-Version: 1.0 X-Provags-ID: V03:K1:lE4j6cFjs+P1HuonD+3Ey93+YZhCoD5F0s/+T0Xtd4cVGiAOiez heD/0W+NnIqYn+PGMvtoUbXg5vGQsrVYEciaYnx7Sq9dBXyOpoGz9F5Vh8eKa+VqCcpua9G rAozkgx958W8mA8SQaPT+UuGjpoPntwh8em1CMWo92g5bF/0lffiVc9qMaQPv14FQNyxf18 pLx94cuY5msLiFENQ3EMQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:yVYlYFcIi/Q=:1FsxoczhuWOk9TYxzy6Lii PvakDtd8X39oUvP5kybZWhz/PuIIKnGnGggJtUrxMxdZpdiDd8XWAXs/q/Hn9SEz7JNGlWyPU StkfrKpfuIjJ5p8wOc6r1eLBo94qiYkTIDSBZkdy8ureO+sGi/autVbddZwG2TMsw5c71u7vl wrD/9PehDUzpo69GZgz87Ro9K/wq1ejPSl869G9ln9bJjWQcmsXmHD6TuGM9iJ1xzLqdPoCpQ ZQKQYiTugGhdkIVKfFn7cRevXfvSRZEFX040Y89DLqPBLsbFpKH2Axb9OCKXBvegmGVPfcxNH NHZmvDaIJk0WRzJO85v3+hP7XtLpSuEwJmGLiWThkYBZWLaWJUUszvfd5FlvpPMfaX0j0Wc3u QFFzqiPTS/Jd0gCaxT2B5F0boNkpsUYz/tkDhsD8erro66AKglV6hjF2/n9ldsrZy+/hnPp0/ UkYGiWrdMHZ4JYzta9DkiAiXK2uLz/iDiXosP6pMNfUvlhTsaHfDWI69xsraLaDMDShDAhm2v wKuofsyqo3WuYEaQGwHfyY5FgipFX1omMbp64Yq347e3vn5VGzEwiwVL8N9hH7Xb5GGy1mSkw nnjQRHMxsvpzJT3Hyr6KcJZBUFuxFpel0fXckl7l3zKpufs2RNjLD/pvbD9WFIJ5JtoxIGOhU iqlODydFHKdvI8EuhpgDRpKHiLabBDsLwROM8uJ38S7jC3ExtTil1Whml7FGIRyl1dWefMJGj yvMBfNSjl/EuGOaaBXPLjsa970KeWlQgXpZ56Wmmkk/bpjg0ymAq7bSdCPRCfbKZhcmhjgosJ 9yCGrrW3dDZ1MuTHCPkCwigp26dSPXKm0f9l/2HEAB7JVPt/89XhGbYrlHuviQnXqEHyl7Kw3 AjGVGATApAIOou/IOAhA== Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Lauri Kasanen --- 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 | 59 ++++++++++++++++++++++++++++++++++++ arch/mips/n64/irq.c | 34 +++++++++++++++++++++ 8 files changed, 154 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 diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 5483e38..3e39590 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_MIPS_N64) += 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..2922bb6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -605,6 +605,18 @@ config MACH_VR41XX select SYS_SUPPORTS_MIPS16 select GPIOLIB +config MIPS_N64 + 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 /* for MIPS_CPU_IRQ_BASE */ + +#include + +#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..bf5edba --- /dev/null +++ b/arch/mips/n64/Platform @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Nintendo 64 +# + +cflags-$(CONFIG_MIPS_N64) += -I$(srctree)/arch/mips/include/asm/mach-n64 +load-$(CONFIG_MIPS_N64) += 0xffffffff80101000 diff --git a/arch/mips/n64/init.c b/arch/mips/n64/init.c new file mode 100644 index 0000000..6fb622d --- /dev/null +++ b/arch/mips/n64/init.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Nintendo 64 init. + * + * Copyright (C) 2020 Lauri Kasanen + */ +#include +#include +#include +#include +#include + +#include +#include + +#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) +{ + int argc, i; + const char **argv; + + argc = fw_arg0; + argv = (const char **)fw_arg1; + + for (i = 1; i < argc; i++) { + strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE); + if (i < (argc - 1)) + strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); + } +} + +void __init prom_free_prom_memory(void) +{ +} + +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..3eb0079 --- /dev/null +++ b/arch/mips/n64/irq.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * N64 IRQ + * + * Copyright (C) 2020 Lauri Kasanen + */ +#include +#include +#include + +#include + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & CAUSEF_IP7) + do_IRQ(TIMER_IRQ); + else if (pending & CAUSEF_IP4) + do_IRQ(PRENMI_IRQ); + else if (pending & CAUSEF_IP2) + do_IRQ(RCP_IRQ); + else if (pending & CAUSEF_IP0) + do_IRQ(MIPS_SOFTINT0_IRQ); + else if (pending & CAUSEF_IP1) + do_IRQ(MIPS_SOFTINT1_IRQ); + else + spurious_interrupt(); +} + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); +} From patchwork Fri Dec 25 17:00:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lauri Kasanen X-Patchwork-Id: 11990157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 391A1C433E9 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1147B22512 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726150AbgLYRFp (ORCPT ); Fri, 25 Dec 2020 12:05:45 -0500 Received: from mout.gmx.net ([212.227.15.18]:39507 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725910AbgLYRFo (ORCPT ); Fri, 25 Dec 2020 12:05:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608915850; bh=L3RQrOGSQQMeJpdUKYFS+8IVZLlMP5S50DxJVxCDMS0=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject; b=As0vPpO0kUAiPUS9kk8PdtZq8PvENphLt/HoZuLJpsE24ikOm9oegngRQcmuh8FCe qAgWgyC1xe3DdMbZmlkvTh+b7ZHLcZV3YZHcjySskCSJX8cDnzpJOY+vIqL0O7j61X oCmyGOHsRn39fe5qS8nUNp1bevh4OUR/dkfj/qsQ= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Valinor ([82.128.181.212]) by mail.gmx.com (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MrhUE-1kEJ6k0ClY-00nf9S; Fri, 25 Dec 2020 18:04:10 +0100 Date: Fri, 25 Dec 2020 19:00:48 +0200 From: Lauri Kasanen To: linux-mips@vger.kernel.org Cc: tsbogend@alpha.franken.de Subject: [PATCH 3/6] fbdev: Add n64rdp driver Message-Id: <20201225190048.776de55443fd4c953e797d8e@gmx.com> X-Mailer: Sylpheed 3.5.0 (GTK+ 2.18.6; x86_64-unknown-linux-gnu) Mime-Version: 1.0 X-Provags-ID: V03:K1:ZRMwGMAHQsqRuY82UxZB/VlykgMPbRnq9wccQKDEM5TgK5iEGa+ 7sCfr5R5smGyhZXlxKea3rzG3zXolFuqxSgM9tM6zQMyBkeVAxvN/Ck8m4pltJWPXnnRRRe XM268PgzxAK8EebA30UgmRmx25p+IYA0ePJBi6VtwLyLyJgbCRJyLtYuGMuvR60HmR/LXKI uksVQeQDe3eI35adN+TIg== X-UI-Out-Filterresults: notjunk:1;V03:K0:CPWejgR/RmM=:s3YXtOQtYlA+q63j5tYdtB 6CCdVkl5Hvz9N0mpgs0Xbj4/kmYQKzUWbXXTibzoIJpsp1lytdl/G/gRWHvzd2dpTTBgAKAgQ 0WxLV8oeRIQ4tAYSIqzs2BR063JQMANHn56IDz0T9+F11ZLu+3v4yT+iujf8IYVJ3/OPl272I IfLaA65YRgXECprjWm2RKVEXb9c53amB1yb4b0UMRdE+MRQHzixVu2A2R8OZmaPWOqNEnQ++3 2/afNYPihBLX7n1XjpPLA4C8nfYD4ivDDT31+XnOKC9SptEixsrPL6iV3iSQ9htUV/SxEQr5G l7wtjfJUJl+gcxfdUdhBV10W8p2sNkIDvKXFH/HIqFs3p7S/vWdNRQP7fQTNewIaTdWocpWhW GxzG64pRv4wX/q36qIH6Yqw5dfq5HPrs6Q/J5faF2dcwgHlrl8Cz9hBkyMen1VYcr0qoJNffz ewaMZHFDyTIQWAFel5slVnm6HTkWghykOLa5yTojOPxVvxZah84PhZUzk1gWaJvEMQ64AEtRC hpz3yzvV9qm7xmYu6AzFJq7k6m3fWzRXm34OiLZ2VpBaCZWiEp9aRO1sJwepJwHQzyiNHnqb7 6WMDkSiezbCGAy1hF5ExrvBjLLlTqTdWgGED80KAcpXDtvwbHEe4U8bBQ5vxfvbwEoUdyKKtT 2ULJm0TqoY4bv52mFWwTpz6YH5vCsYvHuuiVfKqsGAE4y7Gs8jDaDBtg2cIcE4vGiGdfRJ1U2 XPVLmt3PEt0GTHmmqPqntGe2hHVgcu9hcVIg8DBUCM0gW+ozD1SdYdLzBl1m6NJozxt6wM52N VY9aZ8HLn9eDSKZqtJn5ZZhbr4ar6CZ+pDtPkQcdGOxKgpwEVcOGl2oyqG2nIJqG7K2o+E1pU 8aZUUfLo8nhf6v6gIJGQ== Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org I'm aware of the drm-fbdev resolution, but CONFIG_DRM adds 100kb, which is a complete blocker on a system with 8mb RAM. Signed-off-by: Lauri Kasanen --- arch/mips/n64/init.c | 10 +++ drivers/video/fbdev/Kconfig | 9 ++ drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/n64rdp.c | 190 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 drivers/video/fbdev/n64rdp.c -- 2.6.2 diff --git a/arch/mips/n64/init.c b/arch/mips/n64/init.c index 6fb622d..635e9ef 100644 --- a/arch/mips/n64/init.c +++ b/arch/mips/n64/init.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,15 @@ void __init prom_free_prom_memory(void) { } +static int __init n64_platform_init(void) +{ + platform_device_register_simple("n64rdp", -1, NULL, 0); + + return 0; +} + +arch_initcall(n64_platform_init); + void __init plat_mem_setup(void) { iomem_resource_init(); diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index cfb7f56..4dde2c7 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2206,6 +2206,15 @@ config FB_SIMPLE Configuration re: surface address, size, and format must be provided through device tree, or plain old platform data. +config FB_N64RDP + bool "Nintendo 64 RDP support" + depends on (FB = y) && MIPS_N64 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Driver for the N64's display. + config FB_SSD1307 tristate "Solomon SSD1307 framebuffer support" depends on FB && I2C diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 477b962..86f1e22 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -129,6 +129,7 @@ obj-$(CONFIG_FB_MX3) += mx3fb.o obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o obj-$(CONFIG_FB_SIMPLE) += simplefb.o +obj-$(CONFIG_FB_N64RDP) += n64rdp.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/fbdev/n64rdp.c b/drivers/video/fbdev/n64rdp.c new file mode 100644 index 0000000..e5456b6 --- /dev/null +++ b/drivers/video/fbdev/n64rdp.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DRM driver for the N64's RDP + * + * Copyright (c) 2020 Lauri Kasanen + * + * Based on simplefb.c, which was: + * Copyright (c) 2013, Stephen Warren + * + * Based on q40fb.c, which was: + * Copyright (C) 2001 Richard Zidlicky + * + * Also based on offb.c, which was: + * Copyright (C) 1997 Geert Uytterhoeven + * Copyright (C) 1996 Paul Mackerras + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static const struct fb_fix_screeninfo n64rdp_fix = { + .id = "default", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .accel = FB_ACCEL_NONE, +}; + +static const struct fb_var_screeninfo n64rdp_var = { + .height = -1, + .width = -1, + .activate = FB_ACTIVATE_NOW, + .vmode = FB_VMODE_NONINTERLACED, +}; + +#define PSEUDO_PALETTE_SIZE 16 + +static int n64rdp_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info) +{ + u32 *pal = info->pseudo_palette; + u32 cr = red >> (16 - info->var.red.length); + u32 cg = green >> (16 - info->var.green.length); + u32 cb = blue >> (16 - info->var.blue.length); + u32 value; + + if (regno >= PSEUDO_PALETTE_SIZE) + return -EINVAL; + + value = (cr << info->var.red.offset) | + (cg << info->var.green.offset) | + (cb << info->var.blue.offset); + if (info->var.transp.length > 0) { + u32 mask = (1 << info->var.transp.length) - 1; + mask <<= info->var.transp.offset; + value |= mask; + } + pal[regno] = value; + + return 0; +} + +static const struct fb_ops n64rdp_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = n64rdp_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +struct n64rdp_par { + u32 palette[PSEUDO_PALETTE_SIZE]; + dma_addr_t physaddr; +}; + +#define REG_BASE ((u32 *) CKSEG1ADDR(0xA4400000)) + +static void n64rdp_write_reg(const u8 reg, const u32 value) +{ + __raw_writel(value, REG_BASE + reg); +} + +#define W 320 +#define H 240 + +static const u32 ntsc_320[] __initconst = { + 0x00013212, 0x00000000, 0x00000140, 0x00000200, + 0x00000000, 0x03e52239, 0x0000020d, 0x00000c15, + 0x0c150c15, 0x006c02ec, 0x002501ff, 0x000e0204, + 0x00000200, 0x00000400 +}; + +static int __init n64rdp_probe(struct platform_device *pdev) +{ + int ret; + u32 i; + struct fb_info *info; + struct n64rdp_par *par; + dma_addr_t addr; + + info = framebuffer_alloc(sizeof(struct n64rdp_par), &pdev->dev); + if (!info) + return -ENOMEM; + platform_set_drvdata(pdev, info); + + par = info->par; + + info->fix = n64rdp_fix; + info->screen_base = dma_alloc_coherent(&pdev->dev, W * H * 2, &addr, + GFP_DMA | GFP_KERNEL); + if (!info->screen_base) + return -ENOMEM; + + info->fix.smem_start = par->physaddr = addr; + info->fix.smem_len = W * H * 2; + info->fix.line_length = W * 2; + + info->var = n64rdp_var; + info->var.xres = W; + info->var.yres = H; + info->var.xres_virtual = W; + info->var.yres_virtual = H; + info->var.bits_per_pixel = 16; + info->var.red = (struct fb_bitfield) {11, 5}; + info->var.green = (struct fb_bitfield) {6, 5}; + info->var.blue = (struct fb_bitfield) {1, 5}; + info->var.transp = (struct fb_bitfield) {0, 1}; + + info->apertures = alloc_apertures(1); + if (!info->apertures) { + ret = -ENOMEM; + goto error_fb_release; + } + info->apertures->ranges[0].base = info->fix.smem_start; + info->apertures->ranges[0].size = info->fix.smem_len; + + info->fbops = &n64rdp_ops; + info->flags = FBINFO_DEFAULT; + info->pseudo_palette = par->palette; + + dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n", + info->fix.smem_start, info->fix.smem_len, + info->screen_base); + + ret = register_framebuffer(info); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to register n64rdp: %d\n", ret); + goto error_fb_release; + } + + for (i = 0; i < ARRAY_SIZE(ntsc_320); i++) { + if (i == 1) + n64rdp_write_reg(i, par->physaddr); + else + n64rdp_write_reg(i, ntsc_320[i]); + } + + return 0; + +error_fb_release: + framebuffer_release(info); + return ret; +} + +static struct platform_driver n64rdp_driver = { + .driver = { + .name = "n64rdp", + }, +}; + +static int __init n64rdp_init(void) +{ + int ret; + + ret = platform_driver_probe(&n64rdp_driver, n64rdp_probe); + + return ret; +} + +fs_initcall(n64rdp_init); + +MODULE_AUTHOR("Lauri Kasanen "); +MODULE_DESCRIPTION("Driver for the N64's display"); +MODULE_LICENSE("GPL v2"); From patchwork Fri Dec 25 17:01:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lauri Kasanen X-Patchwork-Id: 11990153 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56589C433E6 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 28F3D22285 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725910AbgLYRFq (ORCPT ); Fri, 25 Dec 2020 12:05:46 -0500 Received: from mout.gmx.net ([212.227.15.19]:45269 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726091AbgLYRFo (ORCPT ); Fri, 25 Dec 2020 12:05:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608915851; bh=cr4PYSAp9GNLzC9cvI+9A9WkW5Oj5yyyqtCSrYvHJoQ=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject; b=K5ENOiohs1X0ljV2EfqLL9EOw76/TIUXJHDhi4pXCf1+m7GfI7oCLfR9m+YclCCSl o5rvAiiL4fdsEiP8WA+ObTwdvHHbpiBriSjrm4qRVVAwvl+0SiW8Pf1Yor8rTm4/1J DtJvISC/xwnDlNvb/H6jBRoDw3+xfDM7LsnjhjmE= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Valinor ([82.128.181.212]) by mail.gmx.com (mrgmx004 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MbAcs-1kLyb51Unw-00bYEm; Fri, 25 Dec 2020 18:04:11 +0100 Date: Fri, 25 Dec 2020 19:01:15 +0200 From: Lauri Kasanen To: linux-mips@vger.kernel.org Cc: tsbogend@alpha.franken.de Subject: [PATCH 4/6] input: Add N64 controller driver Message-Id: <20201225190115.efa38e5a0107bec09f993ed6@gmx.com> X-Mailer: Sylpheed 3.5.0 (GTK+ 2.18.6; x86_64-unknown-linux-gnu) Mime-Version: 1.0 X-Provags-ID: V03:K1:Gj308YDFf3ZDvf+pOrLf+ZRZpCoDJGnmjSzwSCAKGlNBUmoNMq9 AU093vdgZG0gTHdeyCR6ZwAlYfYFWnG1MImEaBJhk+qD6PliyGHmgviNjDx7IWLcDE7utHy Il2W0nzTdtxI7IKJh7qyi/AuSeXKA730dm6QsFhSrx+0sY8YR4Jjf9tstSNI/GHK/ituVOx rp1MoHPxwtT5LlX6MA2Rw== X-UI-Out-Filterresults: notjunk:1;V03:K0:MvLAmSbye9Y=:dIEloSbCkJusoICh7x3IVO vdBM8Lcfc/lpobzWNuzku8Tpz/PXhIRi+uenO1zI/lfMiFIcjSUz3H/ug9adwHM6+bYrmJc+c +9okggipaGtooLvW47GjfgZwYZiIrL4GOzHT+8UU9cGleRJ8+RnWwL6U2m4D5VLUAdv9PSNF4 0dz2lnlC6dv1j4ZJ+36iOlzJMTg021mjkg9OLb2Iz0r6NsoUXsJlujK1EKCSfI/m4dsvgfGZ3 fz3vz28pSzd2b7vC9NHuTm1IrnKkx6QZz7wh8ymxSeuk4bOMdRg7awn0CRbLar+o0rOiSAN/h k0m6QZWNa2B0KZJtlYpN84gZfwjafHQUqAsnSi42zWhCkYBoWImbIuK5WWZt0fU47daM8L8RK nAxFaUH1ye18HCc3iBYizSwATojbMKYJxEnFH+3QvDFk3R83jjeT1EhtM8Faz28IK7GlYnrZ8 /dmZ0U17IUql2J9qxtE2/hUDdSousYzpl1Yd6a73oXMKcAlHaHnE9iEzV+DcrfO7KxpyjcAJA Mg9TC8iVdn6rKT+cfBYgP/k3wMSIToYEku6VPo2LExJbBE+H0ujN9XOPBz/vsH6Afrs8Ouiit 4Rh9qrhgjDdJINWR7ZOV9z4nqByf3X+yFy5O3s5K2lgFiPNSCejU5DfeoZ2lhFI6gQqk1dD1u v4hsJh79Gy/cXOnboIDzMJ5Lqms8UR4fI/BJrwLf5+KTvbyZ/IwOgX1gQb8rXnRqiB9sEbvD7 cNrus1jYI9M0eZuH985U3W9+Tjcm6UodDWzoGS5ROlvCdy1ty2GelO++EQhobsVr8TcG35FSf EycbG1mLgxtHAob57O1q3N8sqhIR0oQFNrxsrS32P+7HWhIDqb/SwRS0F/1FEQVggU9UqRD2i sdEBChQbwDdyb9l6Q2vg== Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Lauri Kasanen --- drivers/input/joystick/Kconfig | 6 + drivers/input/joystick/Makefile | 2 +- drivers/input/joystick/n64joy.c | 300 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 drivers/input/joystick/n64joy.c -- 2.6.2 diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index b080f0c..b5098fb 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -382,4 +382,10 @@ config JOYSTICK_FSIA6B To compile this driver as a module, choose M here: the module will be called fsia6b. +config JOYSTICK_N64 + bool "N64 controller" + depends on MIPS_N64 + help + Support for the four N64 controllers. + endif diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile index 58232b3..31d720c 100644 --- a/drivers/input/joystick/Makefile +++ b/drivers/input/joystick/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_JOYSTICK_INTERACT) += interact.o obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o +obj-$(CONFIG_JOYSTICK_N64) += n64joy.o obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o @@ -37,4 +38,3 @@ obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o obj-$(CONFIG_JOYSTICK_WALKERA0701) += walkera0701.o obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o - diff --git a/drivers/input/joystick/n64joy.c b/drivers/input/joystick/n64joy.c new file mode 100644 index 0000000..fbf3686 --- /dev/null +++ b/drivers/input/joystick/n64joy.c @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for the four N64 controllers. + * + * Copyright (c) 2020 Lauri Kasanen + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Lauri Kasanen "); +MODULE_DESCRIPTION("Driver for N64 controllers"); +MODULE_LICENSE("GPL"); + +#define PIF_RAM 0x1fc007c0 +#define REG_BASE ((u32 *) CKSEG1ADDR(0xa4800000)) + +#define SI_DRAM_REG 0 +#define SI_READ_REG 1 +#define SI_WRITE_REG 4 +#define SI_STATUS_REG 6 + +#define SI_STATUS_DMA_BUSY (1 << 0) +#define SI_STATUS_IO_BUSY (1 << 1) + +#define N64_CONTROLLER_ID 0x0500 + +static struct input_dev *n64joy_dev[4]; +static const char *n64joy_phys[4] = { + "n64joy/port0", + "n64joy/port1", + "n64joy/port2", + "n64joy/port3", +}; + +static u8 n64joy_opened; +static DEFINE_MUTEX(n64joy_mutex); +static struct timer_list timer; + +static u64 si_buf[8] ____cacheline_aligned; + +struct joydata { + unsigned: 16; // unused + unsigned err: 2; + unsigned: 14; // unused + + union { + u32 data; + + struct { + unsigned a: 1; + unsigned b: 1; + unsigned z: 1; + unsigned start: 1; + unsigned up: 1; + unsigned down: 1; + unsigned left: 1; + unsigned right: 1; + unsigned: 2; // unused + unsigned l: 1; + unsigned r: 1; + unsigned c_up: 1; + unsigned c_down: 1; + unsigned c_left: 1; + unsigned c_right: 1; + signed x: 8; + signed y: 8; + }; + }; +}; + +static void n64joy_write_reg(const u8 reg, const u32 value) +{ + __raw_writel(value, REG_BASE + reg); +} + +static u32 n64joy_read_reg(const u8 reg) +{ + return __raw_readl(REG_BASE + reg); +} + +static void n64joy_wait_si_dma(void) +{ + while (n64joy_read_reg(SI_STATUS_REG) & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_BUSY)) + ; +} + +static void n64joy_exec_pif(const u64 in[8]) +{ + unsigned long flags; + + dma_cache_wback_inv((unsigned long) in, 8 * 8); + dma_cache_inv((unsigned long) si_buf, 8 * 8); + + local_irq_save(flags); + + n64joy_wait_si_dma(); + + barrier(); + n64joy_write_reg(SI_DRAM_REG, virt_to_phys(in)); + barrier(); + n64joy_write_reg(SI_WRITE_REG, PIF_RAM); + barrier(); + + n64joy_wait_si_dma(); + + barrier(); + n64joy_write_reg(SI_DRAM_REG, virt_to_phys(si_buf)); + barrier(); + n64joy_write_reg(SI_READ_REG, PIF_RAM); + barrier(); + + n64joy_wait_si_dma(); + + local_irq_restore(flags); +} + +static const u64 polldata[] ____cacheline_aligned = { + 0xff010401ffffffff, + 0xff010401ffffffff, + 0xff010401ffffffff, + 0xff010401ffffffff, + 0xfe00000000000000, + 0, + 0, + 1 +}; + +static void n64joy_poll(struct timer_list *t) +{ + const struct joydata *data; + u32 i; + + n64joy_exec_pif(polldata); + + data = (struct joydata *) si_buf; + + for (i = 0; i < 4; i++) { + if (!n64joy_dev[i]) + continue; + + // d-pad + input_report_key(n64joy_dev[i], BTN_DPAD_UP, data[i].up); + input_report_key(n64joy_dev[i], BTN_DPAD_DOWN, data[i].down); + input_report_key(n64joy_dev[i], BTN_DPAD_LEFT, data[i].left); + input_report_key(n64joy_dev[i], BTN_DPAD_RIGHT, data[i].right); + + // c buttons + input_report_key(n64joy_dev[i], BTN_FORWARD, data[i].c_up); + input_report_key(n64joy_dev[i], BTN_BACK, data[i].c_down); + input_report_key(n64joy_dev[i], BTN_LEFT, data[i].c_left); + input_report_key(n64joy_dev[i], BTN_RIGHT, data[i].c_right); + + // matching buttons + input_report_key(n64joy_dev[i], BTN_START, data[i].start); + input_report_key(n64joy_dev[i], BTN_Z, data[i].z); + + // remaining ones: a, b, l, r + input_report_key(n64joy_dev[i], BTN_0, data[i].a); + input_report_key(n64joy_dev[i], BTN_1, data[i].b); + input_report_key(n64joy_dev[i], BTN_2, data[i].l); + input_report_key(n64joy_dev[i], BTN_3, data[i].r); + + input_report_abs(n64joy_dev[i], ABS_X, data[i].x); + input_report_abs(n64joy_dev[i], ABS_Y, data[i].y); + + input_sync(n64joy_dev[i]); + } + + mod_timer(&timer, jiffies + msecs_to_jiffies(16)); +} + +static int n64joy_open(struct input_dev *dev) +{ + int err; + + err = mutex_lock_interruptible(&n64joy_mutex); + if (err) + return err; + + if (!n64joy_opened) { + // Could use the vblank irq, but it's not important if the poll + // point slightly changes. + timer_setup(&timer, n64joy_poll, 0); + mod_timer(&timer, jiffies + msecs_to_jiffies(16)); + } + + n64joy_opened++; + + mutex_unlock(&n64joy_mutex); + return err; +} + +static void n64joy_close(struct input_dev *dev) +{ + mutex_lock(&n64joy_mutex); + if (!--n64joy_opened) + del_timer_sync(&timer); + mutex_unlock(&n64joy_mutex); +} + +static const u64 __initconst scandata[] ____cacheline_aligned = { + 0xff010300ffffffff, + 0xff010300ffffffff, + 0xff010300ffffffff, + 0xff010300ffffffff, + 0xfe00000000000000, + 0, + 0, + 1 +}; + +static int __init n64joy_init(void) +{ + const struct joydata *data; + int err = 0; + u32 i, j, found = 0; + + // The controllers are not hotpluggable, so we can scan in init + n64joy_exec_pif(scandata); + + data = (struct joydata *) si_buf; + + memset(n64joy_dev, 0, 4 * sizeof(void *)); + + for (i = 0; i < 4; i++) { + if (!data[i].err && data[i].data >> 16 == N64_CONTROLLER_ID) { + found++; + + n64joy_dev[i] = input_allocate_device(); + if (!n64joy_dev[i]) { + err = -ENOMEM; + goto fail; + } + + n64joy_dev[i]->name = "N64 controller"; + n64joy_dev[i]->phys = n64joy_phys[i]; + n64joy_dev[i]->id.bustype = BUS_HOST; + n64joy_dev[i]->id.vendor = 0; + n64joy_dev[i]->id.product = data[i].data >> 16; + n64joy_dev[i]->id.version = 0; + + n64joy_dev[i]->open = n64joy_open; + n64joy_dev[i]->close = n64joy_close; + + n64joy_dev[i]->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + n64joy_dev[i]->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); + + // d-pad + n64joy_dev[i]->keybit[BIT_WORD(BTN_DPAD_UP)] = BIT_MASK(BTN_DPAD_UP) | + BIT_MASK(BTN_DPAD_DOWN) | BIT_MASK(BTN_DPAD_LEFT) | + BIT_MASK(BTN_DPAD_RIGHT); + // c buttons + n64joy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | + BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_FORWARD) | BIT_MASK(BTN_BACK); + // matching buttons + n64joy_dev[i]->keybit[BIT_WORD(BTN_GAMEPAD)] |= BIT_MASK(BTN_START) | + BIT_MASK(BTN_Z); + // remaining ones: a, b, l, r + n64joy_dev[i]->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0) | + BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); + + for (j = 0; j < 2; j++) { + input_set_abs_params(n64joy_dev[i], ABS_X + j, + S8_MIN, S8_MAX, 0, 0); + } + + err = input_register_device(n64joy_dev[i]); + if (err) { + input_free_device(n64joy_dev[i]); + goto fail; + } + } + } + + pr_info("n64joy: %u controller(s) connected\n", found); + + if (!found) + return -ENODEV; + + return 0; +fail: + for (i = 0; i < 4; i++) { + if (!n64joy_dev[i]) + continue; + input_unregister_device(n64joy_dev[i]); + } + return err; +} + +module_init(n64joy_init); From patchwork Fri Dec 25 17:01:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lauri Kasanen X-Patchwork-Id: 11990151 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73337C43381 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 48AB822512 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725856AbgLYRFq (ORCPT ); Fri, 25 Dec 2020 12:05:46 -0500 Received: from mout.gmx.net ([212.227.17.20]:40137 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726126AbgLYRFp (ORCPT ); Fri, 25 Dec 2020 12:05:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608915853; bh=CdGhIVN4H+toUYIqPzciwcfWUin4ZDY4mVXlCIALtzw=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject; b=YtO7l4l3QOw+G44mg+FFGjS45tMg6PnHGqAEXLPfvBpE8q6y9VgteGOAZiCOBkRCy WDNzuvHwRZRJSWYE3GToHejLmNCtMnfQCuooPoe5lCimsqJjhs411hQVgEmNJHpkyM cepxzpVNEPjTIf0zezHzsh5JdvXUN0obxbCwc1h8= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Valinor ([82.128.181.212]) by mail.gmx.com (mrgmx105 [212.227.17.174]) with ESMTPSA (Nemesis) id 1MkHMP-1kDU9d3sev-00kfXM; Fri, 25 Dec 2020 18:04:13 +0100 Date: Fri, 25 Dec 2020 19:01:38 +0200 From: Lauri Kasanen To: linux-mips@vger.kernel.org Cc: tsbogend@alpha.franken.de Subject: [PATCH 5/6] sound: Add n64 driver Message-Id: <20201225190138.82003a392c86f08352aca998@gmx.com> X-Mailer: Sylpheed 3.5.0 (GTK+ 2.18.6; x86_64-unknown-linux-gnu) Mime-Version: 1.0 X-Provags-ID: V03:K1:iVoOWWqbE8f8atITOkrrG8wSmh8NKnwG+0wD4op+RB/Kl8YUSzO Bqmbk8k3SNY1muESztmqU8eFTMcOc0BPvlrI+BELQmqhg3gA5qv+zWaBbt0qzokZqM4KOyO 96AIzfxBJ+ZgCnZDc8+jUoH9qUWnKj/dtOf+99fWvT4zbsq/4DC6EJAxpKCRuaUyNYq5MtL dkPFQ77+uH/YvWk/XAgVQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:LV2Mw2j7hCQ=:Rr7KA8oCGV0dJWHv14blyT TGAg6ZMGd0OTbBBZxTU88X885N6tyk/tDKCQq3XzyAXjPqGleGNMZoCaF7zmBlvdqyRBTYh8L 4K5hM59jB4kt/GTcbjH6sYodT8IEStBOhBM036uf+gn5jea0FBT6Ia+tVNu4dN2/5D+sVaOqY rLtlgbLqHYK9gnzUXt0Rx9G8wY1eL06snQd+d3e5Ex8Hb3TMo5BFBLGEh1Gq3bP5Ktz0cI79R 8EwNRPbHMiBs9sAXPIKBaDDYyqNElDZQt+gwaMHgHfilsXNdm7w+txoCYIh3KJIEpYq52DICY l2M+yDF5nTI90C1yIohH1PXamxN/3rvVxW7k1I69UvTcOSQIa1wT7ac5xBAvhpF29d6t3h47o 3aFV2WVvx+v0CR409eMa3JbjSb7fOCejdf3JoeOFLH9K8S41zjRsXITFulBGCVevx9dOKK7In VDteu388zFLo0YOOjnJyFSRN56iYIEHJdqf6vUr9TPqxmtyEc7vmg7hfNUJF90UyEacv+He3P ffhYduiINghbeXoWTmc92v3+C0CZ42eFUTzkAj4Gfdcj5zzvvFU0ZXul4BllfdRmFoic0IQgC cYfiHpa5wTRJXT3gJzf1pwOWwJfvuCmXq/Lb+no/dcw4nssYSBtJLesmj7AScmuFxfcStGiX6 08VJ2e8Mf7RIiNUCzFRicAJZ1Y6WVGOyzVTZ/qs8XYyTQsJ93ijk8Xw/2D24ZMjgZ+cPAO3OP aZLLJugvXMVUDQCKEtnzGmPugR/7bXYtPedsfQd/SdFLvFKfOvyW01rgXwsPcFbQewPPTfZSh H7Kx/iO8FsmjvN5IjgBJezFA+jmIyINe3zkVa6LgitUKMz5tzCX884vRyQYqXeu9rD/p/QYka tOnSWN2mpLYOk5p1t9MA== Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The sound DMA unit has errata on certain alignments, which is why we can't use alsa's DMA buffer directly. Signed-off-by: Lauri Kasanen --- arch/mips/n64/init.c | 1 + sound/mips/Kconfig | 7 ++ sound/mips/Makefile | 1 + sound/mips/snd-n64.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 306 insertions(+) create mode 100644 sound/mips/snd-n64.c -- 2.6.2 diff --git a/arch/mips/n64/init.c b/arch/mips/n64/init.c index 635e9ef..0f82a409 100644 --- a/arch/mips/n64/init.c +++ b/arch/mips/n64/init.c @@ -50,6 +50,7 @@ void __init prom_free_prom_memory(void) static int __init n64_platform_init(void) { platform_device_register_simple("n64rdp", -1, NULL, 0); + platform_device_register_simple("n64audio", -1, NULL, 0); return 0; } diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig index b497b80..f37ad92 100644 --- a/sound/mips/Kconfig +++ b/sound/mips/Kconfig @@ -24,5 +24,12 @@ config SND_SGI_HAL2 help Sound support for the SGI Indy and Indigo2 Workstation. +config SND_N64 + bool "N64 Audio" + depends on MIPS_N64 + select SND_PCM + help + Sound support for the N64. + endif # SND_MIPS diff --git a/sound/mips/Makefile b/sound/mips/Makefile index ccc364e..7c86268 100644 --- a/sound/mips/Makefile +++ b/sound/mips/Makefile @@ -9,3 +9,4 @@ snd-sgi-hal2-objs := hal2.o # Toplevel Module Dependency obj-$(CONFIG_SND_SGI_O2) += snd-sgi-o2.o obj-$(CONFIG_SND_SGI_HAL2) += snd-sgi-hal2.o +obj-$(CONFIG_SND_N64) += snd-n64.o diff --git a/sound/mips/snd-n64.c b/sound/mips/snd-n64.c new file mode 100644 index 0000000..84fa752 --- /dev/null +++ b/sound/mips/snd-n64.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sound driver for Nintendo 64. + * + * Copyright 2020 Lauri Kasanen + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Lauri Kasanen "); +MODULE_DESCRIPTION("N64 Audio"); +MODULE_LICENSE("GPL"); + +#define AI_NTSC_DACRATE 48681812 +#define AI_STATUS_BUSY (1 << 30) +#define AI_STATUS_FULL (1 << 31) + +#define REG_BASE ((u32 *) CKSEG1ADDR(0xa4500000)) + +#define AI_ADDR_REG 0 +#define AI_LEN_REG 1 +#define AI_CONTROL_REG 2 +#define AI_STATUS_REG 3 +#define AI_RATE_REG 4 +#define AI_BITCLOCK_REG 5 + +#define MI_REG_BASE ((u32 *) CKSEG1ADDR(0xa4300000)) + +#define MI_INTR_REG 2 +#define MI_MASK_REG 3 + +#define MI_INTR_AI 0x04 + +#define MI_MASK_CLR_AI 0x0010 +#define MI_MASK_SET_AI 0x0020 + + +struct n64audio_t { + struct snd_card *card; + + void *ring_base; + dma_addr_t ring_base_dma; + + struct { + struct snd_pcm_substream *substream; + int pos, nextpos; + u32 writesize; + u32 bufsize; + spinlock_t lock; + } chan; +}; + +static void n64audio_write_reg(const u8 reg, const u32 value) +{ + __raw_writel(value, REG_BASE + reg); +} + +static void n64mi_write_reg(const u8 reg, const u32 value) +{ + __raw_writel(value, MI_REG_BASE + reg); +} + +static u32 n64mi_read_reg(const u8 reg) +{ + return __raw_readl(MI_REG_BASE + reg); +} + +static void n64audio_push(struct n64audio_t *priv, uint8_t irq) +{ + struct snd_pcm_runtime *runtime = priv->chan.substream->runtime; + unsigned long flags; + u32 count; + + count = priv->chan.writesize; + count &= ~7; + + spin_lock_irqsave(&priv->chan.lock, flags); + + memcpy(priv->ring_base, runtime->dma_area + priv->chan.nextpos, count); + + n64audio_write_reg(AI_ADDR_REG, priv->ring_base_dma); + n64audio_write_reg(AI_LEN_REG, count); + + priv->chan.nextpos += count; + priv->chan.nextpos %= priv->chan.bufsize; + if (irq) + priv->chan.pos = priv->chan.nextpos; + + spin_unlock_irqrestore(&priv->chan.lock, flags); +} + +static irqreturn_t n64audio_isr(int irq, void *dev_id) +{ + struct n64audio_t *priv = dev_id; + + // Check it's ours + const u32 intrs = n64mi_read_reg(MI_INTR_REG); + if (!(intrs & MI_INTR_AI)) + return IRQ_NONE; + + n64audio_write_reg(AI_STATUS_REG, 1); + + n64audio_push(priv, 1); + snd_pcm_period_elapsed(priv->chan.substream); + + return IRQ_HANDLED; +} + +static const struct snd_pcm_hardware n64audio_pcm_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER), + .formats = SNDRV_PCM_FMTBIT_S16_BE, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 32768, + .period_bytes_min = 1024, + .period_bytes_max = 32768, + .periods_min = 1, + .periods_max = 128, +}; + +static int n64audio_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw = n64audio_pcm_hw; + return 0; +} + +static int n64audio_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct n64audio_t *priv = substream->pcm->private_data; + unsigned long flags; + u32 rate; + + rate = ((2 * AI_NTSC_DACRATE / runtime->rate) + 1) / 2 - 1; + + n64audio_write_reg(AI_RATE_REG, rate); + + rate /= 66; + if (rate > 16) + rate = 16; + n64audio_write_reg(AI_BITCLOCK_REG, rate - 1); + + spin_lock_irqsave(&priv->chan.lock, flags); + + /* Setup the pseudo-dma transfer pointers. */ + priv->chan.pos = 0; + priv->chan.nextpos = 0; + priv->chan.substream = substream; + priv->chan.writesize = snd_pcm_lib_period_bytes(substream); + priv->chan.bufsize = snd_pcm_lib_buffer_bytes(substream); + + spin_unlock_irqrestore(&priv->chan.lock, flags); + return 0; +} + +static int n64audio_pcm_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + n64audio_push(substream->pcm->private_data, 0); + n64audio_write_reg(AI_CONTROL_REG, 1); + n64mi_write_reg(MI_MASK_REG, MI_MASK_SET_AI); + break; + case SNDRV_PCM_TRIGGER_STOP: + n64audio_write_reg(AI_CONTROL_REG, 0); + n64mi_write_reg(MI_MASK_REG, MI_MASK_CLR_AI); + break; + default: + return -EINVAL; + } + return 0; +} + +static snd_pcm_uframes_t n64audio_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct n64audio_t *priv = substream->pcm->private_data; + + return bytes_to_frames(substream->runtime, + priv->chan.pos); +} + +static int n64audio_pcm_close(struct snd_pcm_substream *substream) +{ + return 0; // Nothing to do, but the kernel crashes if close() doesn't exist +} + +static const struct snd_pcm_ops n64audio_pcm_ops = { + .open = n64audio_pcm_open, + .prepare = n64audio_pcm_prepare, + .trigger = n64audio_pcm_trigger, + .pointer = n64audio_pcm_pointer, + .close = n64audio_pcm_close, +}; + +static int __init n64audio_probe(struct platform_device *pdev) +{ + struct snd_card *card; + struct snd_pcm *pcm; + struct n64audio_t *priv; + int err; + + err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, + SNDRV_DEFAULT_STR1, + THIS_MODULE, 0, &card); + if (err < 0) + return err; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (priv == NULL) { + err = -ENOMEM; + goto fail_card; + } + + priv->card = card; + priv->ring_base = dma_alloc_coherent(card->dev, 32 * 1024, + &priv->ring_base_dma, + GFP_DMA | GFP_KERNEL); + if (!priv->ring_base) + goto fail_alloc; + + if (request_irq(RCP_IRQ, n64audio_isr, + IRQF_SHARED, "N64 Audio", priv)) { + err = -EBUSY; + goto fail_alloc; + } + + spin_lock_init(&priv->chan.lock); + + err = snd_pcm_new(card, "N64 Audio", 0, 1, 0, &pcm); + if (err < 0) + goto fail_alloc; + + pcm->private_data = priv; + strcpy(pcm->name, "N64 Audio"); + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &n64audio_pcm_ops); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); + + strcpy(card->driver, "N64 Audio"); + strcpy(card->shortname, "N64 Audio"); + strcpy(card->longname, "N64 Audio"); + + err = snd_card_register(card); + if (err < 0) + goto fail_alloc; + + platform_set_drvdata(pdev, priv); + + return 0; + +fail_alloc: + kfree(priv); + +fail_card: + snd_card_free(card); + return err; +} + +static struct platform_driver n64audio_driver = { + .driver = { + .name = "n64audio", + }, +}; + +static int __init n64audio_init(void) +{ + int ret; + + ret = platform_driver_probe(&n64audio_driver, n64audio_probe); + + return ret; +} + +fs_initcall(n64audio_init); From patchwork Fri Dec 25 17:01:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lauri Kasanen X-Patchwork-Id: 11990155 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8113BC4332B for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5F80722795 for ; Fri, 25 Dec 2020 17:05:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725953AbgLYRFr (ORCPT ); Fri, 25 Dec 2020 12:05:47 -0500 Received: from mout.gmx.net ([212.227.17.22]:41023 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726164AbgLYRFr (ORCPT ); Fri, 25 Dec 2020 12:05:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608915854; bh=w7OHd5Xbuoj7IWGUrgbsqC8PhQlGXU05DPLOUYyzVNY=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject; b=AYwAfuEpORCp9riZdJQh3JVzQaXmYLASVV0wMVHaSG/Wmcn7ktf+VWXoJKsDaNt+3 8KVAFLPhGjd82/+IcsNS4iafp3WRhzrpVBNgqusVgVpHLtnsCfU39dbM3M7UmhvrT7 c5ghuTCavLTfF81FlRV+zEqFwUWaIJhGCPOrSdIw= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Valinor ([82.128.181.212]) by mail.gmx.com (mrgmx104 [212.227.17.174]) with ESMTPSA (Nemesis) id 1MoO24-1kHatS186i-00onyF; Fri, 25 Dec 2020 18:04:14 +0100 Date: Fri, 25 Dec 2020 19:01:58 +0200 From: Lauri Kasanen To: linux-mips@vger.kernel.org Cc: tsbogend@alpha.franken.de Subject: [PATCH 6/6] block: Add n64 cart driver Message-Id: <20201225190158.f94c679d21c4a2020c40adb4@gmx.com> X-Mailer: Sylpheed 3.5.0 (GTK+ 2.18.6; x86_64-unknown-linux-gnu) Mime-Version: 1.0 X-Provags-ID: V03:K1:93oi1qlI6UdnzR+iv441jF7MCBTNdhKfi5vxx/zPfFCFA1vF7GY 6Aeh1E54yGJ4/QPuFpiX68BfqgJdE2IyezInq6cTmqt4/fngNWzF2AlU9nVvsgnWymbdVcF IwfTjkj6bD4jB7QJEMaK8LX5qr3W39MbL0oYhxYVOjwXAX2U8sW9RdxrwIXrnsl3S38JHRA bvVB5uBOpi2tpeUsLuFpw== X-UI-Out-Filterresults: notjunk:1;V03:K0:rgijOwOeQfc=:WeDJkhdfYQGsXwo57ruFjw AOMNYwkfG92lg2XaBgNPXPqgBFhTWPDSTBx5tGhp9afxEfT8mWWHl1AemcyIOrMkXF6btBWlv Egj2vgVe/DeN8wVuId1ZUDs1K+xud9KQsTpPwHDRSFuNXclVcfAdwxrnuB7Zmx90NUTc6Dulm YT9DlOgkttVScMu+D3XwtSv4uxdn0WSE4OtjWOLijr6vABiglO1SjP4HR7yrODH7GNuGnQB9R 2W2Y69UOC2yWtu6GZAmqXGyMXQWgj15aLJ9w4kTBsbMFDf6/oL07h2+HcZ1ZsNlfu/guB3AcE BTfG/3njf72TMJc5ND0HXqRlydtfjDCMfZUDREJV2AthkleQOCaWU9mIObCtBITY4COzT4WxP 66q2OZhsYjLbPqxw/XUYeSRz7CZYAFEr7aaFH/48Bm9bz9kgXzC3h4BYP+4G5R9VaymxKlQfG p9ALe9D0UJaIQm1ARi5jNkb2PVjARejWjwVA8YocQGYSoDcb2T89+lZL6j/FqmhTlNZyLioMp Ivo0VMHBAGCgodecQVDtVZiWn0LjU9SfYIcO47uswnKaHh4xapaBzeQvx+oAmQ8FLbmQbY1tu otUsPYQmVhLR35/JARS457NKMgRw3PLn2BYzfVJw/srNTAeHtQdsOwSWie1Bm7DZu2lcmzgm5 S9dum8YktNDAoQJMMGT47AkU7KT0GRhBuPP4olw4oe5wRilYQJcGuZ6xz5TzpPy0IdxuIzD0y JIhNSl7VCiPNiFYm9DOHhQydtXJROYQrIIhiX1mVYhz3IXC+lYleYwcQuuLcSSOsaMTmA3QwU 3Ukldx0GbXf527V+0hp29qalmArLRapjCm8qo8STEvOGTV1CXcCIhLSkKy7rj0NHAKbdhbHZr 3LhIv1cvcWoXZMbzB6Kg== Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Lauri Kasanen --- drivers/block/Kconfig | 6 ++ drivers/block/Makefile | 1 + drivers/block/n64cart.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 drivers/block/n64cart.c -- 2.6.2 diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ecceaaa..28a0bad 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -72,6 +72,12 @@ config AMIGA_Z2RAM To compile this driver as a module, choose M here: the module will be called z2ram. +config N64CART + bool "N64 cart support" + depends on MIPS_N64 + help + Support for the N64 cart. + config CDROM tristate select BLK_SCSI_REQUEST diff --git a/drivers/block/Makefile b/drivers/block/Makefile index e1f6311..b9642cf 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PS3_DISK) += ps3disk.o obj-$(CONFIG_PS3_VRAM) += ps3vram.o obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o +obj-$(CONFIG_N64CART) += n64cart.o obj-$(CONFIG_BLK_DEV_RAM) += brd.o obj-$(CONFIG_BLK_DEV_LOOP) += loop.o obj-$(CONFIG_XILINX_SYSACE) += xsysace.o diff --git a/drivers/block/n64cart.c b/drivers/block/n64cart.c new file mode 100644 index 0000000..83acfe2 --- /dev/null +++ b/drivers/block/n64cart.c @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for the N64 cart. + * + * Copyright (c) 2020 Lauri Kasanen + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Lauri Kasanen "); +MODULE_DESCRIPTION("Driver for the N64 cart"); +MODULE_LICENSE("GPL"); + +#define BUFSIZE (64 * 1024) + +static unsigned int start, size; +static int major; +static struct request_queue *queue; +static struct blk_mq_tag_set tag_set; +static struct gendisk *disk; + +static void *buf; +static dma_addr_t dma_addr; + +static DEFINE_SPINLOCK(n64cart_lock); + +#define REG_BASE ((u32 *) CKSEG1ADDR(0xA4600000)) + +#define PI_DRAM_REG 0 +#define PI_CART_REG 1 +#define PI_READ_REG 2 +#define PI_WRITE_REG 3 +#define PI_STATUS_REG 4 + +#define PI_STATUS_DMA_BUSY (1 << 0) +#define PI_STATUS_IO_BUSY (1 << 1) + +static void n64cart_write_reg(const u8 reg, const u32 value) +{ + __raw_writel(value, REG_BASE + reg); +} + +static u32 n64cart_read_reg(const u8 reg) +{ + return __raw_readl(REG_BASE + reg); +} + +static void n64cart_wait_dma(void) +{ + while (n64cart_read_reg(PI_STATUS_REG) & + (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) + ; +} + +static blk_status_t get_seg(struct request *req) +{ + u32 bstart = blk_rq_pos(req) * 512; + u32 len = blk_rq_cur_bytes(req); + void *dst = bio_data(req->bio); + + if (bstart + len > size || rq_data_dir(req) == WRITE) + return BLK_STS_IOERR; + + bstart += start; + + while (len) { + const u32 curlen = len < BUFSIZE ? len : BUFSIZE; + + dma_cache_inv((unsigned long) buf, curlen); + + n64cart_wait_dma(); + + barrier(); + n64cart_write_reg(PI_DRAM_REG, dma_addr); + barrier(); + n64cart_write_reg(PI_CART_REG, (bstart | 0x10000000) & 0x1FFFFFFF); + barrier(); + n64cart_write_reg(PI_WRITE_REG, curlen - 1); + barrier(); + + n64cart_wait_dma(); + + memcpy(dst, buf, curlen); + + len -= curlen; + dst += curlen; + bstart += curlen; + } + + return BLK_STS_OK; +} + +static blk_status_t n64cart_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) +{ + unsigned long flags; + struct request *req = bd->rq; + blk_status_t err; + + blk_mq_start_request(req); + + spin_lock_irqsave(&n64cart_lock, flags); + + do { + err = get_seg(req); + } while (blk_update_request(req, err, blk_rq_cur_bytes(req))); + + spin_unlock_irqrestore(&n64cart_lock, flags); + blk_mq_end_request(req, BLK_STS_OK); + return BLK_STS_OK; +} + +static const struct blk_mq_ops n64cart_mq_ops = { + .queue_rq = n64cart_queue_rq, +}; + +static const struct block_device_operations n64cart_fops = { + .owner = THIS_MODULE, +}; + +static int __init n64cart_init(void) +{ + int err; + + if (!start || !size) { + pr_err("n64cart: start and size not specified\n"); + return -ENODEV; + } + + if (size & 4095) { + pr_err("n64cart: size must be a multiple of 4K\n"); + return -ENODEV; + } + + major = register_blkdev(0, "n64cart"); + if (major <= 0) { + pr_err("n64cart: unable to get major number\n"); + return -EBUSY; + } + + queue = blk_mq_init_sq_queue(&tag_set, &n64cart_mq_ops, 16, + BLK_MQ_F_SHOULD_MERGE); + if (IS_ERR(queue)) { + err = PTR_ERR(queue); + goto fail_reg; + } + + buf = kmalloc(BUFSIZE, GFP_DMA | GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto fail_queue; + } + dma_addr = virt_to_phys(buf); + + disk = alloc_disk(1); + if (!disk) { + err = -ENOMEM; + goto fail_dma; + } + + disk->major = major; + disk->first_minor = 0; + disk->queue = queue; + disk->flags = GENHD_FL_NO_PART_SCAN; + disk->fops = &n64cart_fops; + strcpy(disk->disk_name, "n64cart"); + + set_capacity(disk, size / 512); + + blk_queue_flag_set(QUEUE_FLAG_NONROT, queue); + blk_queue_physical_block_size(queue, 4096); + blk_queue_logical_block_size(queue, 4096); + + add_disk(disk); + + pr_info("n64cart: %u kb disk\n", size / 1024); + + return 0; +fail_dma: + kfree(buf); +fail_queue: + blk_cleanup_queue(queue); +fail_reg: + unregister_blkdev(major, "n64cart"); + return err; +} + +module_param(start, uint, 0); +MODULE_PARM_DESC(start, "Start address of the cart block data"); + +module_param(size, uint, 0); +MODULE_PARM_DESC(size, "Size of the cart block data, in bytes"); + +module_init(n64cart_init);