From patchwork Sun Sep 1 15:35:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125313 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2B0ED17EF for ; Sun, 1 Sep 2019 15:43:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 08A14208CB for ; Sun, 1 Sep 2019 15:43:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728496AbfIAPnH (ORCPT ); Sun, 1 Sep 2019 11:43:07 -0400 Received: from ste-pvt-msa1.bahnhof.se ([213.80.101.70]:32659 "EHLO ste-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAPnH (ORCPT ); Sun, 1 Sep 2019 11:43:07 -0400 Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTP id A6B843F771 for ; Sun, 1 Sep 2019 17:36:01 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from ste-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (ste-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Yk9dODtmJJSB for ; Sun, 1 Sep 2019 17:36:00 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 93E5E3F76C for ; Sun, 1 Sep 2019 17:36:00 +0200 (CEST) Date: Sun, 1 Sep 2019 17:35:59 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 001/120] MIPS: R5900: Initial support for the Emotion Engine in the PlayStation 2 Message-ID: <074470b707e277f2277bfedfe89ee4acbe159396.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The R5900 implements the 64-bit MIPS III instruction set except LL, SC, LLD and SCD, with additional PREFETCH and conditional move instructions from MIPS IV as well as three-operand multiply and multiply-accumulate instructions[1]. It also has a set of R5900 specific 128-bit multimedia instructions. Endianness is not configurable and taken to be little- endian. The R5900 does not implement CP0.Status.{UX,SX,KX,PX}. The COP1 FPU implements single-precision floating-point operations but is not entirely IEEE 754 compatible. In particular, - NaN (not a number) and plus/minus infinities are not supported; - exception mechanisms are not fully supported; - denormalized numbers are not supported; - rounding towards nearest and plus/minus infinities are not supported; - computed results usually differs in the least significant bit; - saturating instructions can differ more than the least significant bit. Since only rounding towards zero is supported, the two least significant bits of FCR31 are hardwired to 01. To support IEEE 754 in applications the FPU is emulated in software by the kernel. The VPU0 is a vector processor of the Emotion Engine. In macro mode, it functions as COP2 (coprocessor) and instructions execute simultaneously in the main integer pipeline I1 and the COP2 pipeline[2]. In micro mode, the VPU0 functions as a stand-alone processor. The VPU1 is an additional vector processor that operates independently of both the R5900 and the VPU0. It primarily acts as a preprocessor to the Graphics Synthesizer[3]. The vector processors are initially disabled. The scratch pad RAM (SPRAM) of the Emotion Engine is 16 KiB of very fast static RAM organised in 128-bit quadwords[4]. Both the DMA controller and the R5900 can access the SPRAM. The SPRAM is initially disabled. The R5900 has several significant hardware bugs. Perhaps the most important bug affecting applications is the short loop bug that under certain conditions causes loops to execute only once or twice. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, https://wiki.qemu.org/File:C790.pdf [2] "VU User's Manual", version 6.0, Sony Computer Entertainment Inc. [3] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc. [4] "EE Core User's Manual", version 6.0, Sony Computer Entertainment Inc. Signed-off-by: Fredrik Noring --- arch/mips/Kconfig | 13 ++++++++++++- arch/mips/Makefile | 1 + arch/mips/include/asm/cpu-type.h | 4 ++++ arch/mips/include/asm/cpu.h | 3 ++- arch/mips/include/asm/module.h | 2 ++ arch/mips/kernel/cpu-probe.c | 8 ++++++++ arch/mips/mm/Makefile | 1 + arch/mips/mm/c-r4k.c | 19 +++++++++++++++++++ 8 files changed, 49 insertions(+), 2 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d50fafd7bf3a..88d6c13260e1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1749,6 +1749,14 @@ config CPU_BMIPS help Support for BMIPS32/3300/4350/4380 and BMIPS5000 processors. +config CPU_R5900 + bool "R5900" + depends on SYS_HAS_CPU_R5900 + select CPU_SUPPORTS_32BIT_KERNEL + select IRQ_MIPS_CPU + help + Toshiba R5900 processor (Emotion Engine in the Sony PlayStation 2). + config CPU_XLR bool "Netlogic XLR SoC" depends on SYS_HAS_CPU_XLR @@ -1987,6 +1995,9 @@ config SYS_HAS_CPU_R5432 config SYS_HAS_CPU_R5500 bool +config SYS_HAS_CPU_R5900 + bool + config SYS_HAS_CPU_NEVADA bool @@ -2309,7 +2320,7 @@ config MIPS_FP_SUPPORT config CPU_R2300_FPU bool depends on MIPS_FP_SUPPORT - default y if CPU_R3000 || CPU_TX39XX + default y if CPU_R3000 || CPU_TX39XX || CPU_R5900 config CPU_R4K_FPU bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index eceff9b75b22..81cd620d32f7 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -178,6 +178,7 @@ cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \ -Wa,--trap cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=r5000) \ -Wa,--trap +cflags-$(CONFIG_CPU_R5900) += -march=r5900 -Wa,--trap cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ -Wa,--trap cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index a45af3de075d..7d35100e0e18 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -151,6 +151,10 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_R5500: #endif +#ifdef CONFIG_SYS_HAS_CPU_R5900 + case CPU_R5900: +#endif + #ifdef CONFIG_SYS_HAS_CPU_NEVADA case CPU_NEVADA: #endif diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 290369fa44a4..05a0f5a07f08 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -83,6 +83,7 @@ #define PRID_IMP_R4650 0x2200 /* Same as R4640 */ #define PRID_IMP_R5000 0x2300 #define PRID_IMP_TX49 0x2d00 +#define PRID_IMP_R5900 0x2e00 /* PlayStation 2 */ #define PRID_IMP_SONIC 0x2400 #define PRID_IMP_MAGIC 0x2500 #define PRID_IMP_RM7000 0x2700 @@ -298,7 +299,7 @@ enum cpu_type_enum { CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000, CPU_R12000, CPU_R14000, CPU_R16000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000, - CPU_SR71000, CPU_TX49XX, + CPU_SR71000, CPU_TX49XX, CPU_R5900, /* * R8000 class processors diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index 6dc0b21b8acd..d6fbc3aad2a1 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -115,6 +115,8 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "R5432 " #elif defined CONFIG_CPU_R5500 #define MODULE_PROC_FAMILY "R5500 " +#elif defined CONFIG_CPU_R5900 +#define MODULE_PROC_FAMILY "R5900 " #elif defined CONFIG_CPU_NEVADA #define MODULE_PROC_FAMILY "NEVADA " #elif defined CONFIG_CPU_R8000 diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 9635c1db3ae6..629391948ab4 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1484,6 +1484,14 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 48; break; + case PRID_IMP_R5900: + c->cputype = CPU_R5900; + __cpu_name[cpu] = "R5900"; + c->isa_level = MIPS_CPU_ISA_III; + c->fpu_msk31 |= FPU_CSR_CONDX; + c->options = R4K_OPTS | MIPS_CPU_DIVEC; + c->tlbsize = 48; + break; case PRID_IMP_NEVADA: c->cputype = CPU_NEVADA; __cpu_name[cpu] = "Nevada"; diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 1e8d335025d7..08db8f27d125 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_DMA_NONCOHERENT) += dma-noncoherent.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_R5900) += c-r4k.o cex-gen.o tlb-r4k.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-r4k.c b/arch/mips/mm/c-r4k.c index 5166e38cd1c6..4f2cecbec722 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1113,6 +1113,18 @@ static void probe_pcache(void) c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH; break; + case CPU_R5900: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 64; + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 64; + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + case CPU_TX49XX: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); @@ -1388,6 +1400,13 @@ static void probe_pcache(void) case CPU_R16000: break; + case CPU_R5900: + if (c->icache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + if (c->dcache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + break; + case CPU_74K: case CPU_1074K: has_74k_erratum = alias_74k_erratum(c); From patchwork Sun Sep 1 15:36:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125311 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 751021395 for ; Sun, 1 Sep 2019 15:43:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 518E920870 for ; Sun, 1 Sep 2019 15:43:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728676AbfIAPnH (ORCPT ); Sun, 1 Sep 2019 11:43:07 -0400 Received: from ste-pvt-msa1.bahnhof.se ([213.80.101.70]:42317 "EHLO ste-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAPnG (ORCPT ); Sun, 1 Sep 2019 11:43:06 -0400 Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 101D23F793 for ; Sun, 1 Sep 2019 17:36:32 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from ste-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (ste-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SicFsrujHwbl for ; Sun, 1 Sep 2019 17:36:30 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id E8CC03F773 for ; Sun, 1 Sep 2019 17:36:30 +0200 (CEST) Date: Sun, 1 Sep 2019 17:36:30 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 002/120] MIPS: R5900: Trap the RDHWR instruction as an SQ address exception Message-ID: <4f856a5ea2c039c6639df875d11b5bff1bf7ecd2.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org On the R5900, the RDHWR instruction is interpreted as the R5900 specific SQ instruction[1] that traps into a zero page address exception. Hence RDHWR can be emulated by emulate_load_store_insn(). CONFIG_DEFAULT_MMAP_MIN_ADDR must not be less than PAGE_SIZE to reliably trap and emulate RDHWR, so this is made a BUILD_BUG_ON for the R5900. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. B-162, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- arch/mips/include/asm/traps.h | 2 ++ arch/mips/kernel/traps.c | 2 +- arch/mips/kernel/unaligned.c | 36 ++++++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h index 6a0864bb604d..ed6449f2967b 100644 --- a/arch/mips/include/asm/traps.h +++ b/arch/mips/include/asm/traps.h @@ -35,4 +35,6 @@ extern int register_nmi_notifier(struct notifier_block *nb); register_nmi_notifier(&fn##_nb); \ }) +int simulate_rdhwr(struct pt_regs *regs, int rd, int rt); + #endif /* _ASM_TRAPS_H */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 342e41de9d64..9423b9a2eb67 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -625,7 +625,7 @@ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode) * Simulate trapping 'rdhwr' instructions to provide user accessible * registers not implemented in hardware. */ -static int simulate_rdhwr(struct pt_regs *regs, int rd, int rt) +int simulate_rdhwr(struct pt_regs *regs, int rd, int rt) { struct thread_info *ti = task_thread_info(current); diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 92bd2b0f0548..f490944d73cf 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -90,6 +90,7 @@ #include #include #include +#include #include #define STR(x) __STR(x) @@ -934,7 +935,39 @@ static void emulate_load_store_insn(struct pt_regs *regs, * interest. */ case spec3_op: - if (insn.dsp_format.func == lx_op) { + if (IS_ENABLED(CONFIG_CPU_R5900)) { + /* + * On the R5900, the RDHWR instruction + * + * +--------+-------+----+----+-------+--------+ + * | 011111 | 00000 | rt | rd | 00000 | 111011 | + * +--------+-------+----+----+-------+--------+ + * 6 5 5 5 5 6 + * + * is interpreted as the R5900 specific SQ instruction + * + * +--------+-------+----+---------------------+ + * | 011111 | base | rt | offset | + * +--------+-------+----+---------------------+ + * 6 5 5 16 + * + * that asserts a zero page address exception. Hence + * RDHWR can be trapped and emulated here, provided + * DEFAULT_MMAP_MIN_ADDR isn't zero. + */ + BUILD_BUG_ON(IS_ENABLED(CONFIG_CPU_R5900) && + CONFIG_DEFAULT_MMAP_MIN_ADDR < PAGE_SIZE); + if (insn.r_format.func == rdhwr_op && + insn.r_format.rs == 0 && + insn.r_format.re == 0) { + if (compute_return_epc(regs) < 0 || + simulate_rdhwr(regs, insn.r_format.rd, + insn.r_format.rt) < 0) + goto sigill; + return; + } + goto sigbus; + } else if (insn.dsp_format.func == lx_op) { switch (insn.dsp_format.op) { case lwx_op: if (!access_ok(addr, 4)) @@ -1342,6 +1375,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, cu2_notifier_call_chain(CU2_SDC2_OP, regs); break; #endif + default: /* * Pheeee... We encountered an yet unknown instruction or From patchwork Sun Sep 1 15:36:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125315 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AFE5C13B1 for ; Sun, 1 Sep 2019 15:45:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7BAB2233A2 for ; Sun, 1 Sep 2019 15:45:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728775AbfIAPpj (ORCPT ); Sun, 1 Sep 2019 11:45:39 -0400 Received: from ste-pvt-msa2.bahnhof.se ([213.80.101.71]:8839 "EHLO ste-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728687AbfIAPpj (ORCPT ); Sun, 1 Sep 2019 11:45:39 -0400 Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 925D93F9E2 for ; Sun, 1 Sep 2019 17:36:58 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from ste-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (ste-ftg-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7FIUlIm4-6mT for ; Sun, 1 Sep 2019 17:36:57 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by ste-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 91AF73F9CE for ; Sun, 1 Sep 2019 17:36:57 +0200 (CEST) Date: Sun, 1 Sep 2019 17:36:57 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 003/120] MIPS: R5900: Sign-extend o32 system call registers Message-ID: <2a8a082cea486293c0f1f64356e3cb9cd55ef869.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The R5900 has 64-bit instructions but does not implement CP0.Status.UX so a 32-bit kernel cannot assume o32 registers are sign-extended[1]. CP0.Status.{UX,SX,KX} are read-only and always read as zero. CP0.Status.PX (bit 23) is called CP0.Status.DEV and controls the location of performance counter and debug/SIO exception vectors. In other MIPS ISA implementations, attempting to execute 64-bit operations in 32-bit user or supervisor mode may cause the reserved instruction exception. In the Emotion Engine core, however, 64-bit operations are always valid, regardless of the operation mode[2]. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. 4-16, https://wiki.qemu.org/File:C790.pdf [2] "EE Core User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 107. Signed-off-by: Fredrik Noring --- arch/mips/kernel/scall32-o32.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index d9434cd0f568..b5ad6798978c 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -25,6 +25,18 @@ .align 5 NESTED(handle_sys, PT_SIZE, sp) .set noat +#ifdef CONFIG_CPU_R5900 + /* + * We don't want to stumble over broken sign extensions from + * userland. O32 does never use the upper half, but since the + * R5900 does not implement CP0.Status.UX it cannot enforce it. + */ + sll v0, v0, 0 + sll a0, a0, 0 + sll a1, a1, 0 + sll a2, a2, 0 + sll a3, a3, 0 +#endif SAVE_SOME TRACE_IRQS_ON_RELOAD STI From patchwork Sun Sep 1 15:37:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125317 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C432217EF for ; Sun, 1 Sep 2019 15:45:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ABB112342E for ; Sun, 1 Sep 2019 15:45:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728687AbfIAPpj (ORCPT ); Sun, 1 Sep 2019 11:45:39 -0400 Received: from ste-pvt-msa2.bahnhof.se ([213.80.101.71]:37489 "EHLO ste-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728621AbfIAPpj (ORCPT ); Sun, 1 Sep 2019 11:45:39 -0400 Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa2.bahnhof.se (Postfix) with ESMTP id D0F9B3F9E4; Sun, 1 Sep 2019 17:37:36 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from ste-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (ste-ftg-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id btzH-vP_3bIy; Sun, 1 Sep 2019 17:37:36 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by ste-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 173B13F9CE; Sun, 1 Sep 2019 17:37:36 +0200 (CEST) Date: Sun, 1 Sep 2019 17:37:35 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 004/120] MIPS: R5900: Reset bits 127..64 of GPRs in RESTORE_SOME Message-ID: <810f5e4de4a5d600a013733c9c13c7aa0b8c30d5.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Bits 127..64 are not used by the kernel but can be modified by applications using the R5900 specific multimedia instructions. Clearing them in RESTORE_SOME prevents leaking information between processes. This is a provisional measure until full 128-bit registers are saved/restored, possibly using SQ/LQ. Signed-off-by: Fredrik Noring --- As mentioned in the cover letter, I think it would be much better to save and restore 128-bit GPRs here. --- arch/mips/include/asm/stackframe.h | 53 ++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 4d6ad907ae54..aaed9b522220 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -349,6 +349,58 @@ cfi_ld sp, PT_R29, \docfi .endm +#ifdef CONFIG_CPU_R5900 + /* + * Reset bits 127..64 of 128-bit multimedia registers. + * + * Bits 127..64 are not used by the kernel but can be modified + * by applications using the R5900 specific multimedia + * instructions. Clearing them prevents leaking information + * between processes. This is a provisional measure until full + * 128-bit registers are saved/restored, possibly using SQ/LQ. + */ + .macro RESET_MMR + .set push + .set noreorder + .set noat + pcpyld $1, $0, $1 + pcpyld $2, $0, $2 + pcpyld $3, $0, $3 + pcpyld $4, $0, $4 + pcpyld $5, $0, $5 + pcpyld $6, $0, $6 + pcpyld $7, $0, $7 + pcpyld $8, $0, $8 + pcpyld $9, $0, $9 + pcpyld $10, $0, $10 + pcpyld $11, $0, $11 + pcpyld $12, $0, $12 + pcpyld $13, $0, $13 + pcpyld $14, $0, $14 + pcpyld $15, $0, $15 + pcpyld $16, $0, $16 + pcpyld $17, $0, $17 + pcpyld $18, $0, $18 + pcpyld $19, $0, $19 + pcpyld $20, $0, $20 + pcpyld $21, $0, $21 + pcpyld $22, $0, $22 + pcpyld $23, $0, $23 + pcpyld $24, $0, $24 + pcpyld $25, $0, $25 + pcpyld $26, $0, $26 + pcpyld $27, $0, $27 + pcpyld $28, $0, $28 + pcpyld $29, $0, $29 + pcpyld $30, $0, $30 + pcpyld $31, $0, $31 + .set pop + .endm +#else + .macro RESET_MMR + .endm +#endif + #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) .macro RESTORE_SOME docfi=0 @@ -393,6 +445,7 @@ .set push .set reorder .set noat + RESET_MMR mfc0 a0, CP0_STATUS ori a0, STATMASK xori a0, STATMASK From patchwork Sun Sep 1 15:38:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125355 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 30FEA112C for ; Sun, 1 Sep 2019 15:48:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0EA3D20828 for ; Sun, 1 Sep 2019 15:48:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729158AbfIAPsF (ORCPT ); Sun, 1 Sep 2019 11:48:05 -0400 Received: from ste-pvt-msa1.bahnhof.se ([213.80.101.70]:39451 "EHLO ste-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729151AbfIAPsF (ORCPT ); Sun, 1 Sep 2019 11:48:05 -0400 Received: from localhost (localhost [127.0.0.1]) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTP id D3A4A3F797; Sun, 1 Sep 2019 17:38:26 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from ste-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (ste-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id LxdvdqJ1fkop; Sun, 1 Sep 2019 17:38:26 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by ste-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id C84293F6D0; Sun, 1 Sep 2019 17:38:25 +0200 (CEST) Date: Sun, 1 Sep 2019 17:38:25 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 005/120] MIPS: R5900: Reset the funnel shift amount (SA) register in RESTORE_SOME Message-ID: <5ea4fddbb423d86cbf9894690fd221a121636c3a.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The shift amount (SA) register is a 64-bit special register storing the funnel shift amount[1]. It is used by the QFSRV (quadword funnel shift right variable) 256-bit multimedia instruction. This is a provisional measure until the SA register is saved/restored properly. The R5900 specific MTSAB (move byte count to shift amount register) instruction is used to reset the SA register. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. B-161, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- The shift amount (SA) register ought to be saved and restored properly too, along with the 128-bit GPRs, I think. --- arch/mips/include/asm/stackframe.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index aaed9b522220..2fbead2e86d1 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -394,6 +394,7 @@ pcpyld $29, $0, $29 pcpyld $30, $0, $30 pcpyld $31, $0, $31 + mtsab $0, 0 /* Reset the funnel shift (SA) register. */ .set pop .endm #else From patchwork Sun Sep 1 15:38:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125365 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E97E514E5 for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CE63923429 for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729172AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57476 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729151AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 10373402D7 for ; Sun, 1 Sep 2019 17:38:46 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9DN2j69RFKgk for ; Sun, 1 Sep 2019 17:38:45 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 41CE63FBF6 for ; Sun, 1 Sep 2019 17:38:45 +0200 (CEST) Date: Sun, 1 Sep 2019 17:38:44 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 006/120] MIPS: R5900: Workaround for the short loop bug Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The short loop bug under certain conditions causes loops to execute only once or twice. The Gnu assembler (GAS) has the following note about it: On the R5900 short loops need to be fixed by inserting a NOP in the branch delay slot. The short loop bug under certain conditions causes loops to execute only once or twice. We must ensure that the assembler never generates loops that satisfy all of the following conditions: - a loop consists of less than or equal to six instructions (including the branch delay slot); - a loop contains only one conditional branch instruction at the end of the loop; - a loop does not contain any other branch or jump instructions; - a branch delay slot of the loop is not NOP (EE 2.9 or later). We need to do this because of a hardware bug in the R5900 chip. GAS handles the short loop bug in most cases. However, GAS is unable to adjust machine code having the noreorder directive, as used by the kernel on several occasions. The short loop bug also affects user space code, which is why generic MIPS code cannot execute unadjusted on the R5900. The GAS and GCC option -mfix-r5900 is recommended for such cases. Signed-off-by: Fredrik Noring --- arch/mips/boot/compressed/head.S | 7 +++--- arch/mips/include/asm/asmmacro.h | 41 ++++++++++++++++++++++++++++++++ arch/mips/include/asm/string.h | 3 +++ arch/mips/lib/delay.c | 7 +++--- arch/mips/lib/memset.S | 2 ++ 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/arch/mips/boot/compressed/head.S b/arch/mips/boot/compressed/head.S index 409cb483a9ff..e3dc831e2616 100644 --- a/arch/mips/boot/compressed/head.S +++ b/arch/mips/boot/compressed/head.S @@ -15,7 +15,6 @@ #include #include - .set noreorder .cprestore LEAF(start) start: @@ -26,11 +25,11 @@ start: move s3, a3 /* Clear BSS */ - PTR_LA a0, _edata + PTR_LA a0, _edata - 4 PTR_LA a2, _end -1: sw zero, 0(a0) +1: addiu a0, a0, 4 + sw zero, 0(a0) bne a2, a0, 1b - addiu a0, a0, 4 PTR_LA a0, (.heap) /* heap address */ PTR_LA sp, (.stack + 8192) /* stack address */ diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index feb069cbf44e..aa58474c739f 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h @@ -654,4 +654,45 @@ .set pop .endm +#ifdef CONFIG_CPU_R5900 +/* + * Workaround for the R5900 short loop bug + * + * The short loop bug under certain conditions causes loops to execute only + * once or twice. The Gnu assembler (GAS) has the following note about it: + * + * On the R5900 short loops need to be fixed by inserting a NOP in the + * branch delay slot. + * + * The short loop bug under certain conditions causes loops to execute + * only once or twice. We must ensure that the assembler never + * generates loops that satisfy all of the following conditions: + * + * - a loop consists of less than or equal to six instructions + * (including the branch delay slot); + * - a loop contains only one conditional branch instruction at the + * end of the loop; + * - a loop does not contain any other branch or jump instructions; + * - a branch delay slot of the loop is not NOP (EE 2.9 or later). + * + * We need to do this because of a hardware bug in the R5900 chip. + * + * GAS handles the short loop bug in most cases. However, GAS is unable to + * adjust machine code having the noreorder directive, as used by the kernel + * on several occasions. The short_loop_war macro defined here can be used + * to insert necessary NOPs by placing it just before the jump instruction. + */ + .macro short_loop_war loop_target + .set instruction_count,2 + (. - \loop_target) / 4 + .ifgt 7 - instruction_count + .rept 7 - instruction_count + nop + .endr + .endif + .endm +#else + .macro short_loop_war loop_target + .endm +#endif + #endif /* _ASM_ASMMACRO_H */ diff --git a/arch/mips/include/asm/string.h b/arch/mips/include/asm/string.h index 29030cb398ee..35c9dc3815f4 100644 --- a/arch/mips/include/asm/string.h +++ b/arch/mips/include/asm/string.h @@ -10,6 +10,9 @@ #ifndef _ASM_STRING_H #define _ASM_STRING_H +#if defined(CONFIG_CPU_R5900) +#define IN_STRING_C +#endif /* * Most of the inline functions are rather naive implementations so I just diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 68c495ed71e3..0b370b831708 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -27,11 +27,10 @@ void __delay(unsigned long loops) { __asm__ __volatile__ ( - " .set noreorder \n" " .align 3 \n" - "1: bnez %0, 1b \n" - " " __stringify(LONG_SUBU) " %0, %1 \n" - " .set reorder \n" + " " __stringify(LONG_ADDU) " %0, %1 \n" + "1: " __stringify(LONG_SUBU) " %0, %1 \n" + " bnez %0, 1b \n" : "=r" (loops) : GCC_DADDI_IMM_ASM() (1), "0" (loops)); } diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 418611ef13cf..70db395159f1 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -9,6 +9,7 @@ * Copyright (C) 2011, 2012 MIPS Technologies, Inc. */ #include +#include #include #include #include @@ -222,6 +223,7 @@ 1: PTR_ADDIU a0, 1 /* fill bytewise */ R10KCBARRIER(0(ra)) .set noreorder + short_loop_war(1b) bne t1, a0, 1b EX(sb, a1, -1(a0), .Lsmall_fixup\@) .set reorder From patchwork Sun Sep 1 15:39:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125369 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5DAD7112C for ; Sun, 1 Sep 2019 15:48:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4634D233A2 for ; Sun, 1 Sep 2019 15:48:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729180AbfIAPs1 (ORCPT ); Sun, 1 Sep 2019 11:48:27 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57538 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729151AbfIAPs1 (ORCPT ); Sun, 1 Sep 2019 11:48:27 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 52EA640386 for ; Sun, 1 Sep 2019 17:39:03 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UiPntJFwqv29 for ; Sun, 1 Sep 2019 17:39:02 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 6A5FC4036B for ; Sun, 1 Sep 2019 17:39:02 +0200 (CEST) Date: Sun, 1 Sep 2019 17:39:02 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 007/120] MIPS: R5900: Add the SYNC.P instruction Message-ID: <829485da9abba9367b953c7d5756356a58e8a638.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The SYNC.P instruction is a pipeline barrier. All instructions prior to the barrier are completed before the instructions following the barrier are fetched[1]. However, the barrier operation doesn't wait for any prior instructions to retire, for example multiply, divide, multicycle COP1 operations or a pending load issued before the barrier operation. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. A-125, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- arch/mips/include/asm/uasm.h | 1 + arch/mips/mm/uasm-mips.c | 1 + arch/mips/mm/uasm.c | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index f7effca791a5..71ddf155ef85 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h @@ -171,6 +171,7 @@ Ip_u3u2u1(_srlv); Ip_u3u1u2(_subu); Ip_u2s3u1(_sw); Ip_u1(_sync); +Ip_0(_syncp); Ip_u1(_syscall); Ip_0(_tlbp); Ip_0(_tlbr); diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c index 7154a1d99aad..725c6fe1e317 100644 --- a/arch/mips/mm/uasm-mips.c +++ b/arch/mips/mm/uasm-mips.c @@ -191,6 +191,7 @@ static const struct insn insn_table[insn_invalid] = { [insn_subu] = {M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD}, [insn_sw] = {M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM}, [insn_sync] = {M(spec_op, 0, 0, 0, 0, sync_op), RE}, + [insn_syncp] = {M(spec_op, 0, 0, 0, 0x10, sync_op), 0}, [insn_syscall] = {M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, [insn_tlbp] = {M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0}, [insn_tlbr] = {M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0}, diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index c56f129c9a4b..32c7a5827ba8 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -64,8 +64,8 @@ enum opcode { insn_scd, insn_seleqz, insn_selnez, insn_sd, insn_sh, insn_sll, insn_sllv, insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra, insn_srav, insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, - insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, - insn_wsbh, insn_xor, insn_xori, insn_yield, + insn_syncp, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, + insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield, insn_invalid /* insn_invalid must be last */ }; @@ -369,6 +369,7 @@ I_u2u1u3(_rotr) I_u3u1u2(_subu) I_u2s3u1(_sw) I_u1(_sync) +I_0(_syncp) I_0(_tlbp) I_0(_tlbr) I_0(_tlbwi) From patchwork Sun Sep 1 15:39:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125321 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E18041395 for ; Sun, 1 Sep 2019 15:46:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C818B233A2 for ; Sun, 1 Sep 2019 15:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728929AbfIAPqL (ORCPT ); Sun, 1 Sep 2019 11:46:11 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41312 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728888AbfIAPqL (ORCPT ); Sun, 1 Sep 2019 11:46:11 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 4B4633F65F; Sun, 1 Sep 2019 17:39:20 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nW21PdwY-Sph; Sun, 1 Sep 2019 17:39:19 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 427873F615; Sun, 1 Sep 2019 17:39:19 +0200 (CEST) Date: Sun, 1 Sep 2019 17:39:19 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 008/120] MIPS: R5900: Add implicit SYNC.P to the UASM_i_M[FT]C0 macros Message-ID: <7ca2326b3a86abb55904ddc930785f5590799a1d.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Toshiba TX79 manual specifies that all MTC0 instructions must be followed by a SYNC.P instruction as a barrier to guarantee COP0 register updates[1]. There is one exception to this rule: An MTC0 instruction which loads the EntryHi COP0 register can be followed by a TLBWI or a TLBWR instruction without having an intervening SYNC.P. This special case is handled by a hardware interlock. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. C-28, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- The Linux 2.6 port to the PlayStation 2 has SYNC.P preceding all MFC0 instructions, but I have not found any documentation stating that is necessary. Perhaps this case can be removed? --- arch/mips/include/asm/uasm.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 71ddf155ef85..34b61fb53da5 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h @@ -214,8 +214,19 @@ static inline void uasm_l##lb(struct uasm_label **lab, u32 *addr) \ # define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off) # define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off) # define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd) +#ifndef CONFIG_CPU_R5900 # define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd) # define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd) +#else +# define UASM_i_MFC0(buf, rt, rd...) do { \ + uasm_i_syncp(buf); \ + uasm_i_mfc0(buf, rt, rd); \ + } while(0) +# define UASM_i_MTC0(buf, rt, rd...) do { \ + uasm_i_mtc0(buf, rt, rd); \ + uasm_i_syncp(buf); \ + } while(0) +#endif # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh) # define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off) # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh) @@ -230,8 +241,19 @@ static inline void uasm_l##lb(struct uasm_label **lab, u32 *addr) \ # define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off) # define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off) # define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd) +#ifndef CONFIG_CPU_R5900 # define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd) # define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd) +#else +# define UASM_i_MFC0(buf, rt, rd...) do { \ + uasm_i_syncp(buf); \ + uasm_i_mfc0(buf, rt, rd); \ + } while(0) +# define UASM_i_MTC0(buf, rt, rd...) do { \ + uasm_i_mtc0(buf, rt, rd); \ + uasm_i_syncp(buf); \ + } while(0) +#endif # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh) # define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off) # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh) From patchwork Sun Sep 1 15:39:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125325 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DDA961395 for ; Sun, 1 Sep 2019 15:46:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A98C8233A2 for ; Sun, 1 Sep 2019 15:46:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728830AbfIAPqS (ORCPT ); Sun, 1 Sep 2019 11:46:18 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41314 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728621AbfIAPqS (ORCPT ); Sun, 1 Sep 2019 11:46:18 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id E841D3F684; Sun, 1 Sep 2019 17:39:33 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FH1Ujhf59uMM; Sun, 1 Sep 2019 17:39:32 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id A22E63F672; Sun, 1 Sep 2019 17:39:32 +0200 (CEST) Date: Sun, 1 Sep 2019 17:39:32 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 009/120] MIPS: R5900: Add mandatory SYNC.P to all M[FT]C0 instructions Message-ID: <4775699bfc809a6a8b40749f82be890515303bdd.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Toshiba TX79 manual specifies that all MTC0 instructions must be followed by a SYNC.P instruction as a barrier to guarantee COP0 register updates[1]. There is one exception to this rule: An MTC0 instruction which loads the EntryHi COP0 register can be followed by a TLBWI or a TLBWR instruction without having an intervening SYNC.P. This special case is handled by a hardware interlock. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. C-28, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- The Linux 2.6 port to the PlayStation 2 has SYNC.P preceding all MFC0 instructions, but I have not found any documentation stating that is necessary. Perhaps this case can be removed? --- arch/mips/include/asm/asmmacro.h | 12 ++++++ arch/mips/include/asm/irqflags.h | 15 +++++++ arch/mips/include/asm/mipsregs.h | 69 ++++++++++++++++++++++++++++++ arch/mips/include/asm/stackframe.h | 54 +++++++++++++++++++++++ arch/mips/kernel/genex.S | 60 ++++++++++++++++++++++++++ arch/mips/kernel/head.S | 9 ++++ arch/mips/kernel/r4k_switch.S | 9 ++++ arch/mips/mm/cex-gen.S | 6 +++ arch/mips/mm/tlbex-fault.S | 3 ++ arch/mips/mm/tlbex.c | 14 ++++-- 10 files changed, 247 insertions(+), 4 deletions(-) diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index aa58474c739f..67e77c0b64aa 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h @@ -56,9 +56,15 @@ .endm #else .macro local_irq_enable reg=t0 +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 \reg, CP0_STATUS ori \reg, \reg, 1 mtc0 \reg, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif irq_enable_hazard .endm @@ -67,11 +73,17 @@ lw \reg, TI_PRE_COUNT($28) addi \reg, \reg, 1 sw \reg, TI_PRE_COUNT($28) +#endif +#ifdef CONFIG_CPU_R5900 + sync.p #endif mfc0 \reg, CP0_STATUS ori \reg, \reg, 1 xori \reg, \reg, 1 mtc0 \reg, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif irq_disable_hazard #ifdef CONFIG_PREEMPT lw \reg, TI_PRE_COUNT($28) diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index f0b862a83816..e0c0265b2719 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -78,9 +78,15 @@ static inline void arch_local_irq_restore(unsigned long flags) /* * Fast, dangerous. Life is fun, life is good. */ +#ifdef CONFIG_CPU_R5900 + " sync.p \n" +#endif " mfc0 $1, $12 \n" " ins $1, %[flags], 0, 1 \n" " mtc0 $1, $12 \n" +#ifdef CONFIG_CPU_R5900 + " sync.p \n" +#endif #endif " " __stringify(__irq_disable_hazard) " \n" " .set pop \n" @@ -105,10 +111,16 @@ static inline void arch_local_irq_enable(void) #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) " ei \n" #else +#ifdef CONFIG_CPU_R5900 + " sync.p \n" +#endif " mfc0 $1,$12 \n" " ori $1,0x1f \n" " xori $1,0x1e \n" " mtc0 $1,$12 \n" +#ifdef CONFIG_CPU_R5900 + " sync.p \n" +#endif #endif " " __stringify(__irq_enable_hazard) " \n" " .set pop \n" @@ -124,6 +136,9 @@ static inline unsigned long arch_local_save_flags(void) asm __volatile__( " .set push \n" " .set reorder \n" +#ifdef CONFIG_CPU_R5900 + " sync.p \n" +#endif " mfc0 %[flags], $12 \n" " .set pop \n" : [flags] "=r" (flags)); diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 1e6966e8527e..2aa947b3d0d1 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1345,6 +1345,29 @@ do { \ * Macros to access the system control coprocessor */ +#ifdef CONFIG_CPU_R5900 +#define ___read_32bit_c0_register(source, sel, vol) \ +({ int __res; \ + if (sel == 0) \ + __asm__ vol( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "sync.p\n\t" \ + "mfc0\t%0, " #source "\n\t" \ + ".set pop\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ vol( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + ".set\tmips32\n\t" \ + "sync.p\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set pop\n\t" \ + : "=r" (__res)); \ + __res; \ +}) +#else #define ___read_32bit_c0_register(source, sel, vol) \ ({ unsigned int __res; \ if (sel == 0) \ @@ -1360,6 +1383,7 @@ do { \ : "=r" (__res)); \ __res; \ }) +#endif #define ___read_64bit_c0_register(source, sel, vol) \ ({ unsigned long long __res; \ @@ -1394,6 +1418,28 @@ do { \ #define __read_const_64bit_c0_register(source, sel) \ ___read_64bit_c0_register(source, sel,) +#ifdef CONFIG_CPU_R5900 +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "mtc0\t%z0, " #register "\n\t" \ + "sync.p\n\t" \ + ".set pop\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + "sync.p\n\t" \ + ".set pop\n\t" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) +#else #define __write_32bit_c0_register(register, sel, value) \ do { \ if (sel == 0) \ @@ -1408,6 +1454,7 @@ do { \ ".set\tpop" \ : : "Jr" ((unsigned int)(value))); \ } while (0) +#endif #define __write_64bit_c0_register(register, sel, value) \ do { \ @@ -2649,6 +2696,14 @@ static inline void tlb_probe(void) __asm__ __volatile__( ".set noreorder\n\t" "tlbp\n\t" +#ifdef CONFIG_CPU_R5900 + /* No memory access behind the tlbp instruction. */ + "sync.p\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" +#endif ".set reorder"); } @@ -2674,6 +2729,14 @@ static inline void tlb_read(void) __asm__ __volatile__( ".set noreorder\n\t" "tlbr\n\t" +#ifdef CONFIG_CPU_R5900 + "sync.p\n\t" + /* No branch behind tlbr. */ + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" +#endif ".set reorder"); #if MIPS34K_MISSED_ITLB_WAR @@ -2694,6 +2757,9 @@ static inline void tlb_write_indexed(void) __asm__ __volatile__( ".set noreorder\n\t" "tlbwi\n\t" +#ifdef CONFIG_CPU_R5900 + "sync.p\n\t" +#endif ".set reorder"); } @@ -2702,6 +2768,9 @@ static inline void tlb_write_random(void) __asm__ __volatile__( ".set noreorder\n\t" "tlbwr\n\t" +#ifdef CONFIG_CPU_R5900 + "sync.p\n\t" +#endif ".set reorder"); } diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 2fbead2e86d1..4a0f6639fde8 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -116,6 +116,9 @@ /* SMP variation */ .macro get_saved_sp docfi=0 tosp=0 +#ifdef CONFIG_CPU_R5900 + sync.p +#endif ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) @@ -140,6 +143,9 @@ .endm .macro set_saved_sp stackp temp temp2 +#ifdef CONFIG_CPU_R5900 + sync.p +#endif ASM_CPUID_MFC0 \temp, ASM_SMP_CPUID_REG LONG_SRL \temp, SMP_CPUID_PTRSHIFT LONG_S \stackp, kernelsp(\temp) @@ -165,6 +171,9 @@ 1: move ra, k0 li k0, 3 mtc0 k0, $22 +#ifdef CONFIG_CPU_R5900 + sync.p +#endif #endif /* CONFIG_CPU_JUMP_WORKAROUNDS */ #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) @@ -195,6 +204,9 @@ .set push .set noat .set reorder +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k0, CP0_STATUS sll k0, 3 /* extract cu0 bit */ .set noreorder @@ -251,15 +263,24 @@ * need it to operate correctly */ LONG_S $0, PT_R0(sp) +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 v1, CP0_STATUS cfi_st v0, PT_R2, \docfi LONG_S v1, PT_STATUS(sp) cfi_st $4, PT_R4, \docfi +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 v1, CP0_CAUSE cfi_st $5, PT_R5, \docfi LONG_S v1, PT_CAUSE(sp) cfi_st $6, PT_R6, \docfi cfi_st ra, PT_R31, \docfi +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 ra, CP0_EPC cfi_st $7, PT_R7, \docfi #ifdef CONFIG_64BIT @@ -273,6 +294,9 @@ cfi_st $25, PT_R25, \docfi cfi_st $28, PT_R28, \docfi +#ifdef CONFIG_CPU_R5900 + sync.p +#endif /* Set thread_info if we're coming from user mode */ mfc0 k0, CP0_STATUS sll k0, 3 /* extract cu0 bit */ @@ -447,10 +471,16 @@ .set reorder .set noat RESET_MMR +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 a0, CP0_STATUS ori a0, STATMASK xori a0, STATMASK mtc0 a0, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif li v1, ST0_CU1 | ST0_FR | ST0_IM and a0, v1 LONG_L v0, PT_STATUS(sp) @@ -458,8 +488,14 @@ and v0, v1 or v0, a0 mtc0 v0, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif LONG_L v1, PT_EPC(sp) MTC0 v1, CP0_EPC +#ifdef CONFIG_CPU_R5900 + sync.p +#endif cfi_ld $31, PT_R31, \docfi cfi_ld $28, PT_R28, \docfi cfi_ld $25, PT_R25, \docfi @@ -503,11 +539,17 @@ * Set cp0 enable bit as sign that we're running on the kernel stack */ .macro CLI +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 t0, CP0_STATUS li t1, ST0_CU0 | STATMASK or t0, t1 xori t0, STATMASK mtc0 t0, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif irq_disable_hazard .endm @@ -516,11 +558,17 @@ * Set cp0 enable bit as sign that we're running on the kernel stack */ .macro STI +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 t0, CP0_STATUS li t1, ST0_CU0 | STATMASK or t0, t1 xori t0, STATMASK & ~1 mtc0 t0, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif irq_enable_hazard .endm @@ -530,6 +578,9 @@ * Set cp0 enable bit as sign that we're running on the kernel stack */ .macro KMODE +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 t0, CP0_STATUS li t1, ST0_CU0 | (STATMASK & ~1) #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) @@ -540,6 +591,9 @@ or t0, t1 xori t0, STATMASK & ~1 mtc0 t0, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif irq_disable_hazard .endm diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 398b905b027d..6eaf057e5d95 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -33,7 +33,13 @@ NESTED(except_vec3_generic, 0, sp) .set push .set noat #if R5432_CP0_INTERRUPT_WAR +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k0, CP0_INDEX +#endif +#ifdef CONFIG_CPU_R5900 + sync.p #endif mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c @@ -55,6 +61,9 @@ NESTED(except_vec3_r4000, 0, sp) .set push .set arch=r4000 .set noat +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k1, CP0_CAUSE li k0, 31<<2 andi k1, k1, 0x7c @@ -78,10 +87,16 @@ NESTED(except_vec3_r4000, 0, sp) * load / store will be re-executed. */ handle_vced: +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k0, CP0_BADVADDR li k1, -4 # Is this ... and k0, k1 # ... really needed? mtc0 zero, CP0_TAGLO +#ifdef CONFIG_CPU_R5900 + sync.p +#endif cache Index_Store_Tag_D, (k0) cache Hit_Writeback_Inv_SD, (k0) #ifdef CONFIG_PROC_FS @@ -93,6 +108,9 @@ handle_vced: eret handle_vcei: +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k0, CP0_BADVADDR cache Hit_Writeback_Inv_SD, (k0) # also cleans pi #ifdef CONFIG_PROC_FS @@ -138,12 +156,18 @@ LEAF(__r4k_wait) FEXPORT(rollback_\handler) .set push .set noat +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k0, CP0_EPC PTR_LA k1, __r4k_wait ori k0, 0x1f /* 32 byte rollback region */ xori k0, 0x1f bne k0, k1, \handler MTC0 k0, CP0_EPC +#ifdef CONFIG_CPU_R5900 + sync.p +#endif .set pop .endm @@ -164,11 +188,17 @@ NESTED(handle_int, PT_SIZE, sp) */ .set push .set noat +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k0, CP0_STATUS #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) and k0, ST0_IEP bnez k0, 1f +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k0, CP0_EPC .set noreorder j k0 @@ -349,6 +379,9 @@ NESTED(ejtag_debug_handler, PT_SIZE, sp) .set push .set noat MTC0 k0, CP0_DESAVE +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k0, CP0_DEBUG sll k0, k0, 30 # Check for SDBBP. @@ -404,6 +437,9 @@ NESTED(ejtag_debug_handler, PT_SIZE, sp) ejtag_return: back_to_back_c0_hazard +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k0, CP0_DESAVE .set mips32 deret @@ -494,6 +530,9 @@ NESTED(nmi_handler, PT_SIZE, sp) .endm .macro __build_clear_ade +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 t0, CP0_BADVADDR PTR_S t0, PT_BVADDR(sp) KMODE @@ -579,16 +618,28 @@ NESTED(nmi_handler, PT_SIZE, sp) .set noat .set noreorder /* check if TLB contains a entry for EPC */ +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k1, CP0_ENTRYHI andi k1, MIPS_ENTRYHI_ASID | MIPS_ENTRYHI_ASIDX +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k0, CP0_EPC PTR_SRL k0, _PAGE_SHIFT + 1 PTR_SLL k0, _PAGE_SHIFT + 1 or k1, k0 MTC0 k1, CP0_ENTRYHI +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mtc0_tlbw_hazard tlbp tlb_probe_hazard +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k1, CP0_INDEX .set pop bltz k1, handle_ri /* slow path */ @@ -601,6 +652,9 @@ NESTED(nmi_handler, PT_SIZE, sp) .set noreorder /* MIPS32: 0x7c03e83b: rdhwr v1,$29 */ /* microMIPS: 0x007d6b3c: rdhwr v1,$29 */ +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k1, CP0_EPC #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS64_R2) and k0, k1, 1 @@ -631,6 +685,9 @@ isrdhwr: /* The insn is rdhwr. No need to check CAUSE.BD here. */ get_saved_sp /* k1 := current_thread_info */ .set noreorder +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 k0, CP0_EPC #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ori k1, _THREAD_MASK @@ -648,6 +705,9 @@ isrdhwr: .set noat #endif MTC0 k0, CP0_EPC +#ifdef CONFIG_CPU_R5900 + sync.p +#endif /* I hope three instructions between MTC0 and ERET are enough... */ ori k1, _THREAD_MASK xori k1, _THREAD_MASK diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 351d40fe0859..aae4b17a33d0 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -34,10 +34,16 @@ */ .macro setup_c0_status set clr .set push +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 t0, CP0_STATUS or t0, ST0_CU0|\set|0x1f|\clr xor t0, 0x1f|\clr mtc0 t0, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif .set noreorder sll zero,3 # ehb .set pop @@ -132,6 +138,9 @@ dtb_found: #endif MTC0 zero, CP0_CONTEXT # clear context register +#ifdef CONFIG_CPU_R5900 + sync.p +#endif PTR_LA $28, init_thread_union /* Set the SP after an empty pt_regs. */ PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 58232ae6cfae..de4a1880e9a8 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -26,6 +26,9 @@ */ .align 5 LEAF(resume) +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 t1, CP0_STATUS LONG_S t1, THREAD_STATUS(a0) cpu_save_nonscratch a0 @@ -46,6 +49,9 @@ PTR_ADDU t0, $28, _THREAD_SIZE - 32 set_saved_sp t0, t1, t2 +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 t1, CP0_STATUS /* Do we really need this? */ li a3, 0xff01 and t1, a3 @@ -54,6 +60,9 @@ and a2, a3 or a2, t1 mtc0 a2, CP0_STATUS +#ifdef CONFIG_CPU_R5900 + sync.p +#endif move v0, a0 jr ra END(resume) diff --git a/arch/mips/mm/cex-gen.S b/arch/mips/mm/cex-gen.S index 45dff5cd4b8e..c5075651229c 100644 --- a/arch/mips/mm/cex-gen.S +++ b/arch/mips/mm/cex-gen.S @@ -27,11 +27,17 @@ * in the cache, we may not be able to recover. As a * first-order desperate measure, turn off KSEG0 cacheing. */ +#ifdef CONFIG_CPU_R5900 + sync.p +#endif mfc0 k0,CP0_CONFIG li k1,~CONF_CM_CMASK and k0,k0,k1 ori k0,k0,CONF_CM_UNCACHED mtc0 k0,CP0_CONFIG +#ifdef CONFIG_CPU_R5900 + sync.p +#endif /* Give it a few cycles to sink in... */ nop nop diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S index 77db401fc620..fe2b2c61cca7 100644 --- a/arch/mips/mm/tlbex-fault.S +++ b/arch/mips/mm/tlbex-fault.S @@ -14,6 +14,9 @@ NESTED(tlb_do_page_fault_\write, PT_SIZE, sp) .cfi_signal_frame SAVE_ALL docfi=1 +#ifdef CONFIG_CPU_R5900 + sync.p +#endif MFC0 a2, CP0_BADVADDR KMODE move a0, sp diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 144ceb0fba88..543ddb22b0d9 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -691,6 +691,9 @@ static void build_restore_pagemask(u32 **p, struct uasm_reloc **r, uasm_i_mtc0(p, 0, C0_PAGEMASK); } } +#ifdef CONFIG_CPU_R5900 + uasm_i_syncp(p); +#endif } static void build_huge_tlb_write_entry(u32 **p, struct uasm_label **l, @@ -703,6 +706,9 @@ static void build_huge_tlb_write_entry(u32 **p, struct uasm_label **l, uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16); uasm_i_ori(p, tmp, tmp, PM_HUGE_MASK & 0xffff); uasm_i_mtc0(p, tmp, C0_PAGEMASK); +#ifdef CONFIG_CPU_R5900 + uasm_i_syncp(p); +#endif build_tlb_write_entry(p, l, r, wmode); @@ -963,21 +969,21 @@ void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) { if (pgd_reg != -1) { /* pgd is in pgd_reg */ - uasm_i_mfc0(p, ptr, c0_kscratch(), pgd_reg); - uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */ + UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); + UASM_i_MFC0(p, tmp, C0_BADVADDR); /* get faulting address */ } else { long pgdc = (long)pgd_current; /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ #ifdef CONFIG_SMP - uasm_i_mfc0(p, ptr, SMP_CPUID_REG); + UASM_i_MFC0(p, ptr, SMP_CPUID_REG); UASM_i_LA_mostly(p, tmp, pgdc); uasm_i_srl(p, ptr, ptr, SMP_CPUID_PTRSHIFT); uasm_i_addu(p, ptr, tmp, ptr); #else UASM_i_LA_mostly(p, ptr, pgdc); #endif - uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */ + UASM_i_MFC0(p, tmp, C0_BADVADDR); /* get faulting address */ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr); } uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */ From patchwork Sun Sep 1 15:39:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125323 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0C0321890 for ; Sun, 1 Sep 2019 15:46:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E935C23429 for ; Sun, 1 Sep 2019 15:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728888AbfIAPqL (ORCPT ); Sun, 1 Sep 2019 11:46:11 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41310 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728621AbfIAPqL (ORCPT ); Sun, 1 Sep 2019 11:46:11 -0400 X-Greylist: delayed 443 seconds by postgrey-1.27 at vger.kernel.org; Sun, 01 Sep 2019 11:46:10 EDT Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id A30C73F6A3 for ; Sun, 1 Sep 2019 17:39:51 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id TPq4JKTS86Ot for ; Sun, 1 Sep 2019 17:39:50 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id B4B4A3F695 for ; Sun, 1 Sep 2019 17:39:50 +0200 (CEST) Date: Sun, 1 Sep 2019 17:39:50 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 010/120] MIPS: R5900: Workaround exception NOP execution bug (FLX05) Message-ID: <9b8beb1e11159a3a42233c64ea86607a5954d558.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org For the R5900, there are cases in which the first two instructions in an exception handler are executed as NOP instructions, when certain exceptions occur and then a bus error occurs immediately before jumping to the exception handler (FLX05)[1]. The corrective measure is to place NOP in the first two instruction locations in all exception handlers. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. 1-11, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- arch/mips/kernel/genex.S | 5 +++++ arch/mips/kernel/traps.c | 6 ++++++ arch/mips/mm/tlbex.c | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 6eaf057e5d95..f57842b785b2 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -32,6 +32,11 @@ NESTED(except_vec3_generic, 0, sp) .set push .set noat +#ifdef CONFIG_CPU_R5900 + /* Workaround for R5900 exception execution bug (FLX05). */ + nop + nop +#endif #if R5432_CP0_INTERRUPT_WAR #ifdef CONFIG_CPU_R5900 sync.p diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9423b9a2eb67..9c98475c7dc6 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1953,6 +1953,12 @@ void __init *set_except_vector(int n, void *addr) #endif u32 *buf = (u32 *)(ebase + 0x200); unsigned int k0 = 26; + +#ifdef CONFIG_CPU_R5900 + /* Workaround for R5900 exception execution bug (FLX05). */ + uasm_i_nop(&buf); + uasm_i_nop(&buf); +#endif if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) { uasm_i_j(&buf, handler & ~jump_mask); uasm_i_nop(&buf); diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 543ddb22b0d9..82136c346885 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -1313,6 +1313,12 @@ static void build_r4000_tlb_refill_handler(void) memset(relocs, 0, sizeof(relocs)); memset(final_handler, 0, sizeof(final_handler)); +#ifdef CONFIG_CPU_R5900 + /* Workaround for R5900 exception execution bug (FLX05). */ + uasm_i_nop(&p); + uasm_i_nop(&p); +#endif + if (IS_ENABLED(CONFIG_64BIT) && (scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) { htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1, scratch_reg); From patchwork Sun Sep 1 15:40:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125331 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ED82F16B1 for ; Sun, 1 Sep 2019 15:46:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D517821897 for ; Sun, 1 Sep 2019 15:46:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729146AbfIAPq5 (ORCPT ); Sun, 1 Sep 2019 11:46:57 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56632 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728980AbfIAPq5 (ORCPT ); Sun, 1 Sep 2019 11:46:57 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 6405C3F73E for ; Sun, 1 Sep 2019 17:40:13 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cMHQ580nK6w4 for ; Sun, 1 Sep 2019 17:40:12 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 6A5503F708 for ; Sun, 1 Sep 2019 17:40:12 +0200 (CEST) Date: Sun, 1 Sep 2019 17:40:12 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 011/120] MIPS: R5900: Avoid pipeline hazard with the TLBP instruction Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org On the R5900, the TLBP instruction must be immediately followed by an ERET or a SYNC.P instruction[1]. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. C-37, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- arch/mips/mm/tlbex.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 82136c346885..0519e2eafbb8 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -489,6 +489,19 @@ static void __maybe_unused build_tlb_probe_entry(u32 **p) uasm_i_tlbp(p); break; + case CPU_R5900: + /* + * On the R5900, the TLBWP instruction must be immediately + * followed by an ERET or a SYNC.P instruction. + */ + uasm_i_tlbp(p); + uasm_i_syncp(p); + uasm_i_nop(p); + uasm_i_nop(p); + uasm_i_nop(p); + uasm_i_nop(p); + break; + default: uasm_i_tlbp(p); break; From patchwork Sun Sep 1 15:40:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125335 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B08F112C for ; Sun, 1 Sep 2019 15:46:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 276982342E for ; Sun, 1 Sep 2019 15:46:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728900AbfIAPq5 (ORCPT ); Sun, 1 Sep 2019 11:46:57 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56634 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728621AbfIAPq5 (ORCPT ); Sun, 1 Sep 2019 11:46:57 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 438D93F897 for ; Sun, 1 Sep 2019 17:40:27 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mfyUCjypZbOB for ; Sun, 1 Sep 2019 17:40:26 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 4A01A3F7B1 for ; Sun, 1 Sep 2019 17:40:26 +0200 (CEST) Date: Sun, 1 Sep 2019 17:40:26 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 012/120] MIPS: R5900: Avoid pipeline hazards with the TLBW[IR] instructions Message-ID: <55596f09de274312357656ee483314ec4ef8c51a.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org On the R5900, the TLBWI[1] and TLBWR[2] instructions must be followed by an ERET or a SYNC.P instruction to ensure a TLB update. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. C-39, https://wiki.qemu.org/File:C790.pdf [2] Ibid. p. C-40. Signed-off-by: Fredrik Noring --- arch/mips/mm/tlbex.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 0519e2eafbb8..89ff0eae5397 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -622,6 +622,15 @@ void build_tlb_write_entry(u32 **p, struct uasm_label **l, uasm_i_nop(p); tlbw(p); break; + case CPU_R5900: + /* + * On the R5900, the TLBWI and TLBWR instructions must be + * followed by an ERET or a SYNC.P instruction to ensure a + * TLB update. + */ + tlbw(p); + uasm_i_syncp(p); + break; case CPU_JZRISC: tlbw(p); From patchwork Sun Sep 1 15:40:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125363 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C4BF91890 for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ACE2920828 for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728763AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57482 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729172AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 7DDBC40408 for ; Sun, 1 Sep 2019 17:40:56 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yOALxI-TnqKW for ; Sun, 1 Sep 2019 17:40:55 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 8CE0F403B7 for ; Sun, 1 Sep 2019 17:40:55 +0200 (CEST) Date: Sun, 1 Sep 2019 17:40:55 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 013/120] MIPS: R5900: Avoid pipeline hazard with the TLBR instruction Message-ID: <815e58a51f40c56ea8b02bc39f9ed5f1639a69ee.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org On the R5900, the TLBR instruction must be immediately followed by an ERET or a SYNC.P instruction[1]. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. C-38, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mipsregs.h | 4 ++++ arch/mips/mm/tlbex.c | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 2aa947b3d0d1..ec22406c800f 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -2728,6 +2728,10 @@ static inline void tlb_read(void) __asm__ __volatile__( ".set noreorder\n\t" +#ifdef CONFIG_CPU_R5900 + /* instruction must not be at the end of a page. */ + ".align 8\n\t" +#endif "tlbr\n\t" #ifdef CONFIG_CPU_R5900 "sync.p\n\t" diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 89ff0eae5397..1caa0214d57a 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -2185,6 +2185,18 @@ static void build_r4000_tlb_load_handler(void) uasm_i_tlbr(&p); +#ifdef CONFIG_CPU_R5900 + /* + * On the R5900, the TLBR instruction must be immediately + * followed by an ERET or a SYNC.P instruction. + */ + uasm_i_syncp(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); +#endif + switch (current_cpu_type()) { default: if (cpu_has_mips_r2_exec_hazard) { @@ -2260,6 +2272,18 @@ static void build_r4000_tlb_load_handler(void) uasm_i_tlbr(&p); +#ifdef CONFIG_CPU_R5900 + /* + * On the R5900, the TLBR instruction must be immediately + * followed by an ERET or a SYNC.P instruction. + */ + uasm_i_syncp(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); +#endif + switch (current_cpu_type()) { default: if (cpu_has_mips_r2_exec_hazard) { From patchwork Sun Sep 1 15:41:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125361 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A339D112C for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8A5A820828 for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729159AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57478 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728763AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id EB2774041C for ; Sun, 1 Sep 2019 17:41:10 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WdbLCjR3cars for ; Sun, 1 Sep 2019 17:41:10 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 0A94C4040E for ; Sun, 1 Sep 2019 17:41:09 +0200 (CEST) Date: Sun, 1 Sep 2019 17:41:09 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 014/120] MIPS: R5900: Install final length of TLB refill handler rather than 256 bytes Message-ID: <3eb0ba899a344ff9e83f1c5495010e7b1ee474f0.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The R5900 TLB refill handler is limited to 128 bytes, corresponding to 32 instructions. Installing a 256 byte TLB refill handler for the R5900 at address 0x80000000 overwrites the performance counter handler at address 0x80000080, according to the TX79 manual[1]: Table 5-2. Exception Vectors for Level 1 exceptions Exceptions | Vector Address | BEV = 0 | BEV = 1 ---------------------+------------+----------- TLB Refill (EXL = 0) | 0x80000000 | 0xBFC00200 TLB Refill (EXL = 1) | 0x80000180 | 0xBFC00380 Interrupt | 0x80000200 | 0xBFC00400 Others | 0x80000180 | 0xBFC00380 ---------------------+------------+----------- Table 5-3. Exception Vectors for Level 2 exceptions Exceptions | Vector Address | DEV = 0 | DEV = 1 ---------------------+------------+----------- Reset, NMI | 0xBFC00000 | 0xBFC00000 Performance Counter | 0x80000080 | 0xBFC00280 Debug, SIO | 0x80000100 | 0xBFC00300 ---------------------+------------+----------- References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. 5-7, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- arch/mips/mm/tlbex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 1caa0214d57a..d356953509e6 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -1502,9 +1502,9 @@ static void build_r4000_tlb_refill_handler(void) pr_debug("Wrote TLB refill handler (%u instructions).\n", final_len); - memcpy((void *)ebase, final_handler, 0x100); - local_flush_icache_range(ebase, ebase + 0x100); - dump_handler("r4000_tlb_refill", (u32 *)ebase, (u32 *)(ebase + 0x100)); + memcpy((void *)ebase, final_handler, 4 * final_len); + local_flush_icache_range(ebase, ebase + 4 * final_len); + dump_handler("r4000_tlb_refill", (u32 *)ebase, (u32 *)(ebase + 4 * final_len)); } static void setup_pw(void) From patchwork Sun Sep 1 15:41:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125359 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 80F821395 for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5ECCA20828 for ; Sun, 1 Sep 2019 15:48:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729175AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57480 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729159AbfIAPsW (ORCPT ); Sun, 1 Sep 2019 11:48:22 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 0782640437 for ; Sun, 1 Sep 2019 17:41:20 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id h-DMrQTc6TcZ for ; Sun, 1 Sep 2019 17:41:19 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 261274041E for ; Sun, 1 Sep 2019 17:41:19 +0200 (CEST) Date: Sun, 1 Sep 2019 17:41:18 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 015/120] MIPS: R5900: Verify that the TLB refill handler does not overflow Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The R5900 TLB refill handler is limited to 32 instructions (0x80 bytes, which is 0x80000080 - 0x80000000) according to the TX79 manual[1]: Table 5-2. Exception Vectors for Level 1 exceptions Exceptions | Vector Address | BEV = 0 | BEV = 1 ---------------------+------------+----------- TLB Refill (EXL = 0) | 0x80000000 | 0xBFC00200 TLB Refill (EXL = 1) | 0x80000180 | 0xBFC00380 Interrupt | 0x80000200 | 0xBFC00400 Others | 0x80000180 | 0xBFC00380 ---------------------+------------+----------- Table 5-3. Exception Vectors for Level 2 exceptions Exceptions | Vector Address | DEV = 0 | DEV = 1 ---------------------+------------+----------- Reset, NMI | 0xBFC00000 | 0xBFC00000 Performance Counter | 0x80000080 | 0xBFC00280 Debug, SIO | 0x80000100 | 0xBFC00300 ---------------------+------------+----------- References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. 5-7, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- arch/mips/mm/tlbex.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index d356953509e6..1bd134b6f033 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -1404,6 +1404,10 @@ static void build_r4000_tlb_refill_handler(void) * unused. */ switch (boot_cpu_type()) { + case CPU_R5900: + if ((p - tlb_handler) > 32) + panic("TLB refill handler space exceeded"); + /* Fallthrough */ default: if (sizeof(long) == 4) { case CPU_LOONGSON2: From patchwork Sun Sep 1 15:41:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125393 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 84E091395 for ; Sun, 1 Sep 2019 15:51:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 63036233A2 for ; Sun, 1 Sep 2019 15:51:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728753AbfIAPvL (ORCPT ); Sun, 1 Sep 2019 11:51:11 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41792 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726260AbfIAPvK (ORCPT ); Sun, 1 Sep 2019 11:51:10 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 1B13F3F6B8 for ; Sun, 1 Sep 2019 17:41:42 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BysIxn_d_7g7 for ; Sun, 1 Sep 2019 17:41:41 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 7C8AB3F69D for ; Sun, 1 Sep 2019 17:41:41 +0200 (CEST) Date: Sun, 1 Sep 2019 17:41:41 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 016/120] MIPS: R5900: The ERET instruction has issues with delay slot and CACHE Message-ID: <3a2945e9ac2b70c6f6b14100bf8c805d3ef51ce0.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- The Linux 2.6 port to the PlayStation 2 has this remark. I don't know where it comes from. --- arch/mips/mm/tlbex.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 1bd134b6f033..9d5864b20e9f 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -1383,6 +1383,16 @@ static void build_r4000_tlb_refill_handler(void) uasm_l_leave(&l, p); uasm_i_eret(&p); /* return from trap */ } + +#ifdef CONFIG_CPU_R5900 + /* There should be nothing which can be interpreted as cache instruction. */ + uasm_i_nop(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); + uasm_i_nop(&p); +#endif + #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT uasm_l_tlb_huge_update(&l, p); if (htlb_info.need_reload_pte) @@ -2129,6 +2139,14 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, uasm_l_leave(l, *p); build_restore_work_registers(p); uasm_i_eret(p); /* return from trap */ +#ifdef CONFIG_CPU_R5900 + /* There should be nothing which can be interpreted as cache instruction. */ + uasm_i_nop(p); + uasm_i_nop(p); + uasm_i_nop(p); + uasm_i_nop(p); + uasm_i_nop(p); +#endif #ifdef CONFIG_64BIT build_get_pgd_vmalloc64(p, l, r, tmp, ptr, not_refill); From patchwork Sun Sep 1 15:42:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125399 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8D62C1890 for ; Sun, 1 Sep 2019 15:51:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 75C9E20828 for ; Sun, 1 Sep 2019 15:51:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726260AbfIAPv6 (ORCPT ); Sun, 1 Sep 2019 11:51:58 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56980 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAPv5 (ORCPT ); Sun, 1 Sep 2019 11:51:57 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id D59A03F8A6 for ; Sun, 1 Sep 2019 17:42:04 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oDsKhZb89sZS for ; Sun, 1 Sep 2019 17:42:03 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id D7BA63F752 for ; Sun, 1 Sep 2019 17:42:03 +0200 (CEST) Date: Sun, 1 Sep 2019 17:42:03 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 017/120] MIPS: R5900: Define CACHE instruction operation field encodings Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The CACHE instruction operation field encodings are listed in the TX79 manual[1]: Table C-1. CACHE Instruction Op Field Encoding Mnemonic | OpCode | CACHE Instruction | Target ---------+--------+------------------------------+------------------ IXIN | 00111 | INDEX INVALIDATE | Instruction Cache IXLTG | 00000 | INDEX LOAD TAG | Instruction Cache IXSTG | 00100 | INDEX STORE TAG | Instruction Cache IHIN | 01011 | HIT INVALIDATE | Instruction Cache IFL | 01110 | FILL | Instruction Cache IXLDT | 00001 | INDEX LOAD DATA | Instruction Cache IXSDT | 00101 | INDEX STORE DATA | Instruction Cache ---------+--------+------------------------------+------------------ BXLBT | 00010 | INDEX LOAD BTACC | BTAC BXSBT | 00110 | INDEX STORE BTAC | BTAC BFH | 01100 | BTAC FLUSH | BTAC BHINBT | 01010 | HIT INVALIDATE BTAC | BTAC ---------+--------+------------------------------+------------------ DXWBIN | 10100 | INDEX WRITE BACK INVALIDATE | Data Cache DXLTG | 10000 | INDEX LOAD TAG | Data Cache DXSTG | 10010 | INDEX STORE TAG | Data Cache DXIN | 10110 | INDEX INVALIDATE | Data Cache DHIN | 11010 | HIT INVALIDATE | Data Cache DHWBIN | 11000 | HIT WRITEBACK INVALIDATE | Data Cache DXLDT | 10001 | INDEX LOAD DATA | Data Cache DXSDT | 10011 | INDEX STORE DATA | Data Cache DHWOIN | 11100 | HIT WRITEBACK W/O INVALIDATE | Data Cache ---------+--------+------------------------------+------------------ References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. C-6, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- arch/mips/include/asm/cacheops.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index 8031fbc6b69a..3a6b34be1122 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -34,6 +34,17 @@ /* * Cache Operations available on all MIPS processors with R4000-style caches */ +#ifdef CONFIG_CPU_R5900 +#define Index_Invalidate_I 0x07 +#define Index_Writeback_Inv_D 0x14 +#define Index_Load_Tag_I 0x00 +#define Index_Load_Tag_D 0x10 +#define Index_Store_Tag_I 0x04 +#define Index_Store_Tag_D 0x12 +#define Hit_Invalidate_I 0x0b +#define Hit_Invalidate_D 0x1a +#define Hit_Writeback_Inv_D 0x18 +#else #define Index_Invalidate_I (Cache_I | Index_Writeback_Inv) #define Index_Writeback_Inv_D (Cache_D | Index_Writeback_Inv) #define Index_Load_Tag_I (Cache_I | Index_Load_Tag) @@ -43,14 +54,20 @@ #define Hit_Invalidate_I (Cache_I | Hit_Invalidate) #define Hit_Invalidate_D (Cache_D | Hit_Invalidate) #define Hit_Writeback_Inv_D (Cache_D | Hit_Writeback_Inv) +#endif /* * R4000-specific cacheops */ #define Create_Dirty_Excl_D (Cache_D | 0x0c) +#ifdef CONFIG_CPU_R5900 +#define Fill 0x0e +#define Hit_Writeback_D 0x1c +#else #define Fill (Cache_I | 0x14) #define Hit_Writeback_I (Cache_I | Hit_Writeback) #define Hit_Writeback_D (Cache_D | Hit_Writeback) +#endif /* * R4000SC and R4400SC-specific cacheops From patchwork Sun Sep 1 15:42:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125391 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5A00C112C for ; Sun, 1 Sep 2019 15:51:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 36CF8233A2 for ; Sun, 1 Sep 2019 15:51:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728840AbfIAPvL (ORCPT ); Sun, 1 Sep 2019 11:51:11 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41794 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728753AbfIAPvK (ORCPT ); Sun, 1 Sep 2019 11:51:10 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 4FAFA3F6E5 for ; Sun, 1 Sep 2019 17:42:27 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id S1ySVjPVa914 for ; Sun, 1 Sep 2019 17:42:26 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 9BA213F6D1 for ; Sun, 1 Sep 2019 17:42:26 +0200 (CEST) Date: Sun, 1 Sep 2019 17:42:26 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 018/120] MIPS: R5900: Workaround where MSB must be 0 for the instruction cache Message-ID: <5e49b0399a19c01bf1964daec5e30a1417da02a7.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- The Linux 2.6 port to the PlayStation 2 has this remark. I don't know where it comes from. --- arch/mips/include/asm/r4kcache.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index 7f4a32d3345a..e00087db9d74 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h @@ -37,7 +37,12 @@ extern void (*r4k_blast_icache)(void); * - We need a properly sign extended address for 64-bit code. To get away * without ifdefs we let the compiler do it by a type cast. */ +#ifdef CONFIG_CPU_R5900 +/* MSB must be 0 for the instruction cache due to an R5900 bug. */ +#define INDEX_BASE 0 +#else #define INDEX_BASE CKSEG0 +#endif #define cache_op(op,addr) \ __asm__ __volatile__( \ From patchwork Sun Sep 1 15:42:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125401 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 94198112C for ; Sun, 1 Sep 2019 15:52:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6774520828 for ; Sun, 1 Sep 2019 15:52:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726727AbfIAPwA (ORCPT ); Sun, 1 Sep 2019 11:52:00 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56982 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728676AbfIAPwA (ORCPT ); Sun, 1 Sep 2019 11:52:00 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 4774B402B7; Sun, 1 Sep 2019 17:42:54 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FRuh80TaW6ln; Sun, 1 Sep 2019 17:42:52 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id D75C43F909; Sun, 1 Sep 2019 17:42:52 +0200 (CEST) Date: Sun, 1 Sep 2019 17:42:52 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 019/120] MIPS: R5900: Use SYNC.L for data cache and SYNC.P for instruction cache Message-ID: <4908071c89e101af477fefb28cdd1ba69ffb63d1.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Toshiba TX79 manual programming notes[1]: For all CACHE sub-operations which operate on the instruction cache the following programming restrictions have to be followed: 1. A sequence of CACHE instructions has to be directly preceded and followed by a SYNC.P instruction. 2. Each individual FILL sub-operation has to be followed by a SYNC.L instruction. For all CACHE sub-operations which operate on the data cache the following programming restrictions have to be followed: 1. A sequence of CACHE instructions have to be directly preceded and followed by a SYNC.L instruction. 2. Each of the three WRITEBACK sub-operations have to be individually followed by a SYNC.L instruction. For all CACHE sub-operations which operate on the BTAC the following programming restrictions have to be followed: 1. A sequence of CACHE instructions have to be directly preceded and followed by a SYNC.P instruction. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. C-13, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring --- This is perhaps the most complex change for the R5900. The code comes from the Linux 2.6 port to the PlayStation 2. --- arch/mips/include/asm/r4kcache.h | 239 ++++++++++++++++++++++++------- arch/mips/mm/c-r4k.c | 8 +- 2 files changed, 189 insertions(+), 58 deletions(-) diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index e00087db9d74..da9f55f36fcf 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h @@ -44,7 +44,7 @@ extern void (*r4k_blast_icache)(void); #define INDEX_BASE CKSEG0 #endif -#define cache_op(op,addr) \ +#define cache_op_s(op,addr) \ __asm__ __volatile__( \ " .set push \n" \ " .set noreorder \n" \ @@ -53,56 +53,85 @@ extern void (*r4k_blast_icache)(void); " .set pop \n" \ : \ : "i" (op), "R" (*(unsigned char *)(addr))) +#ifdef CONFIG_CPU_R5900 +#define cache_op_d(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " sync.l \n" \ + " cache %0, %1 \n" \ + " sync.l \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) +#define cache_op_i(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " sync.p \n" \ + " cache %0, %1 \n" \ + " sync.p \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) +#else +#define cache_op_d cache_op_s +#define cache_op_i cache_op_s +#define cache_op cache_op_s +#endif +#define cache_op_t cache_op_s static inline void flush_icache_line_indexed(unsigned long addr) { - cache_op(Index_Invalidate_I, addr); + cache_op_i(Index_Invalidate_I, addr); } static inline void flush_dcache_line_indexed(unsigned long addr) { - cache_op(Index_Writeback_Inv_D, addr); + cache_op_d(Index_Writeback_Inv_D, addr); } static inline void flush_scache_line_indexed(unsigned long addr) { - cache_op(Index_Writeback_Inv_SD, addr); + cache_op_s(Index_Writeback_Inv_SD, addr); } static inline void flush_icache_line(unsigned long addr) { switch (boot_cpu_type()) { case CPU_LOONGSON2: - cache_op(Hit_Invalidate_I_Loongson2, addr); + cache_op_i(Hit_Invalidate_I_Loongson2, addr); break; default: - cache_op(Hit_Invalidate_I, addr); + cache_op_i(Hit_Invalidate_I, addr); break; } } static inline void flush_dcache_line(unsigned long addr) { - cache_op(Hit_Writeback_Inv_D, addr); + cache_op_d(Hit_Writeback_Inv_D, addr); } static inline void invalidate_dcache_line(unsigned long addr) { - cache_op(Hit_Invalidate_D, addr); + cache_op_d(Hit_Invalidate_D, addr); } static inline void invalidate_scache_line(unsigned long addr) { - cache_op(Hit_Invalidate_SD, addr); + cache_op_s(Hit_Invalidate_SD, addr); } static inline void flush_scache_line(unsigned long addr) { - cache_op(Hit_Writeback_Inv_SD, addr); + cache_op_s(Hit_Writeback_Inv_SD, addr); } -#define protected_cache_op(op,addr) \ +#define protected_cache_op_s(op,addr) \ ({ \ int __err = 0; \ __asm__ __volatile__( \ @@ -124,6 +153,49 @@ static inline void flush_scache_line(unsigned long addr) __err; \ }) +#ifdef CONFIG_CPU_R5900 +#define protected_cache_op_d(op,addr) \ +({ \ + int __err = 0; \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " sync.l \n" \ + "1: cache %0, (%1) \n" \ + " sync.l \n" \ + "2: .set pop \n" \ + " .section __ex_table,\"a\" \n" \ + " "STR(PTR)" 1b, 2b \n" \ + " .previous" \ + : \ + : "i" (op), "r" (addr)); \ + __err; \ +}) + +#define protected_cache_op_i(op,addr) \ +({ \ + int __err = 0; \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " sync.p \n" \ + "1: cache %0, (%1) \n" \ + " sync.p \n" \ + "2: .set pop \n" \ + " .section __ex_table,\"a\" \n" \ + " "STR(PTR)" 1b, 2b \n" \ + " .previous" \ + : \ + : "i" (op), "r" (addr)); \ + __err; \ +}) +#else +#define protected_cache_op_i protected_cache_op_s +#define protected_cache_op_d protected_cache_op_s +#define protected_cache_op protected_cache_op_s +#endif #define protected_cachee_op(op,addr) \ ({ \ @@ -155,13 +227,13 @@ static inline int protected_flush_icache_line(unsigned long addr) { switch (boot_cpu_type()) { case CPU_LOONGSON2: - return protected_cache_op(Hit_Invalidate_I_Loongson2, addr); + return protected_cache_op_i(Hit_Invalidate_I_Loongson2, addr); default: #ifdef CONFIG_EVA - return protected_cachee_op(Hit_Invalidate_I, addr); + return protected_cachee_op_i(Hit_Invalidate_I, addr); #else - return protected_cache_op(Hit_Invalidate_I, addr); + return protected_cache_op_i(Hit_Invalidate_I, addr); #endif } } @@ -175,18 +247,18 @@ static inline int protected_flush_icache_line(unsigned long addr) static inline int protected_writeback_dcache_line(unsigned long addr) { #ifdef CONFIG_EVA - return protected_cachee_op(Hit_Writeback_Inv_D, addr); + return protected_cachee_op_d(Hit_Writeback_Inv_D, addr); #else - return protected_cache_op(Hit_Writeback_Inv_D, addr); + return protected_cache_op_d(Hit_Writeback_Inv_D, addr); #endif } static inline int protected_writeback_scache_line(unsigned long addr) { #ifdef CONFIG_EVA - return protected_cachee_op(Hit_Writeback_Inv_SD, addr); + return protected_cachee_op_s(Hit_Writeback_Inv_SD, addr); #else - return protected_cache_op(Hit_Writeback_Inv_SD, addr); + return protected_cache_op_s(Hit_Writeback_Inv_SD, addr); #endif } @@ -195,7 +267,7 @@ static inline int protected_writeback_scache_line(unsigned long addr) */ static inline void invalidate_tcache_page(unsigned long addr) { - cache_op(Page_Invalidate_T, addr); + cache_op_t(Page_Invalidate_T, addr); } #ifndef CONFIG_CPU_MIPSR6 @@ -276,6 +348,65 @@ static inline void invalidate_tcache_page(unsigned long addr) : \ : "r" (base), \ "i" (op)); +#ifdef CONFIG_CPU_R5900 +#define cache64_unroll32_d(base,op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " sync.l \n" \ + " cache %1, 0x000(%0); sync.l; cache %1, 0x040(%0); sync.l \n" \ + " cache %1, 0x080(%0); sync.l; cache %1, 0x0c0(%0); sync.l \n" \ + " cache %1, 0x100(%0); sync.l; cache %1, 0x140(%0); sync.l \n" \ + " cache %1, 0x180(%0); sync.l; cache %1, 0x1c0(%0); sync.l \n" \ + " cache %1, 0x200(%0); sync.l; cache %1, 0x240(%0); sync.l \n" \ + " cache %1, 0x280(%0); sync.l; cache %1, 0x2c0(%0); sync.l \n" \ + " cache %1, 0x300(%0); sync.l; cache %1, 0x340(%0); sync.l \n" \ + " cache %1, 0x380(%0); sync.l; cache %1, 0x3c0(%0); sync.l \n" \ + " cache %1, 0x400(%0); sync.l; cache %1, 0x440(%0); sync.l \n" \ + " cache %1, 0x480(%0); sync.l; cache %1, 0x4c0(%0); sync.l \n" \ + " cache %1, 0x500(%0); sync.l; cache %1, 0x540(%0); sync.l \n" \ + " cache %1, 0x580(%0); sync.l; cache %1, 0x5c0(%0); sync.l \n" \ + " cache %1, 0x600(%0); sync.l; cache %1, 0x640(%0); sync.l \n" \ + " cache %1, 0x680(%0); sync.l; cache %1, 0x6c0(%0); sync.l \n" \ + " cache %1, 0x700(%0); sync.l; cache %1, 0x740(%0); sync.l \n" \ + " cache %1, 0x780(%0); sync.l; cache %1, 0x7c0(%0); sync.l \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); + +#define cache64_unroll32_i(base,op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " sync.p \n" \ + " cache %1, 0x000(%0); cache %1, 0x040(%0) \n" \ + " cache %1, 0x080(%0); cache %1, 0x0c0(%0) \n" \ + " cache %1, 0x100(%0); cache %1, 0x140(%0) \n" \ + " cache %1, 0x180(%0); cache %1, 0x1c0(%0) \n" \ + " cache %1, 0x200(%0); cache %1, 0x240(%0) \n" \ + " cache %1, 0x280(%0); cache %1, 0x2c0(%0) \n" \ + " cache %1, 0x300(%0); cache %1, 0x340(%0) \n" \ + " cache %1, 0x380(%0); cache %1, 0x3c0(%0) \n" \ + " cache %1, 0x400(%0); cache %1, 0x440(%0) \n" \ + " cache %1, 0x480(%0); cache %1, 0x4c0(%0) \n" \ + " cache %1, 0x500(%0); cache %1, 0x540(%0) \n" \ + " cache %1, 0x580(%0); cache %1, 0x5c0(%0) \n" \ + " cache %1, 0x600(%0); cache %1, 0x640(%0) \n" \ + " cache %1, 0x680(%0); cache %1, 0x6c0(%0) \n" \ + " cache %1, 0x700(%0); cache %1, 0x740(%0) \n" \ + " cache %1, 0x780(%0); cache %1, 0x7c0(%0) \n" \ + " sync.p \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); +#else +#define cache64_unroll32_i cache64_unroll32 +#define cache64_unroll32_d cache64_unroll32 +#endif #define cache128_unroll32(base,op) \ __asm__ __volatile__( \ @@ -532,7 +663,7 @@ static inline void invalidate_tcache_page(unsigned long addr) "i" (op)); /* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */ -#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra) \ +#define __BUILD_BLAST_CACHE(fn_pfx, pfx, desc, indexop, hitop, lsize, extra) \ static inline void extra##blast_##pfx##cache##lsize(void) \ { \ unsigned long start = INDEX_BASE; \ @@ -544,7 +675,7 @@ static inline void extra##blast_##pfx##cache##lsize(void) \ \ for (ws = 0; ws < ws_end; ws += ws_inc) \ for (addr = start; addr < end; addr += lsize * 32) \ - cache##lsize##_unroll32(addr|ws, indexop); \ + cache##lsize##_unroll32##fn_pfx(addr|ws, indexop); \ } \ \ static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \ @@ -553,7 +684,7 @@ static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \ unsigned long end = page + PAGE_SIZE; \ \ do { \ - cache##lsize##_unroll32(start, hitop); \ + cache##lsize##_unroll32##fn_pfx(start, hitop); \ start += lsize * 32; \ } while (start < end); \ } \ @@ -570,29 +701,29 @@ static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long \ for (ws = 0; ws < ws_end; ws += ws_inc) \ for (addr = start; addr < end; addr += lsize * 32) \ - cache##lsize##_unroll32(addr|ws, indexop); \ + cache##lsize##_unroll32##fn_pfx(addr|ws, indexop); \ } -__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, ) -__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, ) -__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, ) -__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, ) -__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, ) -__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_) -__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, ) -__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, ) -__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, ) -__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, ) -__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, ) -__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, ) -__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, ) - -__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, ) -__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, ) -__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, ) -__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, ) -__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, ) -__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, ) +__BUILD_BLAST_CACHE(, d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, ) +__BUILD_BLAST_CACHE(, i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, ) +__BUILD_BLAST_CACHE(, s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, ) +__BUILD_BLAST_CACHE(, d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, ) +__BUILD_BLAST_CACHE(, i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, ) +__BUILD_BLAST_CACHE(, i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_) +__BUILD_BLAST_CACHE(, s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, ) +__BUILD_BLAST_CACHE(_d, d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, ) +__BUILD_BLAST_CACHE(_i, i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, ) +__BUILD_BLAST_CACHE(, s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, ) +__BUILD_BLAST_CACHE(, d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, ) +__BUILD_BLAST_CACHE(, i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, ) +__BUILD_BLAST_CACHE(, s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, ) + +__BUILD_BLAST_CACHE(, inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, ) +__BUILD_BLAST_CACHE(, inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, ) +__BUILD_BLAST_CACHE(, inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, ) +__BUILD_BLAST_CACHE(, inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, ) +__BUILD_BLAST_CACHE(, inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, ) +__BUILD_BLAST_CACHE(, inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, ) #define __BUILD_BLAST_USER_CACHE(pfx, desc, indexop, hitop, lsize) \ static inline void blast_##pfx##cache##lsize##_user_page(unsigned long page) \ @@ -617,7 +748,7 @@ __BUILD_BLAST_USER_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, __BUILD_BLAST_USER_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) /* build blast_xxx_range, protected_blast_xxx_range */ -#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra) \ +#define __BUILD_BLAST_CACHE_RANGE(fn_pfx, pfx, desc, hitop, prot, extra) \ static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, \ unsigned long end) \ { \ @@ -626,7 +757,7 @@ static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, unsigned long aend = (end - 1) & ~(lsize - 1); \ \ while (1) { \ - prot##cache_op(hitop, addr); \ + prot##cache_op##fn_pfx(hitop, addr); \ if (addr == aend) \ break; \ addr += lsize; \ @@ -635,8 +766,8 @@ static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, #ifndef CONFIG_EVA -__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, ) -__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, ) +__BUILD_BLAST_CACHE_RANGE(_d, d, dcache, Hit_Writeback_Inv_D, protected_, ) +__BUILD_BLAST_CACHE_RANGE(_i, i, icache, Hit_Invalidate_I, protected_, ) #else @@ -670,15 +801,15 @@ __BUILD_PROT_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D) __BUILD_PROT_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I) #endif -__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, ) -__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I_Loongson2, \ +__BUILD_BLAST_CACHE_RANGE(_s, s, scache, Hit_Writeback_Inv_SD, protected_, ) +__BUILD_BLAST_CACHE_RANGE(_i, i, icache, Hit_Invalidate_I_Loongson2, \ protected_, loongson2_) -__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , ) -__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, , ) -__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , ) +__BUILD_BLAST_CACHE_RANGE(_d, d, dcache, Hit_Writeback_Inv_D, , ) +__BUILD_BLAST_CACHE_RANGE(_i, i, icache, Hit_Invalidate_I, , ) +__BUILD_BLAST_CACHE_RANGE(_s, s, scache, Hit_Writeback_Inv_SD, , ) /* blast_inv_dcache_range */ -__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , ) -__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , ) +__BUILD_BLAST_CACHE_RANGE(_d, inv_d, dcache, Hit_Invalidate_D, , ) +__BUILD_BLAST_CACHE_RANGE(_d, inv_s, scache, Hit_Invalidate_SD, , ) /* Currently, this is very specific to Loongson-3 */ #define __BUILD_BLAST_CACHE_NODE(pfx, desc, indexop, hitop, lsize) \ diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 4f2cecbec722..ae79a78f3002 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1557,14 +1557,14 @@ static int probe_scache(void) write_c0_taglo(0); write_c0_taghi(0); __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - cache_op(Index_Store_Tag_I, begin); - cache_op(Index_Store_Tag_D, begin); - cache_op(Index_Store_Tag_SD, begin); + cache_op_i(Index_Store_Tag_I, begin); + cache_op_d(Index_Store_Tag_D, begin); + cache_op_s(Index_Store_Tag_SD, begin); /* Now search for the wrap around point. */ pow2 = (128 * 1024); for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { - cache_op(Index_Load_Tag_SD, addr); + cache_op_s(Index_Load_Tag_SD, addr); __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ if (!read_c0_taglo()) break; From patchwork Sun Sep 1 15:43:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125397 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C03714E5 for ; Sun, 1 Sep 2019 15:51:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5436820828 for ; Sun, 1 Sep 2019 15:51:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728496AbfIAPv6 (ORCPT ); Sun, 1 Sep 2019 11:51:58 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56978 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726260AbfIAPv5 (ORCPT ); Sun, 1 Sep 2019 11:51:57 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 6B99B404FF for ; Sun, 1 Sep 2019 17:43:06 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6CLKjmgsfE7T for ; Sun, 1 Sep 2019 17:43:05 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 751EB403CF for ; Sun, 1 Sep 2019 17:43:05 +0200 (CEST) Date: Sun, 1 Sep 2019 17:43:05 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 020/120] MIPS: R5900: Define CP0.Config register fields Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The following CP0.Config fields are specific to the R5900[1]: Field | Bit | Type | Description ------+-----+------+----------------------------- DIE | 18 | RW | Enable double issue ICE | 17 | RW | Enable the instruction cache DCE | 16 | RW | Enable the data cache BE | 15 | RO | Enable big-endian NBE | 13 | RW | Enable nonblocking load BPE | 12 | RW | Enable branch prediction ------+-----+------+----------------------------- References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. 4-23, https://wiki.qemu.org/File:C790.pdf Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- arch/mips/include/asm/mipsregs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index ec22406c800f..a3b3ee011539 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -511,6 +511,14 @@ #define R5K_CONF_SE (_ULCAST_(1) << 12) #define R5K_CONF_SS (_ULCAST_(3) << 20) +/* Bits specific to the R5900. */ +#define R5900_CONF_BPE (_ULCAST_(1) << 12) /* Enable branch prediction. */ +#define R5900_CONF_NBE (_ULCAST_(1) << 13) /* Enable non-blocking load. */ +#define R5900_CONF_BE (_ULCAST_(1) << 15) /* Enable big-endian (read-only). */ +#define R5900_CONF_DCE (_ULCAST_(1) << 16) /* Enable the data cache. */ +#define R5900_CONF_ICE (_ULCAST_(1) << 17) /* Enable the instruction cache. */ +#define R5900_CONF_DIE (_ULCAST_(1) << 18) /* Enable double issue. */ + /* Bits specific to the RM7000. */ #define RM7K_CONF_SE (_ULCAST_(1) << 3) #define RM7K_CONF_TE (_ULCAST_(1) << 12) From patchwork Sun Sep 1 15:43:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125395 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B1DE112C for ; Sun, 1 Sep 2019 15:51:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 303C620828 for ; Sun, 1 Sep 2019 15:51:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728687AbfIAPv6 (ORCPT ); Sun, 1 Sep 2019 11:51:58 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56976 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAPv5 (ORCPT ); Sun, 1 Sep 2019 11:51:57 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 9ABD240835 for ; Sun, 1 Sep 2019 17:43:18 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WDPM5NQnHydy for ; Sun, 1 Sep 2019 17:43:17 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id DC6A1405B8 for ; Sun, 1 Sep 2019 17:43:17 +0200 (CEST) Date: Sun, 1 Sep 2019 17:43:17 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 021/120] MIPS: R5900: Workaround for CACHE instruction near branch delay slot Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- The Linux 2.6 port to the PlayStation 2 has this remark. I don't know where it comes from. --- arch/mips/kernel/traps.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9c98475c7dc6..647a1990163a 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1967,6 +1967,17 @@ void __init *set_except_vector(int n, void *addr) uasm_i_jr(&buf, k0); uasm_i_nop(&buf); } +#ifdef CONFIG_CPU_R5900 + /* + * Data that could be interpreted as cache instructions + * is not allowed after the jump. + */ + uasm_i_nop(&buf); + uasm_i_nop(&buf); + uasm_i_nop(&buf); + uasm_i_nop(&buf); + uasm_i_nop(&buf); +#endif local_flush_icache_range(ebase + 0x200, (unsigned long)buf); } return (void *)old_handler; From patchwork Sun Sep 1 15:46:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125327 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 832541395 for ; Sun, 1 Sep 2019 15:46:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6B83A233A2 for ; Sun, 1 Sep 2019 15:46:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728934AbfIAPqW (ORCPT ); Sun, 1 Sep 2019 11:46:22 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56560 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728621AbfIAPqV (ORCPT ); Sun, 1 Sep 2019 11:46:21 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 793DB40F37; Sun, 1 Sep 2019 17:46:19 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id LAhCrnRSKkBy; Sun, 1 Sep 2019 17:46:18 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 8775E40C35; Sun, 1 Sep 2019 17:46:18 +0200 (CEST) Date: Sun, 1 Sep 2019 17:46:18 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 022/120] MIPS: R5900: Support 64-bit inq() and outq() macros in 32-bit kernels Message-ID: <7ea8b1211bceb8193154b51ad4241e7c0b86547d.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org PlayStation 2 hardware such as the Graphics Synthesizer requires 64-bit register reads and writes[1], also in 32-bit kernels. Interrupts must be disabled when manipulating 64-bit registers unless the kernel saves and restores 64-bit registers in the interrupt and context switch handlers. References: [1] "EE User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 26: GS privileged registers must be accessed using LD/SD instructions. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/io.h | 54 +++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 97a280640daf..f7115472f530 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -420,10 +420,32 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \ \ __val = pfx##ioswab##bwlq(__addr, val); \ \ - /* Really, we want this to be atomic */ \ - BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ + if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) { \ + *__addr = __val; \ + } else if (cpu_has_64bits) { \ + unsigned long __flags; \ + type __tmp; \ \ - *__addr = __val; \ + /* Manipulating 64-bit registers in a 32-bit kernel */ \ + /* requires disabling interrupts, since only 32-bit */ \ + /* registers are saved/restored by interrupts. */ \ + local_irq_save(__flags); \ + __asm__ __volatile__( \ + ".set push" "\t\t# __writeq""\n\t" \ + ".set mips3" "\n\t" \ + "dsll32 %L0, %L0, 0" "\n\t" \ + "dsrl32 %L0, %L0, 0" "\n\t" \ + "dsll32 %M0, %M0, 0" "\n\t" \ + "or %L0, %L0, %M0" "\n\t" \ + "sd %L0, %2" "\n\t" \ + "sll %L0, %L0, 0" "\n\t" \ + "sll %M0, %M0, 0" "\n\t" \ + ".set pop" "\n" \ + : "=r" (__tmp) \ + : "0" (__val), "m" (*__addr)); \ + local_irq_restore(__flags); \ + } else \ + BUG(); \ } \ \ static inline type pfx##in##bwlq##p(unsigned long port) \ @@ -433,12 +455,30 @@ static inline type pfx##in##bwlq##p(unsigned long port) \ \ __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \ \ - BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ - \ if (barrier) \ iobarrier_rw(); \ \ - __val = *__addr; \ + if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) { \ + __val = *__addr; \ + } else if (cpu_has_64bits) { \ + unsigned long __flags; \ + \ + /* Manipulating 64-bit registers in a 32-bit kernel */ \ + /* requires disabling interrupts, since only 32-bit */ \ + /* registers are saved/restored by interrupts. */ \ + local_irq_save(__flags); \ + __asm__ __volatile__( \ + ".set push" "\t\t# __outq" "\n\t" \ + ".set mips3" "\n\t" \ + "ld %L0, %1" "\n\t" \ + "dsra32 %M0, %L0, 0" "\n\t" \ + "sll %L0, %L0, 0" "\n\t" \ + ".set pop" "\n" \ + : "=r" (__val) \ + : "m" (*__addr)); \ + local_irq_restore(__flags); \ + } else \ + BUG(); \ \ /* prevent prefetching of coherent DMA data prematurely */ \ if (!relax) \ @@ -478,7 +518,7 @@ __BUILD_MEMORY_PFX(__mem_, q, u64, 0) BUILDIO_IOPORT(b, u8) BUILDIO_IOPORT(w, u16) BUILDIO_IOPORT(l, u32) -#ifdef CONFIG_64BIT +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_R5900) BUILDIO_IOPORT(q, u64) #endif From patchwork Sun Sep 1 15:46:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125329 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 560A517EF for ; Sun, 1 Sep 2019 15:46:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3DC3F233A2 for ; Sun, 1 Sep 2019 15:46:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728896AbfIAPqo (ORCPT ); Sun, 1 Sep 2019 11:46:44 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56588 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728621AbfIAPqo (ORCPT ); Sun, 1 Sep 2019 11:46:44 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id A180240F37 for ; Sun, 1 Sep 2019 17:46:42 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KKHMlAwQWNv0 for ; Sun, 1 Sep 2019 17:46:41 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id A0F8240C35 for ; Sun, 1 Sep 2019 17:46:41 +0200 (CEST) Date: Sun, 1 Sep 2019 17:46:41 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 023/120] MIPS: R5900: Add MFSA and MTSA instructions for the special SA register Message-ID: <484e5c712f0ff87fcd525b3fc18f1483389844fa.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The shift amount (SA) register is a 64-bit special register storing the funnel shift amount. The SA is encoded an implementation-defined manner. It is therefore not meaningful for software to operate on this value. Use the MTSAB and MTSAH instructions to set a new funnel shift amount. The SA is used by the QFSRV (quadword funnel shift right variable) 256-bit multimedia instruction. MFSA copies the SA register to a 64-bit GPR[1]. The sole purpose of this instruction is to permit the shift amount to be saved during a context switch. MTSA copies a 64-bit GPR rs to the SA register[2]. Note that rs must contain a value that was originally generated by MFSA. If some other user-generated value is in rs, the shifting action performed by the funnel shifter is not defined; that is, MTSA cannot be used to by a program to set a new funnel shift amount. The sole purpose of this instruction is to permit the shift amount to be restored during a context switch. Restrictions: The three instructions statically preceding a MTSA instruction must not read or write the SA register; that is, they cannot be either of the instructions MFSA, QFSRV, or MTSAx. References: [1] "TX System RISC TX79 Core Architecture" manual, revision 2.0, Toshiba Corporation, p. B-17, https://wiki.qemu.org/File:C790.pdf [2] Ibid. p. B-20. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mipsregs.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index a3b3ee011539..d8c1ffac2824 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -2594,6 +2594,28 @@ do { \ #else +#ifdef CONFIG_CPU_R5900 +#define mfsa() \ +({ \ + unsigned long __treg; /* FIXME: __u64? */ \ + \ + __asm__ __volatile__( \ + " mfsa %0\n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mtsa(x) \ +do { \ + unsigned long __treg = (x);/* FIXME: __u64? */ \ + \ + __asm__ __volatile__( \ + " mtsa %0\n" \ + : \ + : "r" (__treg)); \ +} while (0) +#endif + #define rddsp(mask) \ ({ \ unsigned int __res; \ From patchwork Sun Sep 1 15:46:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125333 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1BF081890 for ; Sun, 1 Sep 2019 15:46:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 03D12233A2 for ; Sun, 1 Sep 2019 15:46:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728980AbfIAPq5 (ORCPT ); Sun, 1 Sep 2019 11:46:57 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56630 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728900AbfIAPq5 (ORCPT ); Sun, 1 Sep 2019 11:46:57 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 8D67240F37 for ; Sun, 1 Sep 2019 17:46:55 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Kho4OY3DZPGg for ; Sun, 1 Sep 2019 17:46:54 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id E209740C35 for ; Sun, 1 Sep 2019 17:46:54 +0200 (CEST) Date: Sun, 1 Sep 2019 17:46:54 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 024/120] MIPS: PS2: Define PlayStation 2 I/O port, ROM and RAM address spaces Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 17 +++++++++++++++++ arch/mips/ps2/Makefile | 1 + arch/mips/ps2/memory.c | 27 +++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/rom.h create mode 100644 arch/mips/ps2/Makefile create mode 100644 arch/mips/ps2/memory.c diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h new file mode 100644 index 000000000000..6760be183696 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 read-only memory (ROM) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_ROM_H +#define __ASM_MACH_PS2_ROM_H + +#define ROM0_BASE 0x1fc00000 /* ROM0 base address (boot) */ +#define ROM0_SIZE 0x400000 /* ROM0 maximum size */ + +#define ROM1_BASE 0x1e000000 /* ROM1 base address (DVD) */ +#define ROM1_SIZE 0x100000 /* ROM1 maximum size */ + +#endif /* __ASM_MACH_PS2_ROM_H */ diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile new file mode 100644 index 000000000000..24d537d2fb9f --- /dev/null +++ b/arch/mips/ps2/Makefile @@ -0,0 +1 @@ +obj-y += memory.o diff --git a/arch/mips/ps2/memory.c b/arch/mips/ps2/memory.c new file mode 100644 index 000000000000..66ca37f38330 --- /dev/null +++ b/arch/mips/ps2/memory.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 memory + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include + +#include + +void __init plat_mem_setup(void) +{ + ioport_resource.start = 0x10000000; + ioport_resource.end = 0x1fffffff; + + iomem_resource.start = 0x00000000; + iomem_resource.end = KSEG2 - 1; + + add_memory_region(0x00000000, 0x02000000, BOOT_MEM_RAM); + add_memory_region(ROM0_BASE, ROM0_SIZE, BOOT_MEM_ROM_DATA); + add_memory_region(ROM1_BASE, ROM1_SIZE, BOOT_MEM_ROM_DATA); + + set_io_port_base(CKSEG1); /* KSEG1 is uncached */ +} From patchwork Sun Sep 1 15:47:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125343 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CEBC918B7 for ; Sun, 1 Sep 2019 15:47:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B6CE423429 for ; Sun, 1 Sep 2019 15:47:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729160AbfIAPrO (ORCPT ); Sun, 1 Sep 2019 11:47:14 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57400 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729152AbfIAPrO (ORCPT ); Sun, 1 Sep 2019 11:47:14 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id E492040484 for ; Sun, 1 Sep 2019 17:47:12 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4swwCxfaarwX for ; Sun, 1 Sep 2019 17:47:12 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 39BCF4047D for ; Sun, 1 Sep 2019 17:47:12 +0200 (CEST) Date: Sun, 1 Sep 2019 17:47:12 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 025/120] MIPS: PS2: Define interrupt controller, DMA and timer IRQs Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The interrupt controller (INTC) arbitrates 15 interrupt requests from multiple processors and asserts INT0[1]. The DMA controller (DMAC) asserts INT1[2]. References: [1] "EE User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 27-31. [2] Ibid. p. 55. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/irq.h | 74 ++++++++++++++++++++++++++++ arch/mips/ps2/Makefile | 1 + arch/mips/ps2/irq.c | 35 +++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/irq.h create mode 100644 arch/mips/ps2/irq.c diff --git a/arch/mips/include/asm/mach-ps2/irq.h b/arch/mips/include/asm/mach-ps2/irq.h new file mode 100644 index 000000000000..d6f72a7e37a3 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/irq.h @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 IRQs + * + * Copyright (C) 2000-2002 Sony Computer Entertainment Inc. + * Copyright (C) 2010-2013 Jürgen Urban + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_IRQ_H +#define __ASM_MACH_PS2_IRQ_H + +#define INTC_STAT 0x1000f000 /* Flags are cleared by writing 1 */ +#define INTC_MASK 0x1000f010 /* Bits are reversed by writing 1 */ + +#define NR_IRQS 56 + +/* + * The interrupt controller (INTC) arbitrates interrupts from peripheral + * devices, except for the DMAC. + */ +#define IRQ_INTC 0 +#define IRQ_INTC_GS 0 /* Graphics Synthesizer */ +#define IRQ_INTC_SBUS 1 /* Bus connecting the Emotion Engine to the + I/O processor (IOP) via the sub-system + interface (SIF) */ +#define IRQ_INTC_VB_ON 2 /* Vertical blank start */ +#define IRQ_INTC_VB_OFF 3 /* Vertical blank end */ +#define IRQ_INTC_VIF0 4 /* VPU0 interface packet expansion engine */ +#define IRQ_INTC_VIF1 5 /* VPU1 interface packet expansion engine */ +#define IRQ_INTC_VU0 6 /* Vector core operation unit 0 */ +#define IRQ_INTC_VU1 7 /* Vector core operation unit 1 */ +#define IRQ_INTC_IPU 8 /* Image processor unit (MPEG 2 video etc.) */ +#define IRQ_INTC_TIMER0 9 /* Independent screen timer 0 */ +#define IRQ_INTC_TIMER1 10 /* Independent screen timer 1 */ +#define IRQ_INTC_TIMER2 11 /* Independent screen timer 2 */ +#define IRQ_INTC_TIMER3 12 /* Independent screen timer 3 */ +#define IRQ_INTC_SFIFO 13 /* Error detected during SFIFO transfers */ +#define IRQ_INTC_VU0WD 14 /* VU0 watch dog for RUN (sends force break) */ +#define IRQ_INTC_PGPU 15 + +/* DMA controller */ +#define IRQ_DMAC 16 +#define IRQ_DMAC_VIF0 16 /* Ch0 VPU0 interface (VIF0) */ +#define IRQ_DMAC_VIF1 17 /* Ch1 VPU1 interface (VIF1) */ +#define IRQ_DMAC_GIF 18 /* Ch2 Graphics Synthesizer interface (GIF) */ +#define IRQ_DMAC_FIPU 19 /* Ch3 from image processor unit (IPU) */ +#define IRQ_DMAC_TIPU 20 /* Ch4 to image processor unit (IPU) */ +#define IRQ_DMAC_SIF0 21 /* Ch5 sub-system interface 0 (SIF0) */ +#define IRQ_DMAC_SIF1 22 /* Ch6 sub-system interface 1 (SIF1) */ +#define IRQ_DMAC_SIF2 23 /* Ch7 Sub-system interface 2 (SIF2) */ +#define IRQ_DMAC_FSPR 24 /* Ch8 from scratch-pad RAM (SPR) */ +#define IRQ_DMAC_TSPR 25 /* Ch9 to scratch-pad RAM (SPR) */ +#define IRQ_DMAC_S 29 /* DMA stall */ +#define IRQ_DMAC_ME 30 /* MFIFO empty */ +#define IRQ_DMAC_BE 31 /* Bus error */ + +/* Graphics Synthesizer */ +#define IRQ_GS 32 +#define IRQ_GS_SIGNAL 32 /* GS signal event control */ +#define IRQ_GS_FINISH 33 /* GS finish event control */ +#define IRQ_GS_HSYNC 34 /* GS horizontal synch interrupt control */ +#define IRQ_GS_VSYNC 35 /* GS vertical synch interrupt control */ +#define IRQ_GS_EDW 36 /* GS rectangular area write termination */ +#define IRQ_GS_EXHSYNC 37 +#define IRQ_GS_EXVSYNC 38 + +/* MIPS IRQs */ +#define MIPS_CPU_IRQ_BASE 48 +#define IRQ_C0_INTC 50 +#define IRQ_C0_DMAC 51 +#define IRQ_C0_IRQ7 55 + +#endif /* __ASM_MACH_PS2_IRQ_H */ diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index 24d537d2fb9f..d5d089c61381 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -1 +1,2 @@ +obj-y += irq.o obj-y += memory.o diff --git a/arch/mips/ps2/irq.c b/arch/mips/ps2/irq.c new file mode 100644 index 000000000000..09047e128ce8 --- /dev/null +++ b/arch/mips/ps2/irq.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 IRQs + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include + +#include +#include + +#include + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); +} + +asmlinkage void plat_irq_dispatch(void) +{ + const unsigned int pending = read_c0_status() & read_c0_cause(); + + if (!(pending & (CAUSEF_IP2 | CAUSEF_IP3 | CAUSEF_IP7))) + return spurious_interrupt(); + + if (pending & CAUSEF_IP2) + do_IRQ(IRQ_C0_INTC); /* INTC interrupt */ + if (pending & CAUSEF_IP3) + do_IRQ(IRQ_C0_DMAC); /* DMAC interrupt */ + if (pending & CAUSEF_IP7) + do_IRQ(IRQ_C0_IRQ7); /* Timer interrupt */ +} From patchwork Sun Sep 1 15:47:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125349 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EA8E9112C for ; Sun, 1 Sep 2019 15:47:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D2B8921897 for ; Sun, 1 Sep 2019 15:47:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729173AbfIAPr1 (ORCPT ); Sun, 1 Sep 2019 11:47:27 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57456 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729159AbfIAPr1 (ORCPT ); Sun, 1 Sep 2019 11:47:27 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 3513340484 for ; Sun, 1 Sep 2019 17:47:25 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YLwueEjwB2Ts for ; Sun, 1 Sep 2019 17:47:24 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 5CF484047D for ; Sun, 1 Sep 2019 17:47:24 +0200 (CEST) Date: Sun, 1 Sep 2019 17:47:24 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 026/120] MIPS: PS2: Interrupt controller (INTC) IRQ support Message-ID: <4396db79b04c1eb3e24e051d1a406d25506875a3.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- I'm not sure edges or HARDIRQS_SW_RESEND etc. are needed. --- arch/mips/include/asm/mach-ps2/irq.h | 2 + arch/mips/ps2/Makefile | 1 + arch/mips/ps2/intc-irq.c | 112 +++++++++++++++++++++++++++ arch/mips/ps2/irq.c | 2 + 4 files changed, 117 insertions(+) create mode 100644 arch/mips/ps2/intc-irq.c diff --git a/arch/mips/include/asm/mach-ps2/irq.h b/arch/mips/include/asm/mach-ps2/irq.h index d6f72a7e37a3..071c8139dabe 100644 --- a/arch/mips/include/asm/mach-ps2/irq.h +++ b/arch/mips/include/asm/mach-ps2/irq.h @@ -71,4 +71,6 @@ #define IRQ_C0_DMAC 51 #define IRQ_C0_IRQ7 55 +int __init intc_irq_init(void); + #endif /* __ASM_MACH_PS2_IRQ_H */ diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index d5d089c61381..ccdfb80c9f03 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -1,2 +1,3 @@ +obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o diff --git a/arch/mips/ps2/intc-irq.c b/arch/mips/ps2/intc-irq.c new file mode 100644 index 000000000000..36cdc3dd31ca --- /dev/null +++ b/arch/mips/ps2/intc-irq.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Interrupt controller (INTC) IRQs + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +static void intc_reverse_mask(struct irq_data *data) +{ + outl(BIT(data->irq - IRQ_INTC), INTC_MASK); +} + +static void intc_mask_ack(struct irq_data *data) +{ + const unsigned int bit = BIT(data->irq - IRQ_INTC); + + outl(bit, INTC_MASK); + outl(bit, INTC_STAT); +} + +#define INTC_IRQ_TYPE(irq_, name_) \ + { \ + .irq = irq_, \ + .irq_chip = { \ + .name = name_, \ + .irq_unmask = intc_reverse_mask, \ + .irq_mask = intc_reverse_mask, \ + .irq_mask_ack = intc_mask_ack, \ + } \ + } + +static struct { + unsigned int irq; + struct irq_chip irq_chip; +} intc_irqs[] = { + INTC_IRQ_TYPE(IRQ_INTC_GS, "INTC GS"), + INTC_IRQ_TYPE(IRQ_INTC_SBUS, "INTC SBUS"), + INTC_IRQ_TYPE(IRQ_INTC_VB_ON, "INTC VB on"), + INTC_IRQ_TYPE(IRQ_INTC_VB_OFF, "INTC VB off"), + INTC_IRQ_TYPE(IRQ_INTC_VIF0, "INTC VIF0"), + INTC_IRQ_TYPE(IRQ_INTC_VIF1, "INTC VIF1"), + INTC_IRQ_TYPE(IRQ_INTC_VU0, "INTC VU0"), + INTC_IRQ_TYPE(IRQ_INTC_VU1, "INTC VU1"), + INTC_IRQ_TYPE(IRQ_INTC_IPU, "INTC IPU"), + INTC_IRQ_TYPE(IRQ_INTC_TIMER0, "INTC timer0"), + INTC_IRQ_TYPE(IRQ_INTC_TIMER1, "INTC timer1"), + INTC_IRQ_TYPE(IRQ_INTC_TIMER2, "INTC timer2"), + INTC_IRQ_TYPE(IRQ_INTC_TIMER3, "INTC timer3"), + INTC_IRQ_TYPE(IRQ_INTC_SFIFO, "INTC SFIFO"), + INTC_IRQ_TYPE(IRQ_INTC_VU0WD, "INTC VU0WD"), + INTC_IRQ_TYPE(IRQ_INTC_PGPU, "INTC PGPU"), +}; + +static irqreturn_t intc_cascade(int irq, void *data) +{ + unsigned int pending, irq_intc; + irqreturn_t status = IRQ_NONE; + + for (pending = inl(INTC_STAT); pending; pending &= ~BIT(irq_intc)) { + irq_intc = __fls(pending); + + if (generic_handle_irq(irq_intc + IRQ_INTC) < 0) + spurious_interrupt(); + else + status = IRQ_HANDLED; + } + + return status; +} + +static struct irqaction cascade_intc_irqaction = { + .name = "INTC cascade", + .handler = intc_cascade, +}; + +int __init intc_irq_init(void) +{ + size_t i; + int err; + + /* Clear mask and status registers */ + outl(inl(INTC_MASK), INTC_MASK); + outl(inl(INTC_STAT), INTC_STAT); + + for (i = 0; i < ARRAY_SIZE(intc_irqs); i++) + irq_set_chip_and_handler(intc_irqs[i].irq, + &intc_irqs[i].irq_chip, handle_level_irq); + + /* FIXME: Is HARDIRQS_SW_RESEND needed? Are these edge types needed? */ + irq_set_irq_type(IRQ_INTC_GS, IRQ_TYPE_EDGE_FALLING); + irq_set_irq_type(IRQ_INTC_SBUS, IRQ_TYPE_EDGE_FALLING); + irq_set_irq_type(IRQ_INTC_VB_ON, IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(IRQ_INTC_VB_OFF, IRQ_TYPE_EDGE_FALLING); + + err = setup_irq(IRQ_C0_INTC, &cascade_intc_irqaction); + if (err) + pr_err("irq: Failed to setup INTC IRQs (err = %d)\n", err); + + return err; +} diff --git a/arch/mips/ps2/irq.c b/arch/mips/ps2/irq.c index 09047e128ce8..935171a1e3bd 100644 --- a/arch/mips/ps2/irq.c +++ b/arch/mips/ps2/irq.c @@ -17,6 +17,8 @@ void __init arch_init_irq(void) { mips_cpu_irq_init(); + + intc_irq_init(); } asmlinkage void plat_irq_dispatch(void) From patchwork Sun Sep 1 15:47:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125351 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 83AF7112C for ; Sun, 1 Sep 2019 15:47:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 61BCF233A2 for ; Sun, 1 Sep 2019 15:47:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729179AbfIAPrl (ORCPT ); Sun, 1 Sep 2019 11:47:41 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56658 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729175AbfIAPrl (ORCPT ); Sun, 1 Sep 2019 11:47:41 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 9571C3F73E for ; Sun, 1 Sep 2019 17:47:38 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fOXa-0EfqYe5 for ; Sun, 1 Sep 2019 17:47:37 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id BB6693F708 for ; Sun, 1 Sep 2019 17:47:37 +0200 (CEST) Date: Sun, 1 Sep 2019 17:47:37 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 027/120] MIPS: PS2: DMAC: Define DMA controller registers Message-ID: <896e5738996b0cf2a7b8670c68610b5c45b31877.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The DMA controller handles transfers between main memory and peripheral devices or the scratch-pad RAM (SPR)[1]. References: [1] "EE User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 23-24, 41-80. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/dmac.h | 189 ++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/dmac.h diff --git a/arch/mips/include/asm/mach-ps2/dmac.h b/arch/mips/include/asm/mach-ps2/dmac.h new file mode 100644 index 000000000000..30a0f72eeab3 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/dmac.h @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 DMA controller (DMAC) + * + * Copyright (C) 2019 Fredrik Noring + */ + +/** + * DOC: + * + * The DMA controller handles transfers between main memory and peripheral + * devices or the scratch-pad RAM (SPR). + * + * The DMAC arbitrates the main bus at the same time, and supports chain + * mode which switches transfer addresses according to DMA tags attached to + * the transfer. The stall control synchronises two-channel transfers with + * priority control. + * + * Data is transferred in 128-bit words that must be aligned. Bus snooping + * is not performed. + */ + +#ifndef __ASM_MACH_PS2_DMAC_H +#define __ASM_MACH_PS2_DMAC_H + +#include + +/* Channel 0: Vector core operation unit 0 (VU0) interface (VIF0) */ +#define DMAC_VIF0_CHCR 0x10008000 /* VIF0 channel control */ +#define DMAC_VIF0_MADR 0x10008010 /* VIF0 memory address */ +#define DMAC_VIF0_QWC 0x10008020 /* VIF0 quadword count */ +#define DMAC_VIF0_TADR 0x10008030 /* VIF0 tag address */ +#define DMAC_VIF0_ASR0 0x10008040 /* VIF0 address stack 0 */ +#define DMAC_VIF0_ASR1 0x10008050 /* VIF0 address stack 1 */ + +/* Channel 1: Vector core operation unit 1 (VU1) interface (VIF1) */ +#define DMAC_VIF1_CHCR 0x10009000 /* VIF1 channel control */ +#define DMAC_VIF1_MADR 0x10009010 /* VIF1 memory address */ +#define DMAC_VIF1_QWC 0x10009020 /* VIF1 quadword count */ +#define DMAC_VIF1_TADR 0x10009030 /* VIF1 tag address */ +#define DMAC_VIF1_ASR0 0x10009040 /* VIF1 address stack 0 */ +#define DMAC_VIF1_ASR1 0x10009050 /* VIF1 address stack 1 */ + +/* Channel 2: Graphics Synthesizer interface (GIF) */ +#define DMAC_GIF_CHCR 0x1000a000 /* GIF channel control */ +#define DMAC_GIF_MADR 0x1000a010 /* GIF memory address */ +#define DMAC_GIF_QWC 0x1000a020 /* GIF quadword count */ +#define DMAC_GIF_TADR 0x1000a030 /* GIF tag address */ +#define DMAC_GIF_ASR0 0x1000a040 /* GIF address stack 0 */ +#define DMAC_GIF_ASR1 0x1000a050 /* GIF address stack 1 */ + +/* Channel 3: From image processor unit (IPU) */ +#define DMAC_FIPU_CHCR 0x1000b000 /* From IPU channel control */ +#define DMAC_FIPU_MADR 0x1000b010 /* From IPU memory address */ +#define DMAC_FIPU_QWC 0x1000b020 /* From IPU quadword count */ + +/* Channel 4: To image processor unit (IPU) */ +#define DMAC_TIPU_CHCR 0x1000b400 /* To IPU channel control */ +#define DMAC_TIPU_MADR 0x1000b410 /* To IPU memory address */ +#define DMAC_TIPU_QWC 0x1000b420 /* To IPU quadword count */ +#define DMAC_TIPU_TADR 0x1000b430 /* To IPU tag address */ + +/* Channel 5: Sub-system interface 0 (SIF0) */ +#define DMAC_SIF0_CHCR 0x1000c000 /* SIF0 channel control */ +#define DMAC_SIF0_MADR 0x1000c010 /* SIF0 memory address */ +#define DMAC_SIF0_QWC 0x1000c020 /* SIF0 quadword count */ + +/* Channel 6: Sub-system interface 1 (SIF1) */ +#define DMAC_SIF1_CHCR 0x1000c400 /* SIF1 channel control */ +#define DMAC_SIF1_MADR 0x1000c410 /* SIF1 memory address */ +#define DMAC_SIF1_QWC 0x1000c420 /* SIF1 quadword count */ +#define DMAC_SIF1_TADR 0x1000c430 /* SIF1 tag address */ + +/* Channel 7: Sub-system interface 2 (SIF2) */ +#define DMAC_SIF2_CHCR 0x1000c800 /* SIF2 channel control */ +#define DMAC_SIF2_MADR 0x1000c810 /* SIF2 memory address */ +#define DMAC_SIF2_QWC 0x1000c820 /* SIF2 quadword count */ + +/* Channel 8: From scratch-pad RAM (SPR) */ +#define DMAC_FSPR_CHCR 0x1000d000 /* From SPR channel control */ +#define DMAC_FSPR_MADR 0x1000d010 /* From SPR memory address */ +#define DMAC_FSPR_QWC 0x1000d020 /* From SPR quadword count */ +#define DMAC_FSPR_SADR 0x1000d080 /* From SPR address */ + +/* Channel 9: To scratch-pad RAM (SPR) */ +#define DMAC_TSPR_CHCR 0x1000d400 /* To SPR channel control */ +#define DMAC_TSPR_MADR 0x1000d410 /* To SPR memory address */ +#define DMAC_TSPR_QWC 0x1000d420 /* To SPR quadword count */ +#define DMAC_TSPR_TADR 0x1000d430 /* To SPR tag address */ +#define DMAC_TSPR_SADR 0x1000d480 /* To SPR address */ + +#define DMAC_CHCR_DIR_TOMEM (0 << 0) /* Direction to memory */ +#define DMAC_CHCR_DIR_FROMMEM (1 << 0) /* Direction from memory */ +#define DMAC_CHCR_MOD_NORMAL (0 << 2) /* Mode normal */ +#define DMAC_CHCR_MOD_CHAIN (1 << 2) /* Mode chain */ +#define DMAC_CHCR_MOD_ILEAVE (2 << 2) /* Mode interleave */ +#define DMAC_CHCR_ASP_NONE (0 << 4) /* 0 address stack pointer */ +#define DMAC_CHCR_ASP_1ADDR (1 << 4) /* 1 address stack pointer */ +#define DMAC_CHCR_ASP_2ADDR (2 << 4) /* 2 address stack pointer */ +#define DMAC_CHCR_TTE_OFF (0 << 6) /* Tag transfer enable off */ +#define DMAC_CHCR_TTE_ON (1 << 6) /* Tag transfer enable on */ +#define DMAC_CHCR_TIE_OFF (0 << 7) /* Tag interrupt enable off */ +#define DMAC_CHCR_TIE_ON (1 << 7) /* Tag interrupt enable on */ +#define DMAC_CHCR_STR_STOP (0 << 8) /* Stop DMA */ +#define DMAC_CHCR_STR_START (1 << 8) /* Start DMA */ + +#define DMAC_CHCR_STOP DMAC_CHCR_STR_STOP +#define DMAC_CHCR_BUSY DMAC_CHCR_STR_START +#define DMAC_CHCR_SENDN (DMAC_CHCR_DIR_FROMMEM | \ + DMAC_CHCR_MOD_NORMAL | \ + DMAC_CHCR_ASP_NONE | \ + DMAC_CHCR_TTE_OFF | \ + DMAC_CHCR_TIE_OFF | \ + DMAC_CHCR_STR_START) +#define DMAC_CHCR_SENDN_TIE (DMAC_CHCR_DIR_FROMMEM | \ + DMAC_CHCR_MOD_NORMAL | \ + DMAC_CHCR_ASP_NONE | \ + DMAC_CHCR_TTE_OFF | \ + DMAC_CHCR_TIE_ON | \ + DMAC_CHCR_STR_START) +#define DMAC_CHCR_SENDC (DMAC_CHCR_DIR_FROMMEM | \ + DMAC_CHCR_MOD_CHAIN | \ + DMAC_CHCR_ASP_NONE | \ + DMAC_CHCR_TTE_OFF | \ + DMAC_CHCR_TIE_OFF | \ + DMAC_CHCR_STR_START) +#define DMAC_CHCR_SENDC_TTE (DMAC_CHCR_DIR_FROMMEM | \ + DMAC_CHCR_MOD_CHAIN | \ + DMAC_CHCR_ASP_NONE | \ + DMAC_CHCR_TTE_ON | \ + DMAC_CHCR_TIE_OFF | \ + DMAC_CHCR_STR_START) +#define DMAC_CHCR_RECVN (DMAC_CHCR_DIR_TOMEM | \ + DMAC_CHCR_MOD_NORMAL | \ + DMAC_CHCR_ASP_NONE | \ + DMAC_CHCR_TTE_OFF | \ + DMAC_CHCR_TIE_OFF | \ + DMAC_CHCR_STR_START) +#define DMAC_CHCR_RECVC_TIE (DMAC_CHCR_DIR_TOMEM | \ + DMAC_CHCR_MOD_CHAIN | \ + DMAC_CHCR_ASP_NONE | \ + DMAC_CHCR_TTE_OFF | \ + DMAC_CHCR_TIE_ON | \ + DMAC_CHCR_STR_START) + +#define DMAC_CTRL 0x1000e000 /* DMAC control */ +#define DMAC_STAT 0x1000e010 /* DMAC status */ +#define DMAC_PCR 0x1000e020 /* DMAC priority control */ +#define DMAC_SQWC 0x1000e030 /* DMAC skip quadword */ +#define DMAC_RBSR 0x1000e040 /* DMAC ring buffer size */ +#define DMAC_RBOR 0x1000e050 /* DMAC ring buffer offset */ +#define DMAC_STADR 0x1000e060 /* DMAC stall address */ + +/* + * The lower 16 bits are status bits and the upper 16 bits are mask bits. + * Status bit cleared by writing 1. Mask bits are reversed by writing 1. + */ +#define DMAC_STAT_MASK 0x1000e010 + +#define DMAC_STAT_VIF0S (1 << 0) /* Ch0 interrupt status VIF0 */ +#define DMAC_STAT_VIF1S (1 << 1) /* Ch1 interrupt status VIF1 */ +#define DMAC_STAT_GIFS (1 << 2) /* Ch2 interrupt status GIF */ +#define DMAC_STAT_FIPUS (1 << 3) /* Ch3 interrupt status from IPU */ +#define DMAC_STAT_TIPUS (1 << 4) /* Ch4 interrupt status to IPU */ +#define DMAC_STAT_SIF0S (1 << 5) /* Ch5 interrupt status SIF0 */ +#define DMAC_STAT_SIF1S (1 << 6) /* Ch6 interrupt status SIF1 */ +#define DMAC_STAT_SIF2S (1 << 7) /* Ch7 interrupt status SIF2 */ +#define DMAC_STAT_FSPRS (1 << 8) /* Ch8 interrupt status from SPR */ +#define DMAC_STAT_TSPRS (1 << 9) /* Ch9 interrupt status to SPR */ +#define DMAC_STAT_SIS (1 << 13) /* DMA stall interrupt status */ +#define DMAC_STAT_MEIS (1 << 14) /* MFIFO empty interrupt status */ +#define DMAC_STAT_BEIS (1 << 15) /* BUSERR interrupt status */ +#define DMAC_STAT_VIF0M (1 << 16) /* Ch0 interrupt mask VIF0 */ +#define DMAC_STAT_VIF1M (1 << 17) /* Ch1 interrupt mask VIF1 */ +#define DMAC_STAT_GIFM (1 << 18) /* Ch2 interrupt mask GIF */ +#define DMAC_STAT_FIPUM (1 << 19) /* Ch3 interrupt mask from IPU */ +#define DMAC_STAT_TIPUM (1 << 20) /* Ch4 interrupt mask to IPU */ +#define DMAC_STAT_SIF0M (1 << 21) /* Ch5 interrupt mask SIF0 */ +#define DMAC_STAT_SIF1M (1 << 22) /* Ch6 interrupt mask SIF1 */ +#define DMAC_STAT_SIF2M (1 << 23) /* Ch7 interrupt mask SIF2 */ +#define DMAC_STAT_FSPRM (1 << 24) /* Ch8 interrupt mask from SPR */ +#define DMAC_STAT_TSPRM (1 << 25) /* Ch9 interrupt mask to SPR */ +#define DMAC_STAT_SIM (1 << 29) /* DMA stall interrupt mask */ +#define DMAC_STAT_MEIM (1 << 30) /* MFIFO empty interrupt mask */ + +#define DMAC_ENABLER 0x1000f520 /* Acquisition of DMA suspend status */ +#define DMAC_ENABLEW 0x1000f590 /* DMA suspend control */ + +#endif /* __ASM_MACH_PS2_DMAC_H */ From patchwork Sun Sep 1 15:47:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125353 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C42071395 for ; Sun, 1 Sep 2019 15:47:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AC9C4233A2 for ; Sun, 1 Sep 2019 15:47:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729157AbfIAPrx (ORCPT ); Sun, 1 Sep 2019 11:47:53 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41480 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729151AbfIAPrx (ORCPT ); Sun, 1 Sep 2019 11:47:53 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 71A713F65F for ; Sun, 1 Sep 2019 17:47:51 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rrtjtLf0dTRh for ; Sun, 1 Sep 2019 17:47:50 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id C33A73F615 for ; Sun, 1 Sep 2019 17:47:50 +0200 (CEST) Date: Sun, 1 Sep 2019 17:47:50 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 028/120] MIPS: PS2: DMAC: Define tag structures Message-ID: <060f4aecc76fcbdb8a938241ec645bbb82862533.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The DMA tag is used in chain mode to control the destination and source memory addresses, transfer size, etc. There are two types of tag: source chain tag and destination chain tag[1]. References: [1] "EE User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 58-61. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/dmac.h | 65 +++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/dmac.h b/arch/mips/include/asm/mach-ps2/dmac.h index 30a0f72eeab3..fb4c52ad9ad5 100644 --- a/arch/mips/include/asm/mach-ps2/dmac.h +++ b/arch/mips/include/asm/mach-ps2/dmac.h @@ -186,4 +186,69 @@ #define DMAC_ENABLER 0x1000f520 /* Acquisition of DMA suspend status */ #define DMAC_ENABLEW 0x1000f590 /* DMA suspend control */ +enum dma_tag_reg { /* Data start address: Next tag address: */ + dma_tag_id_refe = 0, /* ADDR (none) */ + dma_tag_id_cnts = 0, /* ADDR (none) */ + dma_tag_id_cnt, /* next to tag next to transfer data */ + dma_tag_id_next, /* next to tag ADDR */ + dma_tag_id_ref, /* ADDR next to tag */ + dma_tag_id_refs, /* ADDR next to tag */ + dma_tag_id_call, /* next to tag ADDR */ + dma_tag_id_ret, /* next to tag Dn_ASR */ + dma_tag_id_end /* next to tag (none) */ +}; + +/** + * enum dma_tag_spr - memory or scratch-pad RAM + * @dma_tag_spr_memory: select memory + * @dma_tag_spr_scratchpad: select scratch-pad RAM + */ +enum dma_tag_spr { + dma_tag_spr_memory, + dma_tag_spr_scratchpad +}; + +/** + * struct dma_tag - DMA tag + * @qwc: 128-bit quadword count + * @pce: priority control enable + * @id: &enum dma_tag_reg tag identifier + * @irq: interrupt request + * @addr: address with lower 4 bits zero + * @spr: &enum dma_tag_spr memory or scratch-pad RAM + * + * The DMA tag must be aligned with 16 byte boundaries. + */ +struct dma_tag { + u64 qwc : 16; + u64 : 10; + u64 pce : 2; + u64 id : 3; + u64 irq : 1; + u64 addr : 31; + u64 spr : 1; + + u64 : 64; +} __attribute__((aligned(16))); + +/** + * struct iop_dma_tag - I/O processor (IOP) DMA tag + * @addr: IOP address + * @int_0: assert IOP interupt on completion + * @ert: FIXME + * @wc: 32-bit word count + * + * The IOP DMA tag must be aligned with 16 byte boundaries. + */ +struct iop_dma_tag { + u32 addr : 24; + u32 : 6; + u32 int_0 : 1; + u32 ert : 1; + + u32 wc; + + u64 : 64; +} __attribute__((aligned(16))); + #endif /* __ASM_MACH_PS2_DMAC_H */ From patchwork Sun Sep 1 15:48:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125357 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2D5A01395 for ; Sun, 1 Sep 2019 15:48:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 15DE920828 for ; Sun, 1 Sep 2019 15:48:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729167AbfIAPsI (ORCPT ); Sun, 1 Sep 2019 11:48:08 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41494 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729159AbfIAPsI (ORCPT ); Sun, 1 Sep 2019 11:48:08 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 502A93F65F for ; Sun, 1 Sep 2019 17:48:06 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id swQf4agJgyyI for ; Sun, 1 Sep 2019 17:48:05 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id AD44F3F615 for ; Sun, 1 Sep 2019 17:48:05 +0200 (CEST) Date: Sun, 1 Sep 2019 17:48:05 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 029/120] MIPS: PS2: DMAC: IRQ support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/irq.h | 1 + arch/mips/ps2/Makefile | 1 + arch/mips/ps2/dmac-irq.c | 102 +++++++++++++++++++++++++++ arch/mips/ps2/irq.c | 1 + 4 files changed, 105 insertions(+) create mode 100644 arch/mips/ps2/dmac-irq.c diff --git a/arch/mips/include/asm/mach-ps2/irq.h b/arch/mips/include/asm/mach-ps2/irq.h index 071c8139dabe..16c96aa7ca09 100644 --- a/arch/mips/include/asm/mach-ps2/irq.h +++ b/arch/mips/include/asm/mach-ps2/irq.h @@ -72,5 +72,6 @@ #define IRQ_C0_IRQ7 55 int __init intc_irq_init(void); +int __init dmac_irq_init(void); #endif /* __ASM_MACH_PS2_IRQ_H */ diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index ccdfb80c9f03..1e6406f42b3a 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -1,3 +1,4 @@ +obj-y += dmac-irq.o obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o diff --git a/arch/mips/ps2/dmac-irq.c b/arch/mips/ps2/dmac-irq.c new file mode 100644 index 000000000000..8bb75034fd32 --- /dev/null +++ b/arch/mips/ps2/dmac-irq.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 DMA controller (DMAC) IRQs + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static void dmac_reverse_mask(struct irq_data *data) +{ + outl(BIT(16 + data->irq - IRQ_DMAC), DMAC_STAT_MASK); +} + +static void dmac_mask_ack(struct irq_data *data) +{ + const unsigned int bit = BIT(data->irq - IRQ_DMAC); + + outl((bit << 16) | bit, DMAC_STAT_MASK); +} + +#define DMAC_IRQ_TYPE(irq_, name_) \ + { \ + .irq = irq_, \ + .irq_chip = { \ + .name = name_, \ + .irq_unmask = dmac_reverse_mask, \ + .irq_mask = dmac_reverse_mask, \ + .irq_mask_ack = dmac_mask_ack \ + } \ + } + +static struct { + unsigned int irq; + struct irq_chip irq_chip; +} dmac_irqs[] = { + DMAC_IRQ_TYPE(IRQ_DMAC_VIF0, "DMAC VIF0"), + DMAC_IRQ_TYPE(IRQ_DMAC_VIF1, "DMAC VIF1"), + DMAC_IRQ_TYPE(IRQ_DMAC_GIF, "DMAC GIF"), + DMAC_IRQ_TYPE(IRQ_DMAC_FIPU, "DMAC fromIPU"), + DMAC_IRQ_TYPE(IRQ_DMAC_TIPU, "DMAC toIPU"), + DMAC_IRQ_TYPE(IRQ_DMAC_SIF0, "DMAC SIF0"), + DMAC_IRQ_TYPE(IRQ_DMAC_SIF1, "DMAC SIF1"), + DMAC_IRQ_TYPE(IRQ_DMAC_SIF2, "DMAC SIF2"), + DMAC_IRQ_TYPE(IRQ_DMAC_FSPR, "DMAC fromSPR"), + DMAC_IRQ_TYPE(IRQ_DMAC_TSPR, "DMAC toSPR"), + DMAC_IRQ_TYPE(IRQ_DMAC_S, "DMAC stall"), + DMAC_IRQ_TYPE(IRQ_DMAC_ME, "DMAC MFIFO empty"), + DMAC_IRQ_TYPE(IRQ_DMAC_BE, "DMAC bus error"), +}; + +static irqreturn_t dmac_cascade(int irq, void *data) +{ + unsigned int pending = inl(DMAC_STAT_MASK) & 0xffff; + + if (!pending) + return IRQ_NONE; + + while (pending) { + const unsigned int irq_dmac = __fls(pending); + + if (generic_handle_irq(irq_dmac + IRQ_DMAC) < 0) + spurious_interrupt(); + pending &= ~BIT(irq_dmac); + } + + return IRQ_HANDLED; +} + +static struct irqaction cascade_dmac_irqaction = { + .name = "DMAC cascade", + .handler = dmac_cascade, +}; + +int __init dmac_irq_init(void) +{ + size_t i; + int err; + + outl(inl(DMAC_STAT_MASK), DMAC_STAT_MASK); /* Clear status register */ + + for (i = 0; i < ARRAY_SIZE(dmac_irqs); i++) + irq_set_chip_and_handler(dmac_irqs[i].irq, + &dmac_irqs[i].irq_chip, handle_level_irq); + + err = setup_irq(IRQ_C0_DMAC, &cascade_dmac_irqaction); + if (err) + pr_err("irq: Failed to setup DMAC IRQs (err = %d)\n", err); + + return err; +} diff --git a/arch/mips/ps2/irq.c b/arch/mips/ps2/irq.c index 935171a1e3bd..7c656e3735a1 100644 --- a/arch/mips/ps2/irq.c +++ b/arch/mips/ps2/irq.c @@ -19,6 +19,7 @@ void __init arch_init_irq(void) mips_cpu_irq_init(); intc_irq_init(); + dmac_irq_init(); } asmlinkage void plat_irq_dispatch(void) From patchwork Sun Sep 1 15:48:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125367 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 06E5D1395 for ; Sun, 1 Sep 2019 15:48:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E2C8A233A2 for ; Sun, 1 Sep 2019 15:48:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725954AbfIAPsY (ORCPT ); Sun, 1 Sep 2019 11:48:24 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57502 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729151AbfIAPsY (ORCPT ); Sun, 1 Sep 2019 11:48:24 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id BC5EF3F9B6 for ; Sun, 1 Sep 2019 17:48:21 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AD1PnPto9xjE for ; Sun, 1 Sep 2019 17:48:21 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 062113F21C for ; Sun, 1 Sep 2019 17:48:20 +0200 (CEST) Date: Sun, 1 Sep 2019 17:48:20 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 030/120] MIPS: PS2: Timer support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Emotion Engine has 4 independent timers with 16-bit counters[1]. The bus clock or an external (H-BLANK or V-BLANK) clock perform the counting. When a counter reaches a specified reference value, or when it overflows, an interrupt is asserted. The timer status register indicates the cause. Timers 0 and 1 have hold registers for recording the counter value when an SBUS interrupt occurs. Timer registers are 32-bit long and only word-accessible. References: [1] "EE User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 33-39. Signed-off-by: Fredrik Noring --- arch/mips/ps2/Makefile | 1 + arch/mips/ps2/time.c | 153 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 arch/mips/ps2/time.c diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index 1e6406f42b3a..2015870f9fe7 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -2,3 +2,4 @@ obj-y += dmac-irq.o obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o +obj-y += time.o diff --git a/arch/mips/ps2/time.c b/arch/mips/ps2/time.c new file mode 100644 index 000000000000..4979679bc909 --- /dev/null +++ b/arch/mips/ps2/time.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 timer functions + * + * Copyright (C) 2010-2013 Jürgen Urban + * Copyright (C) 2017-2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define CPU_FREQ 294912000 /* CPU clock frequency (Hz) */ +#define BUS_CLOCK (CPU_FREQ/2) /* Bus clock frequency (Hz) */ +#define TM_COMPARE_VALUE (BUS_CLOCK/256/HZ) /* To generate HZ event */ + +/* + * The Emotion Engine has four independent timers with 16-bit counters. The + * bus clock or an external (H-BLANK or V-BLANK) clock performs the counting. + * When a counter reaches a specified reference value, or when it overflows, + * an interrupt is asserted. The timer status register indicates the cause. + * + * Timers 0 and 1 have hold registers for recording the counter value when an + * SBUS interrupt occurs. + * + * Timer registers are 32-bit long and only word-accessible. + */ + +#define T0_COUNT 0x10000000 /* Timer 0 counter value */ +#define T0_MODE 0x10000010 /* Timer 0 mode/status */ +#define T0_COMP 0x10000020 /* Timer 0 compare value */ +#define T0_HOLD 0x10000030 /* Timer 0 hold value */ + +#define T1_COUNT 0x10000800 /* Timer 1 counter value */ +#define T1_MODE 0x10000810 /* Timer 1 mode/status */ +#define T1_COMP 0x10000820 /* Timer 1 compare value */ +#define T1_HOLD 0x10000830 /* Timer 1 hold value */ + +#define T2_COUNT 0x10001000 /* Timer 2 counter value */ +#define T2_MODE 0x10001010 /* Timer 2 mode/status */ +#define T2_COMP 0x10001020 /* Timer 2 compare value */ + +#define T3_COUNT 0x10001800 /* Timer 3 counter value */ +#define T3_MODE 0x10001810 /* Timer 3 mode/status */ +#define T3_COMP 0x10001820 /* Timer 3 compare value */ + +#define TM_MODE_CLKS_BUSCLK (0 << 0) /* BUSCLK (147.456 MHz) */ +#define TM_MODE_CLKS_BUSCLK_16 (1 << 0) /* 1/16 of BUSCLK */ +#define TM_MODE_CLKS_BUSCLK_256 (2 << 0) /* 1/256 of BUSCLK */ +#define TM_MODE_CLKS_EXTERNAL (3 << 0) /* External clock (V-BLANK) */ +#define TM_MODE_GATE_DISABLE (0 << 2) /* Gate function is not used */ +#define TM_MODE_GATE_ENABLE (1 << 2) /* Gate function is used */ +#define TM_MODE_GATS_H_BLANK (0 << 3) /* H-BLANK (disabled if CLKS is 3) */ +#define TM_MODE_GATS_V_BLANK (1 << 3) /* V-BLANK */ +#define TM_MODE_GATM_WHILE_LOW (0 << 4) /* Count while gate signal is low */ +#define TM_MODE_GATM_RESET_RISE (1 << 4) /* Reset and start on rising edge */ +#define TM_MODE_GATM_RESET_FALL (2 << 4) /* Reset and start on falling edge */ +#define TM_MODE_GATM_RESET_BOTH (3 << 4) /* Reset and start on both edges */ +#define TM_MODE_ZRET_KEEP (0 << 6) /* Keep counting ignoring reference */ +#define TM_MODE_ZRET_CLEAR (1 << 6) /* Zero counter reaching reference */ +#define TM_MODE_CUE_STOP (0 << 7) /* Stop counting */ +#define TM_MODE_CUE_START (1 << 7) /* Start counting */ +#define TM_MODE_CMPE_DISABLE (0 << 8) /* Disable compare interrupts */ +#define TM_MODE_CMPE_ENABLE (1 << 8) /* Interrupt reaching reference */ +#define TM_MODE_OVFE_DISABLE (0 << 9) /* Disable overflow interrupts */ +#define TM_MODE_OVFE_ENABLE (1 << 9) /* Interrupt on overflow */ + +/* + * The equal status flag bit is 1 when a compare-interrupt + * has occured. Write 1 to clear. + */ +#define TM_MODE_EQUAL_FLAG (1 << 10) + +/* + * The overflow status flag bit is 1 when an overflow-interrupt + * has occured. Write 1 to clear. + */ +#define TM_MODE_OVERFLOW_FLAG (1 << 11) + +static irqreturn_t ps2_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd = dev_id; + + outl(inl(T0_MODE), T0_MODE); /* Clear the interrupt */ + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static int timer0_periodic(struct clock_event_device *evt) +{ + outl(0, T0_COUNT); + outl(TM_COMPARE_VALUE, T0_COMP); + outl(TM_MODE_CLKS_BUSCLK_256 | TM_MODE_ZRET_CLEAR | TM_MODE_CUE_START | + TM_MODE_CMPE_ENABLE | TM_MODE_EQUAL_FLAG, T0_MODE); + + return 0; +} + +static int timer0_shutdown(struct clock_event_device *evt) +{ + outl(0, T0_MODE); /* Stop timer */ + + return 0; +} + +static struct irqaction timer0_irqaction = { + .handler = ps2_timer_interrupt, + .flags = IRQF_PERCPU | IRQF_TIMER, + .name = "intc-timer0", +}; + +static struct clock_event_device timer0_clockevent_device = { + .name = "timer0", + /* FIXME: Timer is also able to provide CLOCK_EVT_FEAT_ONESHOT. */ + .features = CLOCK_EVT_FEAT_PERIODIC, + + /* FIXME: .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */ + + .rating = 300, /* FIXME: Check value. */ + .irq = IRQ_INTC_TIMER0, + .set_state_periodic = timer0_periodic, + .set_state_shutdown = timer0_shutdown, +}; + +void __init plat_time_init(void) +{ + /* Add timer 0 as clock event source. */ + timer0_clockevent_device.cpumask = cpumask_of(smp_processor_id()); + clockevents_register_device(&timer0_clockevent_device); + timer0_irqaction.dev_id = &timer0_clockevent_device; + setup_irq(IRQ_INTC_TIMER0, &timer0_irqaction); + + /* FIXME: Timer 1 is free and can also be configured as clock event source. */ + + /* Setup frequency for IP7 timer interrupt. */ + mips_hpt_frequency = CPU_FREQ; +} From patchwork Sun Sep 1 15:48:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125371 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B419B112C for ; Sun, 1 Sep 2019 15:48:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9C1BA233A2 for ; Sun, 1 Sep 2019 15:48:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729182AbfIAPse (ORCPT ); Sun, 1 Sep 2019 11:48:34 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56720 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729181AbfIAPse (ORCPT ); Sun, 1 Sep 2019 11:48:34 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 1C6FC3F73E for ; Sun, 1 Sep 2019 17:48:32 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DNj_EkfpVSnS for ; Sun, 1 Sep 2019 17:48:31 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 6AF9D3F708 for ; Sun, 1 Sep 2019 17:48:31 +0200 (CEST) Date: Sun, 1 Sep 2019 17:48:31 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 031/120] MIPS: PS2: SCMD: System command support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/scmd.h | 33 +++++ arch/mips/ps2/Makefile | 1 + arch/mips/ps2/scmd.c | 180 ++++++++++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/scmd.h create mode 100644 arch/mips/ps2/scmd.c diff --git a/arch/mips/include/asm/mach-ps2/scmd.h b/arch/mips/include/asm/mach-ps2/scmd.h new file mode 100644 index 000000000000..b2b98dbaec9b --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/scmd.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 system commands + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_SCMD_H +#define __ASM_MACH_PS2_SCMD_H + +#include + +#define SCMD_COMMAND 0x1f402016 +#define SCMD_STATUS 0x1f402017 +#define SCMD_SEND 0x1f402017 +#define SCMD_RECV 0x1f402018 + +#define SCMD_STATUS_EMPTY 0x40 /* Data is unavailable */ +#define SCMD_STATUS_BUSY 0x80 /* Command is processing */ + +/** + * enum scmd_cmd - system commands + * @scmd_cmd_power_off: power off the system + */ +enum scmd_cmd { + scmd_cmd_power_off = 15, +}; + +int scmd(enum scmd_cmd cmd, + const void *send, size_t send_size, + void *recv, size_t recv_size); + +#endif /* __ASM_MACH_PS2_SCMD_H */ diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index 2015870f9fe7..d90d3e06387f 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -2,4 +2,5 @@ obj-y += dmac-irq.o obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o +obj-y += scmd.o obj-y += time.o diff --git a/arch/mips/ps2/scmd.c b/arch/mips/ps2/scmd.c new file mode 100644 index 000000000000..0516766ffdba --- /dev/null +++ b/arch/mips/ps2/scmd.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 system commands + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * completed - poll for condition to happen, or timeout + * @condition: function to poll for condition + * + * Return: %true if condition happened, else %false on timeout + */ +static bool completed(bool (*condition)(void)) +{ + const unsigned long timeout = jiffies + 5*HZ; + + do { + if (condition()) + return true; + + msleep(1); + } while (time_is_after_jiffies(timeout)); + + return false; +} + +/** + * scmd_status - read system command status register + * + * Return: system command status register value + */ +static u8 scmd_status(void) +{ + return inb(SCMD_STATUS); +} + +/** + * scmd_write - write system command data + * @data: pointer to data to write + * @size: number of bytes to write + */ +static void scmd_write(const u8 *data, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + outb(data[i], SCMD_SEND); +} + +/** + * scmd_ready - can the system receive a command or has finished processing? + * + * Return: %true if the system is ready to receive a command, or has finished + * processing a previous command, otherwise %false + */ +static bool scmd_ready(void) +{ + return (scmd_status() & SCMD_STATUS_BUSY) == 0; +} + +/** + * scmd_wait - wait for the system command to become ready + * + * Return: %true if the system command is ready, else %false on timeout + */ +static bool scmd_wait(void) +{ + return completed(scmd_ready); +} + +/** + * scmd_data - is command data available to be read from the system? + * + * Return: %true if system data is readable, else %false + */ +static bool scmd_data(void) +{ + return (scmd_status() & SCMD_STATUS_EMPTY) == 0; +} + +/** + * scmd_flush - read and discard all available command data from the system + * + * Return: %true if something was read, else %false + */ +static bool scmd_flush(void) +{ + bool flushed; + + for (flushed = false; scmd_data(); flushed = true) + inb(SCMD_RECV); + + return flushed; +} + +/** + * scmd_read - read command data from the system + * @data: pointer to data to read + * @size: maximum number of bytes to read + * + * Return: actual number of bytes read + */ +static size_t scmd_read(u8 *data, size_t size) +{ + size_t r; + + for (r = 0; r < size && scmd_data(); r++) + data[r] = inb(SCMD_RECV); + + return r; +} + +/** + * scmd - general system command function + * @cmd: system command + * @send: pointer to command data to send + * @send_size: size in bytes of command data to send + * @recv: pointer to command data to receive + * @recv_size: exact size in bytes of command data to receive + * + * Context: sleep + * Return: 0 on success, else a negative error number + */ +int scmd(enum scmd_cmd cmd, + const void *send, size_t send_size, + void *recv, size_t recv_size) +{ + static DEFINE_MUTEX(scmd_lock); + int err = 0; + size_t r; + + mutex_lock(&scmd_lock); + + if (!scmd_ready()) { + pr_warn("%s: Unexpectedly busy preceding command %d\n", + __func__, cmd); + + if (!scmd_wait()) { + err = -EBUSY; + goto out_err; + } + } + if (scmd_flush()) + pr_warn("%s: Unexpected data preceding command %d\n", + __func__, cmd); + + scmd_write(send, send_size); + outb(cmd, SCMD_COMMAND); + + if (!scmd_wait()) { + err = -EIO; + goto out_err; + } + r = scmd_read(recv, recv_size); + if (r == recv_size && scmd_flush()) + pr_warn("%s: Unexpected data following command %d\n", + __func__, cmd); + if (r != recv_size) + err = -EIO; + +out_err: + mutex_unlock(&scmd_lock); + return err; +} +EXPORT_SYMBOL_GPL(scmd); + +MODULE_DESCRIPTION("PlayStation 2 system commands"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:48:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125373 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 39ED6112C for ; Sun, 1 Sep 2019 15:48:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 22BFB233A2 for ; Sun, 1 Sep 2019 15:48:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729015AbfIAPsq (ORCPT ); Sun, 1 Sep 2019 11:48:46 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41548 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728975AbfIAPsp (ORCPT ); Sun, 1 Sep 2019 11:48:45 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id E5E3F3F65F for ; Sun, 1 Sep 2019 17:48:43 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sFwMC-r6a4kN for ; Sun, 1 Sep 2019 17:48:43 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 468563F615 for ; Sun, 1 Sep 2019 17:48:43 +0200 (CEST) Date: Sun, 1 Sep 2019 17:48:43 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 032/120] MIPS: PS2: SCMD: System power off command Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/scmd.h | 2 ++ arch/mips/ps2/scmd.c | 29 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/scmd.h b/arch/mips/include/asm/mach-ps2/scmd.h index b2b98dbaec9b..9e0135655ce8 100644 --- a/arch/mips/include/asm/mach-ps2/scmd.h +++ b/arch/mips/include/asm/mach-ps2/scmd.h @@ -30,4 +30,6 @@ int scmd(enum scmd_cmd cmd, const void *send, size_t send_size, void *recv, size_t recv_size); +int scmd_power_off(void); + #endif /* __ASM_MACH_PS2_SCMD_H */ diff --git a/arch/mips/ps2/scmd.c b/arch/mips/ps2/scmd.c index 0516766ffdba..5544c7dfb7b4 100644 --- a/arch/mips/ps2/scmd.c +++ b/arch/mips/ps2/scmd.c @@ -175,6 +175,35 @@ int scmd(enum scmd_cmd cmd, } EXPORT_SYMBOL_GPL(scmd); +/** + * scmd_power_off - system command to power off the system + * + * On success, the processor will have to wait for the shut down to take effect. + * + * Context: sleep + * Return: 0 on success, else a negative error number + */ +int scmd_power_off(void) +{ + u8 status; + int err; + + err = scmd(scmd_cmd_power_off, NULL, 0, &status, sizeof(status)); + if (err < 0) { + pr_err("%s: Write failed with %d\n", __func__, err); + return err; + } + + if (status != 0) { + pr_err("%s: Invalid result with status 0x%x\n", + __func__, status); + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL_GPL(scmd_power_off); + MODULE_DESCRIPTION("PlayStation 2 system commands"); MODULE_AUTHOR("Fredrik Noring"); MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:48:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125375 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E76AE112C for ; Sun, 1 Sep 2019 15:49:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CF8CE233A2 for ; Sun, 1 Sep 2019 15:49:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728912AbfIAPtB (ORCPT ); Sun, 1 Sep 2019 11:49:01 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41556 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728901AbfIAPtB (ORCPT ); Sun, 1 Sep 2019 11:49:01 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 859FD3F65F for ; Sun, 1 Sep 2019 17:48:59 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id V9zDc9D24ClT for ; Sun, 1 Sep 2019 17:48:58 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id CFC743F615 for ; Sun, 1 Sep 2019 17:48:58 +0200 (CEST) Date: Sun, 1 Sep 2019 17:48:58 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 033/120] MIPS: PS2: SCMD: Read system machine name command Message-ID: <58d39cd6e1f0e341342ace77f6ef518f15be5fd7.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org An example of machine name is SCPH-50004. Machines SCPH-10000 and SCPH-15000 do not implement this command. Late SCPH-10000 and all SCPH-15000 have the name in rom0:OSDSYS instead. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/scmd.h | 12 ++++++ arch/mips/ps2/scmd.c | 62 +++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/scmd.h b/arch/mips/include/asm/mach-ps2/scmd.h index 9e0135655ce8..2389b937eec0 100644 --- a/arch/mips/include/asm/mach-ps2/scmd.h +++ b/arch/mips/include/asm/mach-ps2/scmd.h @@ -21,9 +21,11 @@ /** * enum scmd_cmd - system commands * @scmd_cmd_power_off: power off the system + * @scmd_cmd_read_machine_name: read machine name */ enum scmd_cmd { scmd_cmd_power_off = 15, + scmd_cmd_read_machine_name = 23, }; int scmd(enum scmd_cmd cmd, @@ -32,4 +34,14 @@ int scmd(enum scmd_cmd cmd, int scmd_power_off(void); +/** + * struct scmd_machine_name - machine name, or the empty string + * @name: NUL terminated string, for example ``"SCPH-50004"`` + */ +struct scmd_machine_name { + char name[16]; +}; + +struct scmd_machine_name scmd_read_machine_name(void); + #endif /* __ASM_MACH_PS2_SCMD_H */ diff --git a/arch/mips/ps2/scmd.c b/arch/mips/ps2/scmd.c index 5544c7dfb7b4..aecd4f35e312 100644 --- a/arch/mips/ps2/scmd.c +++ b/arch/mips/ps2/scmd.c @@ -175,6 +175,12 @@ int scmd(enum scmd_cmd cmd, } EXPORT_SYMBOL_GPL(scmd); +static int scmd_send_byte(enum scmd_cmd cmd, u8 send_byte, + void *recv, size_t recv_size) +{ + return scmd(cmd, &send_byte, sizeof(send_byte), recv, recv_size); +} + /** * scmd_power_off - system command to power off the system * @@ -204,6 +210,62 @@ int scmd_power_off(void) } EXPORT_SYMBOL_GPL(scmd_power_off); +/** + * scmd_read_machine_name - system command to read the machine name + * + * An example of machine name is SCPH-50004. + * + * Machines SCPH-10000 and SCPH-15000 do not implement this command. Late + * SCPH-10000 and all SCPH-15000 have the name in rom0:OSDSYS instead. + * + * Context: sleep + * Return: the machine name, or the empty string on failure + */ +struct scmd_machine_name scmd_read_machine_name(void) +{ + struct scmd_machine_name machine = { .name = "" }; + struct __attribute__ ((packed)) { + u8 status; + char name[8]; + } buffer0, buffer8; + int err; + + BUILD_BUG_ON(sizeof(buffer0) != 9 || + sizeof(buffer8) != 9); + + /* The machine name comes in two halves that need to be combined. */ + + err = scmd_send_byte(scmd_cmd_read_machine_name, 0, + &buffer0, sizeof(buffer0)); + if (err < 0) { + pr_debug("%s: Read failed with %d at 0\n", __func__, err); + goto out_err; + } + + err = scmd_send_byte(scmd_cmd_read_machine_name, 8, + &buffer8, sizeof(buffer8)); + if (err < 0) { + pr_debug("%s: Read failed with %d at 8\n", __func__, err); + goto out_err; + } + + if (buffer0.status != 0 || + buffer8.status != 0) { + pr_debug("%s: Invalid results with statuses 0x%x and 0x%x\n", + __func__, buffer0.status, buffer8.status); + goto out_err; + } + + BUILD_BUG_ON(sizeof(machine.name) < 16); + memcpy(&machine.name[0], buffer0.name, 8); + memcpy(&machine.name[8], buffer8.name, 8); + machine.name[15] = '\0'; + +out_err: + return machine; +} +EXPORT_SYMBOL_GPL(scmd_read_machine_name); + MODULE_DESCRIPTION("PlayStation 2 system commands"); MODULE_AUTHOR("Fredrik Noring"); MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:49:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125377 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ED8341395 for ; Sun, 1 Sep 2019 15:49:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D54DE20828 for ; Sun, 1 Sep 2019 15:49:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728901AbfIAPtP (ORCPT ); Sun, 1 Sep 2019 11:49:15 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41572 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728848AbfIAPtP (ORCPT ); Sun, 1 Sep 2019 11:49:15 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 96DA83F65F for ; Sun, 1 Sep 2019 17:49:13 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2dew-xyZBJdb for ; Sun, 1 Sep 2019 17:49:12 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id AF57E3F615 for ; Sun, 1 Sep 2019 17:49:12 +0200 (CEST) Date: Sun, 1 Sep 2019 17:49:12 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 034/120] MIPS: PS2: SCMD: Read system command for the real-time clock (RTC) Message-ID: <4e98b54efcb9e5fd27c5dee2bcdbc77b2c9f444b.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The hardware clock is designed to keep Japan standard time (JST), regardless of the region of the machine. This is adjusted in the driver so that the clock to the kernel appears to be kept in coordinated universal time (UTC). Tools such as hwclock should therefore read the clock in the UTC timescale. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/scmd.h | 5 +++ arch/mips/ps2/scmd.c | 55 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/scmd.h b/arch/mips/include/asm/mach-ps2/scmd.h index 2389b937eec0..352a921181b6 100644 --- a/arch/mips/include/asm/mach-ps2/scmd.h +++ b/arch/mips/include/asm/mach-ps2/scmd.h @@ -8,6 +8,7 @@ #ifndef __ASM_MACH_PS2_SCMD_H #define __ASM_MACH_PS2_SCMD_H +#include #include #define SCMD_COMMAND 0x1f402016 @@ -20,10 +21,12 @@ /** * enum scmd_cmd - system commands + * @scmd_cmd_read_rtc: read the real-time clock (RTC) * @scmd_cmd_power_off: power off the system * @scmd_cmd_read_machine_name: read machine name */ enum scmd_cmd { + scmd_cmd_read_rtc = 8, scmd_cmd_power_off = 15, scmd_cmd_read_machine_name = 23, }; @@ -44,4 +47,6 @@ struct scmd_machine_name { struct scmd_machine_name scmd_read_machine_name(void); +int scmd_read_rtc(time64_t *t); + #endif /* __ASM_MACH_PS2_SCMD_H */ diff --git a/arch/mips/ps2/scmd.c b/arch/mips/ps2/scmd.c index aecd4f35e312..34f0fe36bd3d 100644 --- a/arch/mips/ps2/scmd.c +++ b/arch/mips/ps2/scmd.c @@ -13,8 +13,14 @@ #include #include +#include +#include + #include +#define UTC_TO_JST (9*60*60) /* UTC to Japan standard time */ +#define JST_TO_UTC (-UTC_TO_JST) /* Japan standard time to UTC */ + /** * completed - poll for condition to happen, or timeout * @condition: function to poll for condition @@ -266,6 +272,55 @@ struct scmd_machine_name scmd_read_machine_name(void) } EXPORT_SYMBOL_GPL(scmd_read_machine_name); +/** + * scmd_read_rtc - system command to read the real-time clock (RTC) + * @t: pointer to store the time on a successful reading + * + * The hardware clock is designed to keep Japan standard time (JST), regardless + * of the region of the machine. This is adjusted in the driver so that the + * clock to the kernel appears to be kept in coordinated universal time (UTC). + * Tools such as hwclock should therefore read the clock in the UTC timescale. + * + * Context: sleep + * Return: 0 on success, else a negative error number + */ +int scmd_read_rtc(time64_t *t) +{ + struct __attribute__ ((packed)) { + u8 status; + u8 second; + u8 minute; + u8 hour; + u8 pad; + u8 day; + u8 month; + u8 year; + } rtc; + int err; + + BUILD_BUG_ON(sizeof(rtc) != 8); + err = scmd(scmd_cmd_read_rtc, NULL, 0, &rtc, sizeof(rtc)); + if (err < 0) { + pr_debug("%s: Read failed with %d at 0\n", __func__, err); + return err; + } + if (rtc.status != 0) { + pr_debug("%s: Invalid result with status 0x%x\n", + __func__, rtc.status); + return -EIO; + } + + *t = mktime64(bcd2bin(rtc.year) + 2000, + bcd2bin(rtc.month), + bcd2bin(rtc.day), + bcd2bin(rtc.hour), + bcd2bin(rtc.minute), + bcd2bin(rtc.second)) + JST_TO_UTC; + + return 0; +} +EXPORT_SYMBOL_GPL(scmd_read_rtc); + MODULE_DESCRIPTION("PlayStation 2 system commands"); MODULE_AUTHOR("Fredrik Noring"); MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:49:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125379 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 06A561395 for ; Sun, 1 Sep 2019 15:49:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E308B233A2 for ; Sun, 1 Sep 2019 15:49:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728961AbfIAPtZ (ORCPT ); Sun, 1 Sep 2019 11:49:25 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57652 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAPtZ (ORCPT ); Sun, 1 Sep 2019 11:49:25 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 41B1B402D7 for ; Sun, 1 Sep 2019 17:49:24 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8EPAOYVubZGx for ; Sun, 1 Sep 2019 17:49:23 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 8994F3FBF6 for ; Sun, 1 Sep 2019 17:49:23 +0200 (CEST) Date: Sun, 1 Sep 2019 17:49:23 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 035/120] MIPS: PS2: SCMD: Set system command for the real-time clock (RTC) Message-ID: <71881f4e6c2e1552c338fe532e80963df060fa51.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The hardware clock is designed to keep Japan standard time (JST), regardless of the region of the machine. This is adjusted in the driver so that the clock to the kernel appears to be kept in coordinated universal time (UTC). Tools such as hwclock should therefore set the clock in the UTC timescale. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/scmd.h | 4 ++ arch/mips/ps2/scmd.c | 53 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/scmd.h b/arch/mips/include/asm/mach-ps2/scmd.h index 352a921181b6..3ca106ec7da4 100644 --- a/arch/mips/include/asm/mach-ps2/scmd.h +++ b/arch/mips/include/asm/mach-ps2/scmd.h @@ -22,11 +22,13 @@ /** * enum scmd_cmd - system commands * @scmd_cmd_read_rtc: read the real-time clock (RTC) + * @scmd_cmd_write_rtc: set the real-time clock (RTC) * @scmd_cmd_power_off: power off the system * @scmd_cmd_read_machine_name: read machine name */ enum scmd_cmd { scmd_cmd_read_rtc = 8, + scmd_cmd_write_rtc = 9, scmd_cmd_power_off = 15, scmd_cmd_read_machine_name = 23, }; @@ -49,4 +51,6 @@ struct scmd_machine_name scmd_read_machine_name(void); int scmd_read_rtc(time64_t *t); +int scmd_set_rtc(time64_t t); + #endif /* __ASM_MACH_PS2_SCMD_H */ diff --git a/arch/mips/ps2/scmd.c b/arch/mips/ps2/scmd.c index 34f0fe36bd3d..a9efb0e0a76e 100644 --- a/arch/mips/ps2/scmd.c +++ b/arch/mips/ps2/scmd.c @@ -321,6 +321,59 @@ int scmd_read_rtc(time64_t *t) } EXPORT_SYMBOL_GPL(scmd_read_rtc); +/** + * scmd_set_rtc - system command to set the real-time clock (RTC) + * @t: the time to set + * + * The hardware clock is designed to keep Japan standard time (JST), regardless + * of the region of the machine. This is adjusted in the driver so that the + * clock to the kernel appears to be kept in coordinated universal time (UTC). + * Tools such as hwclock should therefore set the clock in the UTC timescale. + + * Context: sleep + * Return: 0 on success, else a negative error number + */ +int scmd_set_rtc(time64_t t) +{ + struct __attribute__ ((packed)) { + u8 second; + u8 minute; + u8 hour; + u8 pad; + u8 day; + u8 month; + u8 year; + } rtc = { }; + struct rtc_time tm; + u8 status; + int err; + + rtc_time_to_tm(t + UTC_TO_JST, &tm); + rtc.second = bin2bcd(tm.tm_sec); + rtc.minute = bin2bcd(tm.tm_min); + rtc.hour = bin2bcd(tm.tm_hour); + rtc.day = bin2bcd(tm.tm_mday); + rtc.month = bin2bcd(tm.tm_mon + 1); + rtc.year = bin2bcd(tm.tm_year - 100); + + BUILD_BUG_ON(sizeof(rtc) != 7); + err = scmd(scmd_cmd_write_rtc, &rtc, sizeof(rtc), + &status, sizeof(status)); + if (err < 0) { + pr_debug("%s: Write failed with %d\n", __func__, err); + return err; + } + + if (status != 0) { + pr_debug("%s: Invalid result with status 0x%x\n", + __func__, status); + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL_GPL(scmd_set_rtc); + MODULE_DESCRIPTION("PlayStation 2 system commands"); MODULE_AUTHOR("Fredrik Noring"); MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:49:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125381 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A0D2112C for ; Sun, 1 Sep 2019 15:49:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0DE4E20828 for ; Sun, 1 Sep 2019 15:49:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728672AbfIAPtl (ORCPT ); Sun, 1 Sep 2019 11:49:41 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56792 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728667AbfIAPtl (ORCPT ); Sun, 1 Sep 2019 11:49:41 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id B69363F708 for ; Sun, 1 Sep 2019 17:49:37 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5DIXbrUndGYR for ; Sun, 1 Sep 2019 17:49:36 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 84BB63F73E for ; Sun, 1 Sep 2019 17:49:36 +0200 (CEST) Date: Sun, 1 Sep 2019 17:49:36 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 036/120] MIPS: PS2: ROM: Iterate over the files in a given ROM directory Message-ID: <335c94c5e90f1422b7512c3a1ef1da4f0f1b212a.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org All PlayStation 2 machines have at least two read-only memories (ROMs) called ROM0 and ROM1. A ROM consists of concatenated files forming a directory. The rom_for_each_file() iterator will be used to search for certain ROM files in subsequent changes. The rom0:ROMVER file, for example, contains information on the ROM version, the machine region, the machine type (CEX for retail, DEX for debug, or TOOL), etc. The input/output processor (IOP) of the PlayStation 2 links several of its modules by reading ROM files. When the kernel links additional modules to handle relayed interrupt services, for example, the kernel module linker must resolve dependencies by identifying whether libraries are linked as ROM or firmware files. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 79 +++++ arch/mips/ps2/Makefile | 1 + arch/mips/ps2/rom.c | 501 +++++++++++++++++++++++++++ 3 files changed, 581 insertions(+) create mode 100644 arch/mips/ps2/rom.c diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h index 6760be183696..063c8b6acf15 100644 --- a/arch/mips/include/asm/mach-ps2/rom.h +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -8,10 +8,89 @@ #ifndef __ASM_MACH_PS2_ROM_H #define __ASM_MACH_PS2_ROM_H +#include + #define ROM0_BASE 0x1fc00000 /* ROM0 base address (boot) */ #define ROM0_SIZE 0x400000 /* ROM0 maximum size */ #define ROM1_BASE 0x1e000000 /* ROM1 base address (DVD) */ #define ROM1_SIZE 0x100000 /* ROM1 maximum size */ +struct rom_dir_entry; + +/** + * struct rom_dir - ROM directory + * @size: size in bytes of all files combined + * @data: pointer to data of all files combined + * @extinfo: extended information of all files combined + * @extinfo.size: size in bytes of all extended information combined + * @extinfo.data: pointer to data of all extended information combined + * @entries: pointer to array of ROM directory entries, with the terminating + * file as the last entry + * + * A directory is considered to be empty if @size is zero, in which case all + * members are zero. + */ +struct rom_dir { + size_t size; + const void *data; + + struct { + size_t size; + const void *data; + } extinfo; + + const struct rom_dir_entry *entries; +}; + +/** + * struct rom_file - ROM file + * @name: name of file, or the empty string for the terminating file + * @size: size in bytes of file + * @data: pointer to data of file + * @extinfo: extended ROM file information + * @extinfo.size: size in bytes of extended file information + * @extinfo.data: pointer to data of extended file information + * @next: pointer to next file, unless this is the terminating file + * + * A file is considered to be a terminating file if @name is the empty string. + * A terminating file is the last file in a &struct rom_dir directory. + */ +struct rom_file { + const char *name; + size_t size; + const void *data; + + struct { + size_t size; + const void *data; + } extinfo; + + const struct rom_dir_entry *next; +}; + +extern struct rom_dir rom0_dir; /* ROM0 directory (boot) */ +extern struct rom_dir rom1_dir; /* ROM1 directory (DVD) */ + +/** + * rom_for_each_file - iterate over files in given ROM directory + * @file: &struct rom_file to use as a ROM file loop cursor + * @dir: &struct rom_dir with ROM directory to iterate over + * + * The statement following the macro is executed for ROM files in the + * directory. + */ +#define rom_for_each_file(file, dir) \ + for ((file) = rom_first_file(dir); \ + !rom_terminating_file(file); \ + (file) = rom_next_file(file)) + +bool rom_empty_dir(const struct rom_dir dir); + +bool rom_terminating_file(const struct rom_file file); + +struct rom_file rom_next_file(const struct rom_file file); + +struct rom_file rom_first_file(const struct rom_dir dir); + #endif /* __ASM_MACH_PS2_ROM_H */ diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index d90d3e06387f..1101ad0d702b 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -2,5 +2,6 @@ obj-y += dmac-irq.o obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o +obj-y += rom.o obj-y += scmd.o obj-y += time.o diff --git a/arch/mips/ps2/rom.c b/arch/mips/ps2/rom.c new file mode 100644 index 000000000000..12a57f24bd63 --- /dev/null +++ b/arch/mips/ps2/rom.c @@ -0,0 +1,501 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 read-only memory (ROM) + * + * Copyright (C) 2019 Fredrik Noring + */ + +/** + * DOC: PlayStation 2 read-only memory (ROM) layout and handling + * + * All PlayStation 2 machines have at least two ROMs called ROM0 and ROM1. + * A ROM consists of concatenated files. All known ROMs have the three files + * named RESET, ROMDIR and EXTINFO at the very beginning of the ROM: + * + * - RESET: The internal structure of this file is currently unknown. + * - ROMDIR: Array of 16-byte &rom_dir_entry directory entries. The file + * name of the last entry is empty and this file is designated + * the terminating file. + * - EXTINFO: Concatenated variable length extended information entries, + * where &rom_dir_entry.extinfo.size gives the size in bytes of + * each entry. + * + * Since the internal layout of the RESET file is unknown, this implementation + * searches for the ROMDIR file by looking after the ``"RESET"`` string that + * is always the first entry of the ROMDIR file directory structure. + * + * Then the ROMDIR and EXTINFO files, and finally the whole ROM, are validated. + * The ROM is accepted if no structural errors are found. Otherwise the ROM is + * discarded and an error message is printed. + * + * Example of a ROM0 directory structure, as decoded from the ROMDIR file: + * + * =================== =========================== =================== + * &rom_dir_entry.name &rom_dir_entry.extinfo.size &rom_dir_entry.size + * RESET 12 10048 + * ROMDIR 80 1584 + * EXTINFO 0 2028 + * ROMVER 0 16 + * SBIN 12 28576 + * LOGO 12 83604 + * IOPBTCONF 8 234 + * IOPBTCON2 8 195 + * SYSMEM 40 4625 + * LOADCORE 32 9597 + * ... ... ... + * PS2LOGO 12 216260 + * OSDSYS 12 336808 + * KERNEL 12 93736 + * 0 0 + * =================== =========================== =================== + * + * In this example the RESET file is 10048 bytes, which means that the offset + * to the ROMDIR file is 10048 bytes. This is also the location of the + * ``"RESET"`` string. The size of the ROMDIR file is 1584 bytes, which means + * there are 1584 / 16 = 99 files, including the terminating file. Thus there + * are 98 normal files, excluding the terminating file. + * + * The sum of all &rom_dir_entry.extinfo.size correspond to the size of the + * EXTINFO file, which is 2028 bytes in this case. The sum of all + * &rom_dir_entry.size is the size of the ROM, which is 3900816 bytes in this + * case. + * + * Files are padded to align with 16 byte boundaries. The EXTINFO file, in + * this example, is therefore padded to 2032 bytes. Some files named ``-`` + * contain zeros only and seem to be padding to align the following file to + * a specific address. + */ + +#include +#include +#include +#include +#include + +#include + +#include + +struct rom_dir rom0_dir; +struct rom_dir rom1_dir; +EXPORT_SYMBOL_GPL(rom0_dir); +EXPORT_SYMBOL_GPL(rom1_dir); + +/** + * struct rom - ROM object + * @name: name of ROM, for example "rom0" or "rom1" + * @base: virtual address of ROM + * @size: ROM size in bytes + */ +struct rom { + const char *name; + const void *base; + size_t size; +}; + +/** + * struct rom_dir_entry - raw 16-byte ROM directory entry of the ROMDIR file + * @name: file name; the empty string for the last terminating file + * @extinfo: extended ROM file information + * @extinfo.size: size in bytes of extended ROM file information + * @size: file size in bytes + */ +struct rom_dir_entry { + char name[10]; + struct { + u16 size; + } extinfo; + u32 size; +}; + +/** + * rom_align_file_size - align ROM file size to 16 byte boundaries + * @size: possibly unaligned ROM size in bytes + * + * The aligned file size is used to obtain the offset to the subsequent file + * in a ROM. + * + * Return: padded file size in bytes, aligned to 16 byte boundaries + */ +static size_t rom_align_file_size(size_t size) +{ + return ALIGN(size, 16); +} + +/** + * rom_next_extinfo_data - pointer to the EXTINFO entry for the subsequent file + * @file: file to find the next EXTINFO entry pointer for + * + * Return: pointer to the following EXTINFO entry + */ +static const void *rom_next_extinfo_data(const struct rom_file *file) +{ + const u8 *d = file->extinfo.data; + + return &d[file->extinfo.size]; +} + +/** + * rom_next_data - pointer to the data for the subsequent file + * @file: file to find the next data pointer for + * + * Return: pointer to the data for the subsequent file + */ +static const void *rom_next_data(const struct rom_file *file) +{ + const u8 *d = file->data; + + return &d[rom_align_file_size(file->size)]; +} + +/** + * rom_empty_dir - is the ROM directory empty? + * @dir: ROM directory to check + * + * Context: any + * Return: %true if the ROM directory is empty, else %false + */ +bool rom_empty_dir(const struct rom_dir dir) +{ + return !dir.size; +} +EXPORT_SYMBOL_GPL(rom_empty_dir); + +/** + * rom_terminating_file - is this a terminating ROM file? + * @file: ROM file to check + * + * Context: any + * Return: %true if the ROM file is a terminating entry, else %false + */ +bool rom_terminating_file(const struct rom_file file) +{ + return file.name[0] == '\0'; +} +EXPORT_SYMBOL_GPL(rom_terminating_file); + +/** + * rom_next_file - advance to next ROM file, unless terminating file is given + * @file: ROM file to advance from + * + * Context: any + * Return: next ROM file, or a terminating file + */ +struct rom_file rom_next_file(const struct rom_file file) +{ + if (rom_terminating_file(file)) + return file; + + return (struct rom_file) { + .name = file.next->name, + .size = file.next->size, + .data = rom_next_data(&file), + .extinfo = { + .size = file.next->extinfo.size, + .data = rom_next_extinfo_data(&file) + }, + .next = &file.next[file.next->name[0] != '\0' ? 1 : 0] + }; +} +EXPORT_SYMBOL_GPL(rom_next_file); + +/** + * rom_first_file - first ROM file of a ROM directory + * @dir: ROM directory to retrieve the first file for + * + * Context: any + * Return: first ROM file, or a terminating file if the directory is empty + */ +struct rom_file rom_first_file(const struct rom_dir dir) +{ + if (rom_empty_dir(dir)) + return (struct rom_file) { .name = "" }; + + return (struct rom_file) { + .name = dir.entries->name, + .size = dir.entries->size, + .data = dir.data, + .extinfo = { + .size = dir.entries->extinfo.size, + .data = dir.extinfo.data + }, + .next = &dir.entries[1] + }; +} +EXPORT_SYMBOL_GPL(rom_first_file); + +/** + * find_reset_string - find the offset to the ``"RESET"`` string, if it exists + * @rom: ROM to search in + * + * The ``"RESET"`` string that is always the first entry of the ROMDIR file + * directory structure. + * + * Return: byte offset to ``"RESET"``, or the size of the ROM on failure + */ +static loff_t __init find_reset_string(const struct rom rom) +{ + const char *s = rom.base; + size_t i; + + for (i = 0; i + sizeof(struct rom_dir_entry) <= rom.size; i++) + if (s[i + 0] == 'R' && + s[i + 1] == 'E' && + s[i + 2] == 'S' && + s[i + 3] == 'E' && + s[i + 4] == 'T' && + s[i + 5] == '\0') + return i; + + return rom.size; +} + +/** + * rom_addr - pointer at offset within a given ROM object + * @rom: ROM object + * @offset: offset in bytes for the pointer location + * @size: size in bytes of the data at the given offset + * + * Return: ROM pointer, or %NULL if @size at the @offset is outside of the ROM + */ +static const void * __init rom_addr( + const struct rom rom, loff_t offset, size_t size) +{ + const u8 *b = rom.base; + + return offset + size <= rom.size ? &b[offset] : NULL; +} + +/** + * valid_rom_dir_entry_name - does the ROM directory entry has a valid name? + * @entry: ROM directory entry + * + * Return: %true if the ROM directory entry has a valid name, otherwise %false + */ +static bool __init valid_rom_dir_entry_name(const struct rom_dir_entry *entry) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(entry->name); i++) + if (entry->name[i] == '\0') + return true; + + return false; +} + +/** + * rom_dir_entry - ROM directory entry for a given ROM index + * @rom: ROM object + * @reset_offset: offset in bytes from ROM object start to the RESET file + * @entry_index: file index starting from zero + * + * Return: ROM directory entry for the given index + */ +static const struct rom_dir_entry * __init rom_dir_entry( + const struct rom rom, loff_t reset_offset, size_t entry_index) +{ + return rom_addr(rom, + reset_offset + entry_index * sizeof(struct rom_dir_entry), + sizeof(struct rom_dir_entry)); +} + +/** + * valid_rom_dir_header - is the ROM object valid? + * @rom: ROM object + * @reset_offset: offset in bytes from ROM object start to the RESET file + * @reset: the RESET ROM file + * @romdir: the ROMDIR ROM file + * @extinfo: the EXTINFO ROM file + * + * This verifies some of the assumptions that are made about read-only memories. + * + * Return: %true if the ROM appears to have a valid header, otherwise %false + */ +static bool __init valid_rom_dir_header(const struct rom rom, + const loff_t reset_offset, + const struct rom_dir_entry *reset, + const struct rom_dir_entry *romdir, + const struct rom_dir_entry *extinfo) +{ + size_t aligned_rom_header_size; + + if (!reset || !romdir || !extinfo) { + pr_debug("%s: Missing RESET, ROMDIR or EXTINFO\n", rom.name); + return false; + } + + if (strcmp(reset->name, "RESET") != 0 || + strcmp(romdir->name, "ROMDIR") != 0 || + strcmp(extinfo->name, "EXTINFO") != 0) { + pr_debug("%s: Misnamed RESET, ROMDIR or EXTINFO\n", rom.name); + return false; + } + + if (rom_align_file_size(reset->size) != reset_offset) { + pr_debug("%s: Unaligned RESET %zu != %llu\n", rom.name, + rom_align_file_size(reset->size), reset_offset); + return false; + } + + if (romdir->size % sizeof(struct rom_dir_entry) != 0) { + pr_debug("%s: ROMDIR unaligned %zu\n", rom.name, romdir->size); + return false; + } + + aligned_rom_header_size = + rom_align_file_size(reset->size) + + rom_align_file_size(romdir->size) + + rom_align_file_size(extinfo->size); + if (aligned_rom_header_size > rom.size) { + pr_debug("%s: ROM header to large %zu > %zu\n", rom.name, + aligned_rom_header_size, rom.size); + return false; + } + + return true; +} + +/** + * rom_dir_size - total ROM object file size in bytes + * @rom: ROM object + * @reset: the RESET ROM file + * @romdir: the ROMDIR ROM file + * @extinfo: the EXTINFO ROM file + * + * Return: total size in bytes of all files for the ROM object + */ +static size_t __init rom_dir_size(const struct rom rom, + const struct rom_dir_entry *reset, + const struct rom_dir_entry *romdir, + const struct rom_dir_entry *extinfo) +{ + const size_t n = romdir->size / sizeof(struct rom_dir_entry); + const struct rom_dir_entry *entries = reset; + size_t extinfo_size = 0; + size_t size = 0; + size_t i; + + if (!n) { + pr_debug("%s: Missing terminating entry\n", rom.name); + return 0; + } + + if (entries[n - 1].name[0] != '\0') { + pr_debug("%s: Nonterminating name: \"%s\"\n", rom.name, + entries[n - 1].name); + return 0; + } + + for (i = 0; i < n; i++) { + if (!valid_rom_dir_entry_name(&entries[i])) { + pr_debug("%s: Invalid entry name\n", rom.name); + return 0; + } + + extinfo_size += entries[i].extinfo.size; + size += rom_align_file_size(entries[i].size); + } + + if (extinfo_size > extinfo->size) { + pr_debug("%s: EXTINFO too large %zu > %zu\n", rom.name, + extinfo_size, extinfo->size); + return 0; + } + + if (size > rom.size) { + pr_debug("%s: ROM size too large %zu > %zu\n", rom.name, + size, rom.size); + return 0; + } + + pr_info("%s: Found %zu files in %zu bytes\n", rom.name, n - 1, size); + + return size; +} + +/** + * extinfo_data - data for the EXTINFO ROM file + * @rom: read-only memory object + * @reset: the RESET ROM file + * @romdir: the ROMDIR ROM file + * + * The EXTINFO file comes as the third file after RESET and ROMDIR. + * + * Return: EXTINFO ROM file data + */ +static const void * __init extinfo_data(const struct rom rom, + const struct rom_dir_entry *reset, + const struct rom_dir_entry *romdir) +{ + const u8 *b = rom.base; + + return &b[rom_align_file_size(reset->size) + + rom_align_file_size(romdir->size)]; +} + +/** + * rom_dir_for_rom - the ROM directory for a given ROM object + * @rom: ROM object + * + * Return: ROM directory + */ +static struct rom_dir __init rom_dir_for_rom(const struct rom rom) +{ + const loff_t reset_offset = find_reset_string(rom); + struct rom_dir dir = { }; + size_t size; + + /* RESET, ROMDIR and EXTINFO always come at indices 0, 1, 2. */ + const struct rom_dir_entry + *reset = rom_dir_entry(rom, reset_offset, 0), + *romdir = rom_dir_entry(rom, reset_offset, 1), + *extinfo = rom_dir_entry(rom, reset_offset, 2); + + if (!valid_rom_dir_header(rom, reset_offset, reset, romdir, extinfo)) + return dir; + + size = rom_dir_size(rom, reset, romdir, extinfo); + if (!size) + return dir; + + dir.size = size; + dir.data = rom.base; + dir.extinfo.size = extinfo->size; + dir.extinfo.data = extinfo_data(rom, reset, romdir); + dir.entries = reset; + + return dir; +} + +/** + * rom_dir_init - the ROM directory for a given physical address + * @name: name of the ROM object + * @rom_phys_base: physical address of the ROM + * @rom_size: maximum size in bytes of the ROM + * + * The ROM directory is adjusted to the actual total size of the ROM files. + * + * Return: ROM directory + */ +static struct rom_dir __init rom_dir_init(const char *name, + phys_addr_t rom_phys_base, size_t rom_size) +{ + const struct rom rom = { + .name = name, + .base = phys_to_virt(rom_phys_base), + .size = rom_size + }; + + return rom_dir_for_rom(rom); +} + +static int __init ps2_rom_init(void) +{ + BUILD_BUG_ON(sizeof(struct rom_dir_entry) != 16); + + rom0_dir = rom_dir_init("rom0", ROM0_BASE, ROM0_SIZE); + rom1_dir = rom_dir_init("rom1", ROM1_BASE, ROM1_SIZE); + + return 0; +} +arch_initcall(ps2_rom_init); From patchwork Sun Sep 1 15:49:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125383 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE9A5112C for ; Sun, 1 Sep 2019 15:49:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ACF6B233A2 for ; Sun, 1 Sep 2019 15:49:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728667AbfIAPtu (ORCPT ); Sun, 1 Sep 2019 11:49:50 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57714 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAPtu (ORCPT ); Sun, 1 Sep 2019 11:49:50 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id A5F844036B for ; Sun, 1 Sep 2019 17:49:48 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ACefYi-2gaLe for ; Sun, 1 Sep 2019 17:49:48 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 081F43FBF6 for ; Sun, 1 Sep 2019 17:49:47 +0200 (CEST) Date: Sun, 1 Sep 2019 17:49:47 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 037/120] MIPS: PS2: ROM: Find ROM files with a given name, if they exist Message-ID: <34f0675b7e66bf672ff043e8f66c2c2364cd9880.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org rom_find_files() searches for files in the given ROM directory. Most ROM files have unique names, but certain special files named for example "-" appear multiple times. The "continue; else" construction is used to avoid an if-else ambiguity warning from GCC, when the loop has an if-else statement. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h index 063c8b6acf15..8794bd13184e 100644 --- a/arch/mips/include/asm/mach-ps2/rom.h +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -85,6 +85,19 @@ extern struct rom_dir rom1_dir; /* ROM1 directory (DVD) */ !rom_terminating_file(file); \ (file) = rom_next_file(file)) +/** + * rom_find_files - find ROM files with the given name, if they exist + * @file: &struct rom_file to use as a ROM file match cursor + * @dir: &struct rom_dir with ROM directory to search in + * @filename: file name to look for + * + * The statement following the macro is executed for ROM files having the + * given name. + */ +#define rom_find_files(file, dir, filename) \ + rom_for_each_file((file), (dir)) \ + if (strcmp((file).name, filename) != 0) continue; else + bool rom_empty_dir(const struct rom_dir dir); bool rom_terminating_file(const struct rom_file file); From patchwork Sun Sep 1 15:50:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125385 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 557401395 for ; Sun, 1 Sep 2019 15:50:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3CA48233A2 for ; Sun, 1 Sep 2019 15:50:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728654AbfIAPuP (ORCPT ); Sun, 1 Sep 2019 11:50:15 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41670 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAPuO (ORCPT ); Sun, 1 Sep 2019 11:50:14 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 0893E3F684 for ; Sun, 1 Sep 2019 17:50:13 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Y3EikCEZws4j for ; Sun, 1 Sep 2019 17:50:12 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 65A0F3F672 for ; Sun, 1 Sep 2019 17:50:12 +0200 (CEST) Date: Sun, 1 Sep 2019 17:50:12 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 038/120] MIPS: PS2: ROM: Read data for a given ROM file name Message-ID: <69a1b78886392bca426ac6f521197af06d768042.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Reading ROM files is trivial since they are permanently available in memory. Having rom_read_file() is a convenient when for example resolving the machine region in subsequent changes. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 3 +++ arch/mips/ps2/rom.c | 33 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h index 8794bd13184e..f2c35788ddfb 100644 --- a/arch/mips/include/asm/mach-ps2/rom.h +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -98,6 +98,9 @@ extern struct rom_dir rom1_dir; /* ROM1 directory (DVD) */ rom_for_each_file((file), (dir)) \ if (strcmp((file).name, filename) != 0) continue; else +ssize_t rom_read_file(const struct rom_dir dir, + const char *name, void *buffer, size_t size, loff_t offset); + bool rom_empty_dir(const struct rom_dir dir); bool rom_terminating_file(const struct rom_file file); diff --git a/arch/mips/ps2/rom.c b/arch/mips/ps2/rom.c index 12a57f24bd63..840d37a199d8 100644 --- a/arch/mips/ps2/rom.c +++ b/arch/mips/ps2/rom.c @@ -224,6 +224,39 @@ struct rom_file rom_first_file(const struct rom_dir dir) } EXPORT_SYMBOL_GPL(rom_first_file); +/** + * rom_read_file - read ROM file data + * @dir: directory to read the file from + * @name: file name to read + * @buffer: pointer to buffer to store data that is read + * @size: size in bytes to read + * @offset: offset in bytes to start reading + * + * Context: any + * Return: on successful completion, a nonnegative integer indicating the + * number of bytes actually read; otherwise, a negative error number + */ +ssize_t rom_read_file(const struct rom_dir dir, + const char *name, void *buffer, size_t size, loff_t offset) +{ + struct rom_file file; + + rom_find_files(file, dir, name) + if (offset < file.size) { + const u8 *b = file.data; + size_t remaining = file.size - offset; + size_t n = min(size, remaining); + + memcpy(buffer, &b[offset], n); + + return n; + } else + return 0; + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(rom_read_file); + /** * find_reset_string - find the offset to the ``"RESET"`` string, if it exists * @rom: ROM to search in From patchwork Sun Sep 1 15:50:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125387 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2690B112C for ; Sun, 1 Sep 2019 15:50:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0E8BC233A2 for ; Sun, 1 Sep 2019 15:50:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728734AbfIAPu3 (ORCPT ); Sun, 1 Sep 2019 11:50:29 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:56864 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAPu3 (ORCPT ); Sun, 1 Sep 2019 11:50:29 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id BCC1B3F73E for ; Sun, 1 Sep 2019 17:50:27 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aKX_22ltDbSv for ; Sun, 1 Sep 2019 17:50:26 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id E90993F708 for ; Sun, 1 Sep 2019 17:50:26 +0200 (CEST) Date: Sun, 1 Sep 2019 17:50:26 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 039/120] MIPS: PS2: ROM: Read extended information for a given ROM file Message-ID: <5ea0f2d9e2cb3475661c922ee1b1b05367293c63.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The extended information (EXTINFO) is metadata about ROM files, often but not always containing file date, version and brief comments. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 22 ++++++ arch/mips/ps2/rom.c | 106 +++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h index f2c35788ddfb..4cc3fcffaa59 100644 --- a/arch/mips/include/asm/mach-ps2/rom.h +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -69,6 +69,25 @@ struct rom_file { const struct rom_dir_entry *next; }; +/** + * struct rom_extinfo - extended ROM file information + * @version: version number + * @date: date ROM was created + * @date.year: year ROM was created + * @date.month: month ROM was created + * @date.day: day ROM was created + * @comment: comment or the empty string + */ +struct rom_extinfo { + int version; + struct { + int year; + int month; + int day; + } date; + const char *comment; +}; + extern struct rom_dir rom0_dir; /* ROM0 directory (boot) */ extern struct rom_dir rom1_dir; /* ROM1 directory (DVD) */ @@ -101,6 +120,9 @@ extern struct rom_dir rom1_dir; /* ROM1 directory (DVD) */ ssize_t rom_read_file(const struct rom_dir dir, const char *name, void *buffer, size_t size, loff_t offset); +struct rom_extinfo rom_read_extinfo(const char *name, + const void *buffer, size_t size); + bool rom_empty_dir(const struct rom_dir dir); bool rom_terminating_file(const struct rom_file file); diff --git a/arch/mips/ps2/rom.c b/arch/mips/ps2/rom.c index 840d37a199d8..a510832e26d7 100644 --- a/arch/mips/ps2/rom.c +++ b/arch/mips/ps2/rom.c @@ -66,6 +66,7 @@ * a specific address. */ +#include #include #include #include @@ -108,6 +109,32 @@ struct rom_dir_entry { u32 size; }; +/** + * enum rom_extinfo_entry_type - EXTINFO &rom_extinfo_entry.type for a ROM file + * @rom_extinfo_entry_date: BCD of day, month and year follows as 4 byte data + * @rom_extinfo_entry_version: version number is in &rom_extinfo_entry.value + * @rom_extinfo_entry_comment: NUL terminated comment string follows as data + * @rom_extinfo_entry_unknown: Unclear, but seems to indicate file is aligned + */ +enum rom_extinfo_entry_type { + rom_extinfo_entry_date = 1, + rom_extinfo_entry_version = 2, + rom_extinfo_entry_comment = 3, + rom_extinfo_entry_unknown = 0x7f +}; + +/** + * struct rom_extinfo_entry - raw 4-byte EXTINFO entry for a ROM file + * @value: only known use is the version number for &rom_extinfo_entry_version + * @size: size in bytes of following data + * @type: &rom_extinfo_entry_type type + */ +struct rom_extinfo_entry { + u16 value; + u8 size; + u8 type; +}; + /** * rom_align_file_size - align ROM file size to 16 byte boundaries * @size: possibly unaligned ROM size in bytes @@ -257,6 +284,84 @@ ssize_t rom_read_file(const struct rom_dir dir, } EXPORT_SYMBOL_GPL(rom_read_file); +/** + * rom_read_extinfo - read EXTINFO for a ROM file + * @name: name of ROM file, used for error reporting + * @buffer: pointer to EXTINFO data + * @size: size of EXTINFO data + * + * Return: EXTINFO for ROM file, where undefined members are zero or the empty + * string in the case of the comment + */ +struct rom_extinfo rom_read_extinfo(const char *name, + const void *buffer, size_t size) +{ + struct rom_extinfo ei = { .comment = "" }; + struct rom_extinfo_entry entry; + const u8 *buf = buffer; + size_t i = 0; + + /* + * As an example, three EXTINFO entries for a ROM file might look + * like this in binary form: + * + * 00 00 04 01 03 04 02 20 01 01 00 02 00 00 08 03 ................ + * 53 74 64 69 6f 00 00 00 Stdio... + * + * The first entry is the date 2002-04-03, the second entry is the + * version 0x101, and the last entry is the comment "Stdio". + */ + + while (i + sizeof(entry) <= size) { + const u8 *data = &buf[i + sizeof(entry)]; + + memcpy(&entry, &buf[i], sizeof(entry)); + i += sizeof(entry) + entry.size; + + if (i > size) { + pr_debug("%s: %s: Invalid entry size %zu > %zu\n", + __func__, name, i, size); + break; + } + + switch (entry.type) { + case rom_extinfo_entry_date: + if (entry.size == 4) { + ei.date.day = bcd2bin(data[0]); + ei.date.month = bcd2bin(data[1]); + ei.date.year = bcd2bin(data[2]) + + bcd2bin(data[3]) * 100; + } else + pr_debug("%s: %s: Invalid date size %u\n", + __func__, name, entry.size); + break; + + case rom_extinfo_entry_version: + ei.version = entry.value; + break; + + case rom_extinfo_entry_comment: + if (entry.size > 0 && data[entry.size - 1] == '\0') { + ei.comment = (const char *)data; + } else + pr_debug("%s: %s: Malformed comment\n", + __func__, name); + break; + + case rom_extinfo_entry_unknown: + /* Ignore */ + break; + + default: + pr_debug("%s: %s: Invalid type %d\n", + __func__, name, entry.type); + } + } + + return ei; +} +EXPORT_SYMBOL_GPL(rom_read_extinfo); + /** * find_reset_string - find the offset to the ``"RESET"`` string, if it exists * @rom: ROM to search in @@ -525,6 +630,7 @@ static struct rom_dir __init rom_dir_init(const char *name, static int __init ps2_rom_init(void) { BUILD_BUG_ON(sizeof(struct rom_dir_entry) != 16); + BUILD_BUG_ON(sizeof(struct rom_extinfo_entry) != 4); rom0_dir = rom_dir_init("rom0", ROM0_BASE, ROM0_SIZE); rom1_dir = rom_dir_init("rom1", ROM1_BASE, ROM1_SIZE); From patchwork Sun Sep 1 15:50:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125389 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0FFDC112C for ; Sun, 1 Sep 2019 15:50:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ECB75233A2 for ; Sun, 1 Sep 2019 15:50:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726552AbfIAPum (ORCPT ); Sun, 1 Sep 2019 11:50:42 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57800 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726260AbfIAPum (ORCPT ); Sun, 1 Sep 2019 11:50:42 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 37E20402D7 for ; Sun, 1 Sep 2019 17:50:41 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3ia7rdVHrTBq for ; Sun, 1 Sep 2019 17:50:40 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 85C8C3FBF6 for ; Sun, 1 Sep 2019 17:50:40 +0200 (CEST) Date: Sun, 1 Sep 2019 17:50:40 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 040/120] MIPS: PS2: ROM: Read and decode the ROMVER file Message-ID: <01d431fa1e7c4b03bb95d5a7016677958a09abd3.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The ROMVER file contains information on the ROM version, the machine region, the machine type (CEX for retail, DEX for debug, or TOOL) and the date the ROM was created. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 30 ++++++++++++++++++++++++++++ arch/mips/ps2/rom.c | 28 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h index 4cc3fcffaa59..42e520f32f65 100644 --- a/arch/mips/include/asm/mach-ps2/rom.h +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -123,6 +123,36 @@ ssize_t rom_read_file(const struct rom_dir dir, struct rom_extinfo rom_read_extinfo(const char *name, const void *buffer, size_t size); +/** + * struct rom_ver - ROM version + * @number: ROM version number + * @region: ROM region with ``'J'`` for Japan, ``'E'`` for Europe, + * ``'C'`` for China, and ``'A'`` or ``'H'`` for the USA + * @type: ROM type with ``'C'`` for retail (CEX), ``'D'`` for debug (DEX), + * and `'T'`` for TOOL, or ``'-'`` for undefined + * @date: date ROM was created + * @date.year: year ROM was created + * @date.month: month ROM was created + * @date.day: day ROM was created + * + * Note that the Namco System 246 arcade systems are TOOL types as well. + * + * A ROM version is considered to be invalid if @number is zero, in which + * case all members are zero except @region and @type that are ``'-'``. + */ +struct rom_ver { + int number; + char region; + char type; + struct { + int year; + int month; + int day; + } date; +}; + +struct rom_ver rom_version(void); + bool rom_empty_dir(const struct rom_dir dir); bool rom_terminating_file(const struct rom_file file); diff --git a/arch/mips/ps2/rom.c b/arch/mips/ps2/rom.c index a510832e26d7..32ae8ec839c4 100644 --- a/arch/mips/ps2/rom.c +++ b/arch/mips/ps2/rom.c @@ -362,6 +362,27 @@ struct rom_extinfo rom_read_extinfo(const char *name, } EXPORT_SYMBOL_GPL(rom_read_extinfo); +/** + * rom_version - read the ROMVER file in ROM0 + * + * Context: any + * Return: ROM version; or, if reading failed, all members zeroed except + * @region and @type that are set to ``'-'`` + */ +struct rom_ver rom_version(void) +{ + struct rom_ver v = { }; + char buffer[20] = { }; + ssize_t r = rom_read_file(rom0_dir, "ROMVER", + buffer, sizeof(buffer) - 1, 0); + + return r > 0 && sscanf(buffer, "%4x%c%c%4d%2d%2d", + &v.number, &v.region, &v.type, + &v.date.year, &v.date.month, &v.date.day) == 6 ? + v : (struct rom_ver) { .region = '-', .type = '-' }; +} +EXPORT_SYMBOL_GPL(rom_version); + /** * find_reset_string - find the offset to the ``"RESET"`` string, if it exists * @rom: ROM to search in @@ -629,12 +650,19 @@ static struct rom_dir __init rom_dir_init(const char *name, static int __init ps2_rom_init(void) { + struct rom_ver v; + BUILD_BUG_ON(sizeof(struct rom_dir_entry) != 16); BUILD_BUG_ON(sizeof(struct rom_extinfo_entry) != 4); rom0_dir = rom_dir_init("rom0", ROM0_BASE, ROM0_SIZE); rom1_dir = rom_dir_init("rom1", ROM1_BASE, ROM1_SIZE); + v = rom_version(); + pr_info("rom0: Version %04x %c %c %04d-%02d-%02d\n", + v.number, v.region, v.type, + v.date.year, v.date.month, v.date.day); + return 0; } arch_initcall(ps2_rom_init); From patchwork Sun Sep 1 15:52:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125405 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EE7D3112C for ; Sun, 1 Sep 2019 15:52:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D06A52339D for ; Sun, 1 Sep 2019 15:52:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728644AbfIAPwm (ORCPT ); Sun, 1 Sep 2019 11:52:42 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:57010 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728616AbfIAPwm (ORCPT ); Sun, 1 Sep 2019 11:52:42 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 945B53F73E for ; Sun, 1 Sep 2019 17:52:40 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FIlQnHnI_MeK for ; Sun, 1 Sep 2019 17:52:39 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id E798D3F708 for ; Sun, 1 Sep 2019 17:52:39 +0200 (CEST) Date: Sun, 1 Sep 2019 17:52:39 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 041/120] MIPS: PS2: ROM: Resolve the name for the type in the ROMVER file Message-ID: <6a096d0e6a7532194907863bc0286059fddb7bef.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org 'C' indicates CEX for retail, 'D' indicates DEX for debug, and 'T' indicates a TOOL machine. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 4 ++++ arch/mips/ps2/rom.c | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h index 42e520f32f65..0b0e7c4162f5 100644 --- a/arch/mips/include/asm/mach-ps2/rom.h +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -135,6 +135,8 @@ struct rom_extinfo rom_read_extinfo(const char *name, * @date.month: month ROM was created * @date.day: day ROM was created * + * The @type name can be resolved with rom_type_name(). + * * Note that the Namco System 246 arcade systems are TOOL types as well. * * A ROM version is considered to be invalid if @number is zero, in which @@ -153,6 +155,8 @@ struct rom_ver { struct rom_ver rom_version(void); +const char *rom_type_name(char type); + bool rom_empty_dir(const struct rom_dir dir); bool rom_terminating_file(const struct rom_file file); diff --git a/arch/mips/ps2/rom.c b/arch/mips/ps2/rom.c index 32ae8ec839c4..9adea705cbca 100644 --- a/arch/mips/ps2/rom.c +++ b/arch/mips/ps2/rom.c @@ -383,6 +383,22 @@ struct rom_ver rom_version(void) } EXPORT_SYMBOL_GPL(rom_version); +/** + * rom_type_name - name for the ROM type character in the ROMVER file in ROM0 + * @type: &rom_ver.type type character. + * + * Context: any + * Return: ROM type name, ``"-"`` if undefined or ``"?"`` if unrecognised + */ +const char *rom_type_name(char type) +{ + return type == 'C' ? "CEX" : + type == 'D' ? "DEX" : + type == 'T' ? "TOOL" : + type == '-' ? "-" : "?"; +} +EXPORT_SYMBOL_GPL(rom_type_name); + /** * find_reset_string - find the offset to the ``"RESET"`` string, if it exists * @rom: ROM to search in @@ -659,8 +675,8 @@ static int __init ps2_rom_init(void) rom1_dir = rom_dir_init("rom1", ROM1_BASE, ROM1_SIZE); v = rom_version(); - pr_info("rom0: Version %04x %c %c %04d-%02d-%02d\n", - v.number, v.region, v.type, + pr_info("rom0: Version %04x %c %s %04d-%02d-%02d\n", + v.number, v.region, rom_type_name(v.type), v.date.year, v.date.month, v.date.day); return 0; From patchwork Sun Sep 1 15:52:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125407 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 67215112C for ; Sun, 1 Sep 2019 15:53:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4FDB42339D for ; Sun, 1 Sep 2019 15:53:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728874AbfIAPxA (ORCPT ); Sun, 1 Sep 2019 11:53:00 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:41972 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728616AbfIAPxA (ORCPT ); Sun, 1 Sep 2019 11:53:00 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 0C12F3F695 for ; Sun, 1 Sep 2019 17:52:58 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4qlIxCNUCWes for ; Sun, 1 Sep 2019 17:52:57 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 6749D3F684 for ; Sun, 1 Sep 2019 17:52:57 +0200 (CEST) Date: Sun, 1 Sep 2019 17:52:57 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 042/120] MIPS: PS2: ROM: Resolve the name for the region in the ROMVER file Message-ID: <938c0cf921142d71b832d0c062503aeff71c103f.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org 'J' indicates Japan, 'E' indicates Europe, 'C' indicates China and 'A' and 'H' indicate the USA. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/rom.h | 5 ++++- arch/mips/ps2/rom.c | 22 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/arch/mips/include/asm/mach-ps2/rom.h b/arch/mips/include/asm/mach-ps2/rom.h index 0b0e7c4162f5..43770fd62a2e 100644 --- a/arch/mips/include/asm/mach-ps2/rom.h +++ b/arch/mips/include/asm/mach-ps2/rom.h @@ -135,7 +135,8 @@ struct rom_extinfo rom_read_extinfo(const char *name, * @date.month: month ROM was created * @date.day: day ROM was created * - * The @type name can be resolved with rom_type_name(). + * The @region and @type names can be resolved with rom_region_name() and + * rom_type_name(). * * Note that the Namco System 246 arcade systems are TOOL types as well. * @@ -155,6 +156,8 @@ struct rom_ver { struct rom_ver rom_version(void); +const char *rom_region_name(char region); + const char *rom_type_name(char type); bool rom_empty_dir(const struct rom_dir dir); diff --git a/arch/mips/ps2/rom.c b/arch/mips/ps2/rom.c index 9adea705cbca..7cdc4962069e 100644 --- a/arch/mips/ps2/rom.c +++ b/arch/mips/ps2/rom.c @@ -383,6 +383,24 @@ struct rom_ver rom_version(void) } EXPORT_SYMBOL_GPL(rom_version); +/** + * rom_region_name - name for the ROM region character in the ROMVER file + * @region: &rom_ver.region region character. + * + * Context: any + * Return: ROM region name, ``"-"`` if undefined or ``"?"`` if unrecognised + */ +const char *rom_region_name(char region) +{ + return region == 'J' ? "Japan" : + region == 'E' ? "Europe" : + region == 'C' ? "China" : + region == 'A' ? "USA" : + region == 'H' ? "USA" : + region == '-' ? "-" : "?"; +} +EXPORT_SYMBOL_GPL(rom_region_name); + /** * rom_type_name - name for the ROM type character in the ROMVER file in ROM0 * @type: &rom_ver.type type character. @@ -675,8 +693,8 @@ static int __init ps2_rom_init(void) rom1_dir = rom_dir_init("rom1", ROM1_BASE, ROM1_SIZE); v = rom_version(); - pr_info("rom0: Version %04x %c %s %04d-%02d-%02d\n", - v.number, v.region, rom_type_name(v.type), + pr_info("rom0: Version %04x %s %s %04d-%02d-%02d\n", + v.number, rom_region_name(v.region), rom_type_name(v.type), v.date.year, v.date.month, v.date.day); return 0; From patchwork Sun Sep 1 15:53:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125409 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3C3DA1395 for ; Sun, 1 Sep 2019 15:53:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 191FF2339D for ; Sun, 1 Sep 2019 15:53:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728888AbfIAPxL (ORCPT ); Sun, 1 Sep 2019 11:53:11 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:57956 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728616AbfIAPxL (ORCPT ); Sun, 1 Sep 2019 11:53:11 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id E9F46402D7 for ; Sun, 1 Sep 2019 17:53:09 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id P6C6akW_3F4u for ; Sun, 1 Sep 2019 17:53:09 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 3D35D3FBF6 for ; Sun, 1 Sep 2019 17:53:09 +0200 (CEST) Date: Sun, 1 Sep 2019 17:53:09 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 043/120] MIPS: PS2: ROM: Permit /dev/mem to access read-only memory Message-ID: <644f2908571adb1c66d27ab0ecb0c32a3f8581c9.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/io.h | 6 ++++++ arch/mips/ps2/memory.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index f7115472f530..f449a27c2b79 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -709,4 +709,10 @@ extern void (*_dma_cache_inv)(unsigned long start, unsigned long size); void __ioread64_copy(void *to, const void __iomem *from, size_t count); +#ifdef CONFIG_SONY_PS2 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE +extern int valid_phys_addr_range(phys_addr_t addr, size_t size); +extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); +#endif /* CONFIG_SONY_PS2 */ + #endif /* _ASM_IO_H */ diff --git a/arch/mips/ps2/memory.c b/arch/mips/ps2/memory.c index 66ca37f38330..c513b6912bb0 100644 --- a/arch/mips/ps2/memory.c +++ b/arch/mips/ps2/memory.c @@ -7,9 +7,25 @@ #include #include +#include #include #include +#include + +#include + +int valid_phys_addr_range(phys_addr_t addr, size_t size) +{ + return addr + size <= __pa(high_memory) || + (ROM0_BASE <= addr && addr + size <= ROM0_BASE + ROM0_SIZE) || + (ROM1_BASE <= addr && addr + size <= ROM1_BASE + ROM1_SIZE); +} + +int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) +{ + return 1; +} void __init plat_mem_setup(void) { From patchwork Sun Sep 1 15:53:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125411 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1A4401395 for ; Sun, 1 Sep 2019 15:53:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EC5332339D for ; Sun, 1 Sep 2019 15:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726727AbfIAPxq (ORCPT ); Sun, 1 Sep 2019 11:53:46 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:57100 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAPxq (ORCPT ); Sun, 1 Sep 2019 11:53:46 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id BDA2B3F73E for ; Sun, 1 Sep 2019 17:53:43 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DCh4GNNbdPxr for ; Sun, 1 Sep 2019 17:53:43 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id ECE743F708 for ; Sun, 1 Sep 2019 17:53:42 +0200 (CEST) Date: Sun, 1 Sep 2019 17:53:42 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 044/120] MIPS: PS2: ROM: Sysfs module to inspect ROM files Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The ROM sysfs module gives information on the ROM file names, sizes, and addresses. For example, listing all files of ROM0: # cat /sys/rom/rom0/file/*/name | column RESET VBLANK RMRESET MCSERV XSIFCMD ROMDIR IOMAN OSDVER PADMAN XCDVDMAN EXTINFO MODLOAD - CDVDMAN XCDVDFSV ROMVER ROMDRV IOPBOOT CDVDFSV XFILEIO SBIN ADDDRV OSDCNF FILEIO XSIO2MAN LOGO STDIO - CLEARSPU XMTAPMAN IOPBTCONF SIFMAN TBIN UDNL XMCMAN ... Viewing for example the contents of the ROM file ROMVER using /dev/mem: # grep -l ROMVER /sys/rom/rom0/file/*/name /sys/rom/rom0/file/3/name # cd /sys/rom/rom0/file/3 # dd if=/dev/mem bs=$(cat size) iflag=skip_bytes \ skip=$(( $(cat data) )) count=1 status=none 0170EC20030227 For convenience, the ROMVER file is also available directly in sysfs: # ls /sys/rom/rom0/version date number region type # cat /sys/rom/rom0/version/* 2003-02-27 0x0170 Europe CEX The CEX type indicates that it is a retail machine, as opposed to for example DEX that would be a debug machine. Signed-off-by: Fredrik Noring --- arch/mips/ps2/Makefile | 1 + arch/mips/ps2/rom-sysfs.c | 288 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 arch/mips/ps2/rom-sysfs.c diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index 1101ad0d702b..a56ea782120e 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -3,5 +3,6 @@ obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o obj-y += rom.o +obj-m += rom-sysfs.o obj-y += scmd.o obj-y += time.o diff --git a/arch/mips/ps2/rom-sysfs.c b/arch/mips/ps2/rom-sysfs.c new file mode 100644 index 000000000000..158d36763af5 --- /dev/null +++ b/arch/mips/ps2/rom-sysfs.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 read-only memory (ROM) sysfs + * + * Copyright (C) 2019 Fredrik Noring + * + * FIXME: Is /sys/rom the proper placement? + */ + +/// +// DOC: +// +// ROM0 and ROM1 contain simple file systems that can be inspected with this +// sysfs module. For example, listing all files of ROM0:: +// +// # cat /sys/rom/rom0/file/*/name | column +// RESET VBLANK RMRESET MCSERV XSIFCMD +// ROMDIR IOMAN OSDVER PADMAN XCDVDMAN +// EXTINFO MODLOAD - CDVDMAN XCDVDFSV +// ROMVER ROMDRV IOPBOOT CDVDFSV XFILEIO +// SBIN ADDDRV OSDCNF FILEIO XSIO2MAN +// LOGO STDIO - CLEARSPU XMTAPMAN +// IOPBTCONF SIFMAN TBIN UDNL XMCMAN +// ... +// +// Viewing for example the contents of the ROM file ROMVER using /dev/mem:: +// +// # grep -l ROMVER /sys/rom/rom0/file/*/name +// /sys/rom/rom0/file/3/name +// # cd /sys/rom/rom0/file/3 +// # dd if=/dev/mem bs=$(cat size) iflag=skip_bytes +// skip=$(( $(cat data) )) count=1 status=none +// 0170EC20030227 +// +// For convenience, the ROMVER file is also available directly in sysfs:: +// +// # ls /sys/rom/rom0/version +// date number region type +// # cat /sys/rom/rom0/version/* +// 2003-02-27 +// 0x0170 +// Europe +// CEX +// +// The CEX type indicates that it is a retail machine, as opposed to for +// example DEX that would be a debug machine. +// + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static int rom0_sysfs(struct kobject *romn_kobj); + +/* FIXME */ +static const struct { + const char *name; + const struct rom_dir *dir; + int (*func)(struct kobject *romn_kobj); +} rom_dirs[] = { + { "rom0", &rom0_dir, rom0_sysfs }, + { "rom1", &rom1_dir, NULL }, +}; + +static struct rom_dir rom_dir_from_kobj(const struct kobject *kobj) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(rom_dirs); i++) + if (strcmp(rom_dirs[i].name, kobj->parent->name) == 0) + return *rom_dirs[i].dir; + + pr_err("%s: ROM dir for \"%s\" does not exist\n", __func__, + kobj->parent->name); + + return (struct rom_dir) { }; +} + +static struct rom_file rom_file_from_kobj(const struct kobject *kobj) +{ + const size_t rom_id = simple_strtoull(kobj->name, NULL, 0); + const struct rom_dir dir = rom_dir_from_kobj(kobj->parent); + struct rom_file file; + size_t id = 0; + + rom_for_each_file(file, dir) + if (id++ == rom_id) + return file; + + pr_err("%s: ROM id %zu for \"%s\" does not exist\n", __func__, + rom_id, kobj->parent->name); + + return (struct rom_file) { .name = "" }; +} + +static ssize_t rom_version_number_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "0x%04x\n", rom_version().number); +} + +static ssize_t rom_version_region_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%s\n", + rom_region_name(rom_version().region)); +} + +static ssize_t rom_version_type_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%s\n", + rom_type_name(rom_version().type)); +} + +static ssize_t rom_version_date_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + const struct rom_ver v = rom_version(); + + return scnprintf(buf, PAGE_SIZE, "%04d-%02d-%02d\n", + v.date.year, v.date.month, v.date.day); +} + +static ssize_t rom_file_name_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%s\n", + rom_file_from_kobj(kobj).name); +} + +static ssize_t rom_file_size_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%zu\n", + rom_file_from_kobj(kobj).size); +} + +static ssize_t rom_file_data_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "0x%lx\n", + virt_to_phys(rom_file_from_kobj(kobj).data)); +} + +#define DEFINE_ROM_FIELD_ATTR(prefix, field) \ + static struct kobj_attribute rom_attribute_##prefix##_##field = \ + __ATTR(field, S_IRUGO, rom_##prefix##_##field##_show, NULL) + +DEFINE_ROM_FIELD_ATTR(version, number); +DEFINE_ROM_FIELD_ATTR(version, region); +DEFINE_ROM_FIELD_ATTR(version, type); +DEFINE_ROM_FIELD_ATTR(version, date); + +static struct attribute *rom_version_attributes[] = { + &rom_attribute_version_number.attr, + &rom_attribute_version_region.attr, + &rom_attribute_version_type.attr, + &rom_attribute_version_date.attr, + NULL +}; + +static struct attribute_group rom_version_attribute_group = { + .attrs = rom_version_attributes +}; + +DEFINE_ROM_FIELD_ATTR(file, name); +DEFINE_ROM_FIELD_ATTR(file, size); +DEFINE_ROM_FIELD_ATTR(file, data); + +static struct attribute *rom_file_attributes[] = { + &rom_attribute_file_name.attr, + &rom_attribute_file_size.attr, + &rom_attribute_file_data.attr, + NULL +}; + +static struct attribute_group rom_file_attribute_group = { + .attrs = rom_file_attributes +}; + +static int rom0_sysfs(struct kobject *rom0_kobj) +{ + struct kobject *version_kobj; + + version_kobj = kobject_create_and_add("version", rom0_kobj); + if (!version_kobj) + return -ENOMEM; + + return sysfs_create_group(version_kobj, &rom_version_attribute_group); +} + +static int __init rom_init_file(struct kobject *file_kobj, size_t index, + const struct rom_file file) +{ + struct kobject *index_kobj; + char index_string[20]; + int err; + + scnprintf(index_string, sizeof(index_string), "%zu", index); + + index_kobj = kobject_create_and_add(index_string, file_kobj); + if (!index_kobj) + return -ENOMEM; + + return sysfs_create_group(index_kobj, &rom_file_attribute_group); +} + +static int __init rom_init_dir(struct kobject *romn_kobj, + const struct rom_dir dir) +{ + struct kobject *file_kobj = kobject_create_and_add("file", romn_kobj); + struct rom_file file; + size_t i = 0; + + if (!file_kobj) + return -ENOMEM; + + rom_for_each_file(file, dir) { + int err = rom_init_file(file_kobj, i++, file); + + if (err) + return err; + } + + return 0; +} + +static int __init rom_init_rom(struct kobject *rom_kobj, + const char *name, const struct rom_dir dir, + int (*func)(struct kobject *romn_kobj)) +{ + struct kobject *romn_kobj = kobject_create_and_add(name, rom_kobj); + int err; + + if (!romn_kobj) + return -ENOMEM; + + err = rom_init_dir(romn_kobj, dir); + if (!err && func) + err = func(romn_kobj); + + return err; +} + +static struct kobject *rom_kobj; + +static int __init rom_sysfs_init(void) +{ + size_t i; + + rom_kobj = kobject_create_and_add("rom", NULL); + if (!rom_kobj) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(rom_dirs); i++) { + int err = rom_init_rom(rom_kobj, rom_dirs[i].name, + *rom_dirs[i].dir, rom_dirs[i].func); + + if (err) { + kobject_del(rom_kobj); + return err; + } + } + + return 0; +} + +static void __exit rom_sysfs_exit(void) +{ + kobject_del(rom_kobj); +} + +module_init(rom_sysfs_init); +module_exit(rom_sysfs_exit); + +MODULE_DESCRIPTION("PlayStation 2 read-only memory (ROM) sysfs"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:54:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125413 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A9FD112C for ; Sun, 1 Sep 2019 15:54:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E603E2339D for ; Sun, 1 Sep 2019 15:54:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726260AbfIAPyJ (ORCPT ); Sun, 1 Sep 2019 11:54:09 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:57174 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAPyJ (ORCPT ); Sun, 1 Sep 2019 11:54:09 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 997A13F73E for ; Sun, 1 Sep 2019 17:54:07 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aglGtmeKr8Fl for ; Sun, 1 Sep 2019 17:54:06 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id DAECF3F708 for ; Sun, 1 Sep 2019 17:54:06 +0200 (CEST) Date: Sun, 1 Sep 2019 17:54:06 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 045/120] MIPS: PS2: ROM: Provide extended file information via sysfs Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The extended ROM file information can be viewed with sysfs: # ls /sys/rom/rom0/file/8/extinfo comment data date size version # cat /sys/rom/rom0/file/8/extinfo/* System_Memory_Manager 0x1fc02df4 2002-04-03 40 0x0101 Signed-off-by: Fredrik Noring --- arch/mips/ps2/rom-sysfs.c | 104 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/arch/mips/ps2/rom-sysfs.c b/arch/mips/ps2/rom-sysfs.c index 158d36763af5..804644a931e8 100644 --- a/arch/mips/ps2/rom-sysfs.c +++ b/arch/mips/ps2/rom-sysfs.c @@ -28,6 +28,8 @@ // # grep -l ROMVER /sys/rom/rom0/file/*/name // /sys/rom/rom0/file/3/name // # cd /sys/rom/rom0/file/3 +// # ls +// data extinfo name size // # dd if=/dev/mem bs=$(cat size) iflag=skip_bytes // skip=$(( $(cat data) )) count=1 status=none // 0170EC20030227 @@ -45,6 +47,17 @@ // The CEX type indicates that it is a retail machine, as opposed to for // example DEX that would be a debug machine. // +// The extended ROM file information can also be viewed with sysfs:: +// +// # ls /sys/rom/rom0/file/8/extinfo +// comment data date size version +// # cat /sys/rom/rom0/file/8/extinfo/* +// System_Memory_Manager +// 0x1fc02df4 +// 2002-04-03 +// 40 +// 0x0101 +// #include #include @@ -102,6 +115,14 @@ static struct rom_file rom_file_from_kobj(const struct kobject *kobj) return (struct rom_file) { .name = "" }; } +static struct rom_extinfo rom_extinfo_from_kobj(const struct kobject *kobj) +{ + const struct rom_file file = rom_file_from_kobj(kobj->parent); + + return rom_read_extinfo(file.name, + file.extinfo.data, file.extinfo.size); +} + static ssize_t rom_version_number_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -131,6 +152,54 @@ static ssize_t rom_version_date_show(struct kobject *kobj, v.date.year, v.date.month, v.date.day); } +static ssize_t rom_extinfo_size_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%zu\n", + rom_file_from_kobj(kobj->parent).extinfo.size); +} + +static ssize_t rom_extinfo_data_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "0x%lx\n", + virt_to_phys(rom_file_from_kobj(kobj->parent).extinfo.data)); +} + +static ssize_t rom_extinfo_version_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + const struct rom_extinfo ei = rom_extinfo_from_kobj(kobj); + + if (!ei.version) + return 0; + + return scnprintf(buf, PAGE_SIZE, "0x%04x\n", ei.version); +} + +static ssize_t rom_extinfo_date_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + const struct rom_extinfo ei = rom_extinfo_from_kobj(kobj); + + if (!ei.date.year && !ei.date.month && !ei.date.day) + return 0; + + return scnprintf(buf, PAGE_SIZE, "%04d-%02d-%02d\n", + ei.date.year, ei.date.month, ei.date.day); +} + +static ssize_t rom_extinfo_comment_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + const struct rom_extinfo ei = rom_extinfo_from_kobj(kobj); + + if (ei.comment[0] == '\0') + return 0; + + return scnprintf(buf, PAGE_SIZE, "%s\n", ei.comment); +} + static ssize_t rom_file_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -173,6 +242,25 @@ static struct attribute_group rom_version_attribute_group = { .attrs = rom_version_attributes }; +DEFINE_ROM_FIELD_ATTR(extinfo, size); +DEFINE_ROM_FIELD_ATTR(extinfo, data); +DEFINE_ROM_FIELD_ATTR(extinfo, version); +DEFINE_ROM_FIELD_ATTR(extinfo, date); +DEFINE_ROM_FIELD_ATTR(extinfo, comment); + +static struct attribute *rom_extinfo_attributes[] = { + &rom_attribute_extinfo_size.attr, + &rom_attribute_extinfo_data.attr, + &rom_attribute_extinfo_version.attr, + &rom_attribute_extinfo_date.attr, + &rom_attribute_extinfo_comment.attr, + NULL +}; + +static struct attribute_group rom_extinfo_attribute_group = { + .attrs = rom_extinfo_attributes +}; + DEFINE_ROM_FIELD_ATTR(file, name); DEFINE_ROM_FIELD_ATTR(file, size); DEFINE_ROM_FIELD_ATTR(file, data); @@ -199,6 +287,18 @@ static int rom0_sysfs(struct kobject *rom0_kobj) return sysfs_create_group(version_kobj, &rom_version_attribute_group); } +static int __init rom_init_file_extinfo(struct kobject *index_kobj, + const struct rom_file file) +{ + struct kobject *extinfo_kobj; + + extinfo_kobj = kobject_create_and_add("extinfo", index_kobj); + if (!extinfo_kobj) + return -ENOMEM; + + return sysfs_create_group(extinfo_kobj, &rom_extinfo_attribute_group); +} + static int __init rom_init_file(struct kobject *file_kobj, size_t index, const struct rom_file file) { @@ -212,6 +312,10 @@ static int __init rom_init_file(struct kobject *file_kobj, size_t index, if (!index_kobj) return -ENOMEM; + err = rom_init_file_extinfo(index_kobj, file); + if (err) + return err; + return sysfs_create_group(index_kobj, &rom_file_attribute_group); } From patchwork Sun Sep 1 15:54:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125415 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 16D26112C for ; Sun, 1 Sep 2019 15:54:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F32CC233A2 for ; Sun, 1 Sep 2019 15:54:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726552AbfIAPyX (ORCPT ); Sun, 1 Sep 2019 11:54:23 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:42070 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAPyX (ORCPT ); Sun, 1 Sep 2019 11:54:23 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id ECA963F69D for ; Sun, 1 Sep 2019 17:54:21 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sy9hcjzcMVHU for ; Sun, 1 Sep 2019 17:54:21 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 4D07D3F695 for ; Sun, 1 Sep 2019 17:54:21 +0200 (CEST) Date: Sun, 1 Sep 2019 17:54:21 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 046/120] MIPS: PS2: Identify the machine by model name Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org ROM version 1.00 is always SCPH-10000. Later machines with ROM version 1.0x have the machine name in the ROM0 file OSDSYS at offset 0x8c808. These are late SCPH-10000 and all SCPH-15000. Even later machines have a system command (SCMD) to read the machine name. The machine name is shown in the /proc/cpuinfo file, for example: # grep machine /proc/cpuinfo machine : SCPH-37000 L Signed-off-by: Fredrik Noring --- arch/mips/ps2/Makefile | 1 + arch/mips/ps2/identify.c | 80 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 arch/mips/ps2/identify.c diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index a56ea782120e..b53bddcc8c01 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -1,4 +1,5 @@ obj-y += dmac-irq.o +obj-y += identify.o obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o diff --git a/arch/mips/ps2/identify.c b/arch/mips/ps2/identify.c new file mode 100644 index 000000000000..264fdc13dc43 --- /dev/null +++ b/arch/mips/ps2/identify.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 identification + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include + +#include + +#include +#include + +static int __init set_machine_name_by_scmd(void) +{ + const struct scmd_machine_name machine = scmd_read_machine_name(); + + if (machine.name[0] == '\0') { + pr_err("identify: %s: Reading failed\n", __func__); + return -EIO; + } + + mips_set_machine_name(machine.name); + + return 0; +} + +static int __init set_machine_name_by_osdsys(void) +{ + char name[12] = { }; + int err = rom_read_file(rom0_dir, "OSDSYS", + name, sizeof(name) - 1, 0x8c808); + + if (err) { + pr_err("identify: %s: Reading failed with %d\n", __func__, err); + return err; + } + + mips_set_machine_name(name); + + return 0; +} + +static void __init set_machine_name(void) +{ + const int rom_version_number = rom_version().number; + int err = 0; + + /* + * ROM version 1.00 is always SCPH-10000. Later machines with + * ROM version 1.0x have the machine name in the ROM0 file OSDSYS + * at offset 0x8c808. These are late SCPH-10000 and all SCPH-15000. + * Even later machines have a system command (SCMD) to read the + * machine name. + */ + + if (rom_version_number >= 0x110) + err = set_machine_name_by_scmd(); /* ver >= 1.10 */ + else if (rom_version_number > 0x100) + err = set_machine_name_by_osdsys(); /* 1.10 > ver > 1.00 */ + else if (rom_version_number == 0x100) + mips_set_machine_name("SCPH-10000"); /* ver = 1.00 */ + else + err = -ENODEV; + + if (err) + pr_err("identify: Determining machine name for ROM %04x failed with %d\n", + rom_version_number, err); +} + +static int __init ps2_identify_init(void) +{ + set_machine_name(); + + return 0; +} +subsys_initcall(ps2_identify_init); From patchwork Sun Sep 1 15:54:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125417 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 906F01395 for ; Sun, 1 Sep 2019 15:54:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6A1F4233A2 for ; Sun, 1 Sep 2019 15:54:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726121AbfIAPyn (ORCPT ); Sun, 1 Sep 2019 11:54:43 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:57196 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAPyn (ORCPT ); Sun, 1 Sep 2019 11:54:43 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 1B7EA3F73E for ; Sun, 1 Sep 2019 17:54:42 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wrS0PBGj-tZX for ; Sun, 1 Sep 2019 17:54:41 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 5C96B3F708 for ; Sun, 1 Sep 2019 17:54:41 +0200 (CEST) Date: Sun, 1 Sep 2019 17:54:41 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 047/120] MIPS: PS2: Let the system type be Sony PlayStation 2 Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The system type is shown in the /proc/cpuinfo file: # grep system' 'type /proc/cpuinfo system type : Sony PlayStation 2 Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- arch/mips/ps2/identify.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/mips/ps2/identify.c b/arch/mips/ps2/identify.c index 264fdc13dc43..579148fb79c4 100644 --- a/arch/mips/ps2/identify.c +++ b/arch/mips/ps2/identify.c @@ -9,11 +9,17 @@ #include #include +#include #include #include #include +const char *get_system_type(void) +{ + return "Sony PlayStation 2"; +} + static int __init set_machine_name_by_scmd(void) { const struct scmd_machine_name machine = scmd_read_machine_name(); From patchwork Sun Sep 1 15:55:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125419 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DC9161395 for ; Sun, 1 Sep 2019 15:55:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B03BC233A2 for ; Sun, 1 Sep 2019 15:55:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728496AbfIAPzT (ORCPT ); Sun, 1 Sep 2019 11:55:19 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58118 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAPzT (ORCPT ); Sun, 1 Sep 2019 11:55:19 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 7D7824036B for ; Sun, 1 Sep 2019 17:55:15 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QPxdjR66tP6B for ; Sun, 1 Sep 2019 17:55:14 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 881F63FC34 for ; Sun, 1 Sep 2019 17:55:14 +0200 (CEST) Date: Sun, 1 Sep 2019 17:55:14 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 048/120] MIPS: Define and use cpu_relax_forever() for various halting loops Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Using cpu_relax_forever() can lower processor energy consumption when halting indefinitely. Signed-off-by: Fredrik Noring --- arch/mips/alchemy/board-gpr.c | 7 +++---- arch/mips/alchemy/board-mtx1.c | 7 ++----- arch/mips/alchemy/board-xxs1500.c | 7 ++----- arch/mips/alchemy/devboards/platform.c | 4 ++-- arch/mips/ar7/setup.c | 4 ++-- arch/mips/ath79/setup.c | 8 +++----- arch/mips/bcm47xx/setup.c | 9 +++++---- arch/mips/bcm63xx/setup.c | 12 ++++++------ arch/mips/boot/compressed/decompress.c | 4 ++-- arch/mips/cavium-octeon/smp.c | 4 ++-- arch/mips/cobalt/reset.c | 5 +---- arch/mips/emma/markeins/setup.c | 5 +++-- arch/mips/fw/arc/init.c | 4 ++-- arch/mips/include/asm/processor.h | 6 ++++++ arch/mips/jz4740/reset.c | 9 ++------- arch/mips/loongson64/common/reset.c | 16 ++++------------ arch/mips/mm/cerr-sb1.c | 4 ++-- arch/mips/pic32/common/reset.c | 9 ++------- arch/mips/pnx833x/common/reset.c | 5 ++--- arch/mips/sgi-ip22/ip22-reset.c | 3 ++- arch/mips/sgi-ip27/ip27-berr.c | 4 ++-- arch/mips/sgi-ip27/ip27-reset.c | 13 ++++--------- arch/mips/sgi-ip32/ip32-berr.c | 4 ++-- arch/mips/sgi-ip32/ip32-irq.c | 3 ++- arch/mips/sibyte/common/cfe.c | 3 ++- arch/mips/txx9/rbtx4939/setup.c | 4 ++-- arch/mips/vr41xx/common/pmu.c | 2 +- 27 files changed, 70 insertions(+), 95 deletions(-) diff --git a/arch/mips/alchemy/board-gpr.c b/arch/mips/alchemy/board-gpr.c index 6c47318946e4..5247dfc1e0ed 100644 --- a/arch/mips/alchemy/board-gpr.c +++ b/arch/mips/alchemy/board-gpr.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -65,14 +66,12 @@ static void gpr_reset(char *c) alchemy_gpio_direction_output(1, 0); udelay(1); alchemy_gpio_set_value(1, 1); - while (1) - cpu_wait(); + cpu_relax_forever(); } static void gpr_power_off(void) { - while (1) - cpu_wait(); + cpu_relax_forever(); } void __init board_setup(void) diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 23093535399f..2025ba4ebfdd 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -60,11 +61,7 @@ static void mtx1_reset(char *c) static void mtx1_power_off(void) { - while (1) - asm volatile ( - " .set mips32 \n" - " wait \n" - " .set mips0 \n"); + cpu_relax_forever(); } void __init board_setup(void) diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c index c67dfe1f4997..6189efe70e65 100644 --- a/arch/mips/alchemy/board-xxs1500.c +++ b/arch/mips/alchemy/board-xxs1500.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -56,11 +57,7 @@ static void xxs1500_reset(char *c) static void xxs1500_power_off(void) { - while (1) - asm volatile ( - " .set mips32 \n" - " wait \n" - " .set mips0 \n"); + cpu_relax_forever(); } void __init board_setup(void) diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 8d4b65c3268a..2203fddc42d8 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -56,8 +57,7 @@ static void db1x_power_off(void) { bcsr_write(BCSR_RESETS, 0); bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET); - while (1) /* sit and spin */ - cpu_wait(); + cpu_relax_forever(); /* sit and spin */ } static void db1x_reset(char *c) diff --git a/arch/mips/ar7/setup.c b/arch/mips/ar7/setup.c index b3ffe7c898eb..2649ee848921 100644 --- a/arch/mips/ar7/setup.c +++ b/arch/mips/ar7/setup.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -21,8 +22,7 @@ static void ar7_machine_restart(char *command) static void ar7_machine_halt(void) { - while (1) - ; + cpu_relax_forever(); } static void ar7_machine_power_off(void) diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index ea385a865781..ad1d0fab5dad 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -24,6 +24,7 @@ #include /* for mips_hpt_frequency */ #include /* for _machine_{restart,halt} */ #include +#include #include #include @@ -39,15 +40,12 @@ static void ath79_restart(char *command) { local_irq_disable(); ath79_device_reset_set(AR71XX_RESET_FULL_CHIP); - for (;;) - if (cpu_wait) - cpu_wait(); + cpu_relax_forever(); } static void ath79_halt(void) { - while (1) - cpu_wait(); + cpu_relax_forever(); } static void __init ath79_detect_sys_type(void) diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 82627c264964..7ae2462ff3ae 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -77,8 +78,8 @@ static void bcm47xx_machine_restart(char *command) break; #endif } - while (1) - cpu_relax(); + + cpu_relax_forever(); } static void bcm47xx_machine_halt(void) @@ -97,8 +98,8 @@ static void bcm47xx_machine_halt(void) break; #endif } - while (1) - cpu_relax(); + + cpu_relax_forever(); } #ifdef CONFIG_BCM47XX_SSB diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index e28ee9a7cc7e..342ca32c0ae2 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,8 +26,8 @@ void bcm63xx_machine_halt(void) { pr_info("System halted\n"); - while (1) - ; + + cpu_relax_forever(); } static void bcm6348_a1_reboot(void) @@ -58,8 +59,8 @@ static void bcm6348_a1_reboot(void) "jr\t%0" : : "r" (0xbfc00000)); - while (1) - ; + + cpu_relax_forever(); } void bcm63xx_machine_reboot(void) @@ -118,8 +119,7 @@ void bcm63xx_machine_reboot(void) reg |= SYS_PLL_SOFT_RESET; bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG); } - while (1) - ; + cpu_relax_forever(); } static void __bcm63xx_machine_reboot(char *p) diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index 88f5d637b1c4..27e9c13614ee 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -13,6 +13,7 @@ #include #include +#include /* * These two variables specify the free mem region @@ -41,8 +42,7 @@ void error(char *x) puts(x); puts("\n\n -- System halted"); - while (1) - ; /* Halt */ + cpu_relax_forever(); /* Halt */ } /* activate the code for pre-boot environment */ diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 076db9a06b5e..cb397b413967 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -354,8 +355,7 @@ void play_dead(void) mb(); - while (1) /* core will be reset here */ - ; + cpu_relax_forever(); /* core will be reset here */ } static void start_after_reset(void) diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c index 4eedd481dd00..13f67197193a 100644 --- a/arch/mips/cobalt/reset.c +++ b/arch/mips/cobalt/reset.c @@ -37,10 +37,7 @@ void cobalt_machine_halt(void) led_trigger_event(power_off_led_trigger, LED_FULL); local_irq_disable(); - while (1) { - if (cpu_wait) - cpu_wait(); - } + cpu_relax_forever(); } void cobalt_machine_restart(char *command) diff --git a/arch/mips/emma/markeins/setup.c b/arch/mips/emma/markeins/setup.c index c8a91c2a63bc..c12e4e6ceb76 100644 --- a/arch/mips/emma/markeins/setup.c +++ b/arch/mips/emma/markeins/setup.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -34,13 +35,13 @@ static void markeins_machine_halt(void) { printk("EMMA2RH Mark-eins halted.\n"); markeins_led("halted."); - while (1) ; + cpu_relax_forever(); } static void markeins_machine_power_off(void) { markeins_led("poweroff."); - while (1) ; + cpu_relax_forever(); } static unsigned long __initdata emma2rh_clock[4] = { diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c index 008555969534..90fa8ed75a50 100644 --- a/arch/mips/fw/arc/init.c +++ b/arch/mips/fw/arc/init.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -34,8 +35,7 @@ void __init prom_init(void) if (pb->magic != 0x53435241) { printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n", (unsigned long) pb->magic); - while(1) - ; + cpu_relax_forever(); } prom_init_cmdline(); diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index aca909bd7841..e1e4cb7833a6 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -405,6 +405,12 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() #endif +static inline void __noreturn cpu_relax_forever(void) +{ + for (;;) + cpu_relax(); +} + /* * Return_address is a replacement for __builtin_return_address(count) * which on certain architectures cannot reasonably be implemented in GCC diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c index 1f9f02e54085..c6703d32edb9 100644 --- a/arch/mips/jz4740/reset.c +++ b/arch/mips/jz4740/reset.c @@ -3,19 +3,14 @@ * Copyright (C) 2010, Lars-Peter Clausen */ +#include #include #include "reset.h" static void jz4740_halt(void) { - while (1) { - __asm__(".set push;\n" - ".set mips3;\n" - "wait;\n" - ".set pop;\n" - ); - } + cpu_relax_forever(); } void jz4740_reset_init(void) diff --git a/arch/mips/loongson64/common/reset.c b/arch/mips/loongson64/common/reset.c index ce39e918e4d5..e91137922373 100644 --- a/arch/mips/loongson64/common/reset.c +++ b/arch/mips/loongson64/common/reset.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -45,10 +46,7 @@ static void loongson_restart(char *command) void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr; fw_restart(); - while (1) { - if (cpu_wait) - cpu_wait(); - } + cpu_relax_forever(); #endif } @@ -66,20 +64,14 @@ static void loongson_poweroff(void) void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; fw_poweroff(); - while (1) { - if (cpu_wait) - cpu_wait(); - } + cpu_relax_forever(); #endif } static void loongson_halt(void) { pr_notice("\n\n** You can safely turn off the power now **\n\n"); - while (1) { - if (cpu_wait) - cpu_wait(); - } + cpu_relax_forever(); } static int __init mips_reboot_setup(void) diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c index a3c02df19f6f..c0a6acea532c 100644 --- a/arch/mips/mm/cerr-sb1.c +++ b/arch/mips/mm/cerr-sb1.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include @@ -244,8 +245,7 @@ asmlinkage void sb1_cache_error(void) * undesirable. */ #ifdef CONFIG_SB1_CERR_STALL - while (1) - ; + cpu_relax_forever(); #else panic("unhandled cache error"); #endif diff --git a/arch/mips/pic32/common/reset.c b/arch/mips/pic32/common/reset.c index a5fd7a8e2800..32dcda98aa15 100644 --- a/arch/mips/pic32/common/reset.c +++ b/arch/mips/pic32/common/reset.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #include @@ -12,13 +13,7 @@ static void pic32_halt(void) { - while (1) { - __asm__(".set push;\n" - ".set arch=r4000;\n" - "wait;\n" - ".set pop;\n" - ); - } + cpu_relax_forever(); } static void pic32_machine_restart(char *command) diff --git a/arch/mips/pnx833x/common/reset.c b/arch/mips/pnx833x/common/reset.c index b48e83bf912b..8f8b79994dae 100644 --- a/arch/mips/pnx833x/common/reset.c +++ b/arch/mips/pnx833x/common/reset.c @@ -10,6 +10,7 @@ * Nikita Youshchenko , based on PNX8550 code. */ #include +#include #include void pnx833x_machine_restart(char *command) @@ -20,9 +21,7 @@ void pnx833x_machine_restart(char *command) void pnx833x_machine_halt(void) { - while (1) - __asm__ __volatile__ ("wait"); - + cpu_relax_forever(); } void pnx833x_machine_power_off(void) diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index c374f3ceec38..5355c96a2b89 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -72,7 +73,7 @@ static void __noreturn sgi_machine_restart(char *command) if (machine_state & MACHINE_SHUTTING_DOWN) sgi_machine_power_off(); sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT; - while (1); + cpu_relax_forever(); } static void __noreturn sgi_machine_halt(void) diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c index 73ad29b180fb..81cd434cb9ae 100644 --- a/arch/mips/sgi-ip27/ip27-berr.c +++ b/arch/mips/sgi-ip27/ip27-berr.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -73,8 +74,7 @@ int ip27_be_handler(struct pt_regs *regs, int is_fixup) dump_hub_information(errst0, errst1); show_regs(regs); dump_tlb_all(); - while(1); - force_sig(SIGBUS); + cpu_relax_forever(); } void __init ip27_be_init(void) diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c index e44a15d4f573..bc8c2507ba91 100644 --- a/arch/mips/sgi-ip27/ip27-reset.c +++ b/arch/mips/sgi-ip27/ip27-reset.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -26,12 +27,6 @@ #include #include -void machine_restart(char *command) __noreturn; -void machine_halt(void) __noreturn; -void machine_power_off(void) __noreturn; - -#define noreturn while(1); /* Silence gcc. */ - /* XXX How to pass the reboot command to the firmware??? */ static void ip27_machine_restart(char *command) { @@ -50,7 +45,7 @@ static void ip27_machine_restart(char *command) #else LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); #endif - noreturn; + cpu_relax_forever(); } static void ip27_machine_halt(void) @@ -64,13 +59,13 @@ static void ip27_machine_halt(void) REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, PROMOP_RESTART); LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); - noreturn; + cpu_relax_forever(); } static void ip27_machine_power_off(void) { /* To do ... */ - noreturn; + cpu_relax_forever(); } void ip27_reboot_setup(void) diff --git a/arch/mips/sgi-ip32/ip32-berr.c b/arch/mips/sgi-ip32/ip32-berr.c index c860f95ab7ed..daa2036aeecc 100644 --- a/arch/mips/sgi-ip32/ip32-berr.c +++ b/arch/mips/sgi-ip32/ip32-berr.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -28,8 +29,7 @@ static int ip32_be_handler(struct pt_regs *regs, int is_fixup) printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc); show_regs(regs); dump_tlb_all(); - while(1); - force_sig(SIGBUS); + cpu_relax_forever(); } void __init ip32_be_init(void) diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index a6a0ff7f5aed..d34a6b4f2096 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -355,7 +356,7 @@ static void ip32_unknown_interrupt(void) printk("Please mail this report to linux-mips@linux-mips.org\n"); printk("Spinning..."); - while(1) ; + cpu_relax_forever(); } /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index cbf5939ed53a..33143172a644 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -65,7 +66,7 @@ static void __noreturn cfe_linux_exit(void *arg) cfe_exit(warm, 0); printk("cfe_exit returned??\n"); } - while (1); + cpu_relax_forever(); } static void __noreturn cfe_linux_restart(char *command) diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index ef29a9c2ffd6..ec32d8a63d2e 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -31,8 +32,7 @@ static void rbtx4939_machine_restart(char *command) local_irq_disable(); writeb(1, rbtx4939_reseten_addr); writeb(1, rbtx4939_softreset_addr); - while (1) - ; + cpu_relax_forever(); } static void __init rbtx4939_time_init(void) diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index 93cc7e0b30b1..d73178e3d910 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c @@ -72,7 +72,7 @@ static void vr41xx_restart(char *command) { local_irq_disable(); software_reset(); - while (1) ; + cpu_relax_forever(); } static void vr41xx_halt(void) From patchwork Sun Sep 1 15:55:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125421 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 56F87112C for ; Sun, 1 Sep 2019 15:55:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3F888233A2 for ; Sun, 1 Sep 2019 15:55:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728616AbfIAPzf (ORCPT ); Sun, 1 Sep 2019 11:55:35 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:42214 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAPze (ORCPT ); Sun, 1 Sep 2019 11:55:34 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id D18843F684 for ; Sun, 1 Sep 2019 17:55:33 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bH-CMv7QFr-n for ; Sun, 1 Sep 2019 17:55:33 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 356073F615 for ; Sun, 1 Sep 2019 17:55:33 +0200 (CEST) Date: Sun, 1 Sep 2019 17:55:33 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 049/120] MIPS: PS2: Power off support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/ps2/Makefile | 1 + arch/mips/ps2/reboot.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 arch/mips/ps2/reboot.c diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index b53bddcc8c01..6f671112fbcb 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -3,6 +3,7 @@ obj-y += identify.o obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o +obj-y += reboot.o obj-y += rom.o obj-m += rom-sysfs.o obj-y += scmd.o diff --git a/arch/mips/ps2/reboot.c b/arch/mips/ps2/reboot.c new file mode 100644 index 000000000000..b2a3ada5268b --- /dev/null +++ b/arch/mips/ps2/reboot.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 power off + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include + +#include +#include + +#include + +static void __noreturn power_off(void) +{ + scmd_power_off(); + + cpu_relax_forever(); +} + +static int __init ps2_init_reboot(void) +{ + pm_power_off = power_off; + + return 0; +} +subsys_initcall(ps2_init_reboot); From patchwork Sun Sep 1 15:55:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125423 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DE622112C for ; Sun, 1 Sep 2019 15:55:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C5F10233A2 for ; Sun, 1 Sep 2019 15:55:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726727AbfIAPz6 (ORCPT ); Sun, 1 Sep 2019 11:55:58 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:42238 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAPz6 (ORCPT ); Sun, 1 Sep 2019 11:55:58 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 25CB73F684 for ; Sun, 1 Sep 2019 17:55:56 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GdxM6S8gdZkF for ; Sun, 1 Sep 2019 17:55:55 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 723A03F615 for ; Sun, 1 Sep 2019 17:55:55 +0200 (CEST) Date: Sun, 1 Sep 2019 17:55:55 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 050/120] MIPS: PS2: Real-time clock (RTC) driver Message-ID: <989f3074c2a336889842012bc806b967eb8ec009.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- drivers/rtc/Kconfig | 10 ++++++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-ps2.c | 74 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 drivers/rtc/rtc-ps2.c diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e72f65b61176..aaac22576a26 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1896,4 +1896,14 @@ config RTC_DRV_WILCO_EC This can also be built as a module. If so, the module will be named "rtc_wilco_ec". +config RTC_DRV_PS2 + tristate "PlayStation 2 RTC" + depends on SONY_PS2 + default y + help + Say yes here to get support for the PlayStation 2 real-time clock. + + This driver can also be built as a module. If so, the module + will be called rtc-ps2. + endif # RTC_CLASS diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6b09c21dc1b6..5bc300f1040a 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -130,6 +130,7 @@ obj-$(CONFIG_RTC_DRV_PIC32) += rtc-pic32.o obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o obj-$(CONFIG_RTC_DRV_PM8XXX) += rtc-pm8xxx.o +obj-$(CONFIG_RTC_DRV_PS2) += rtc-ps2.o obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o diff --git a/drivers/rtc/rtc-ps2.c b/drivers/rtc/rtc-ps2.c new file mode 100644 index 000000000000..d0c732a052df --- /dev/null +++ b/drivers/rtc/rtc-ps2.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 real-time clock (RTC) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include + +#include "asm/mach-ps2/scmd.h" + +#define DRVNAME "rtc-ps2" + +static int read_time(struct device *dev, struct rtc_time *tm) +{ + time64_t t; + int err = scmd_read_rtc(&t); + + if (!err) + rtc_time64_to_tm(t, tm); + + return err; +} + +static int set_time(struct device *dev, struct rtc_time *tm) +{ + return scmd_set_rtc(rtc_tm_to_time64(tm)); +} + +static const struct rtc_class_ops ps2_rtc_ops = { + .read_time = read_time, + .set_time = set_time, +}; + +static int ps2_rtc_probe(struct platform_device *pdev) +{ + struct rtc_device *rtc; + + rtc = devm_rtc_device_register(&pdev->dev, + DRVNAME, &ps2_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + rtc->uie_unsupported = 1; + + return 0; +} + +static struct platform_driver ps2_rtc_driver = { + .probe = ps2_rtc_probe, + .driver = { + .name = DRVNAME, + }, +}; + +static int __init ps2_rtc_init(void) +{ + return platform_driver_register(&ps2_rtc_driver); +} + +static void __exit ps2_rtc_exit(void) +{ + platform_driver_unregister(&ps2_rtc_driver); +} + +module_init(ps2_rtc_init); +module_exit(ps2_rtc_exit); + +MODULE_DESCRIPTION("PlayStation 2 real-time clock (RTC)"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:56:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125425 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D250D1395 for ; Sun, 1 Sep 2019 15:56:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B89F8233A2 for ; Sun, 1 Sep 2019 15:56:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728654AbfIAP42 (ORCPT ); Sun, 1 Sep 2019 11:56:28 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58208 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728644AbfIAP42 (ORCPT ); Sun, 1 Sep 2019 11:56:28 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id D0EC1402D7 for ; Sun, 1 Sep 2019 17:56:25 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PwB4B-iIvV_b for ; Sun, 1 Sep 2019 17:56:25 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 2A5B43FC34 for ; Sun, 1 Sep 2019 17:56:25 +0200 (CEST) Date: Sun, 1 Sep 2019 17:56:24 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 051/120] MIPS: PS2: IOP: I/O processor DMA register PCR2 set and clear Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- The documentation for the DEV9 is rather poor, unfortunately. --- .../mips/include/asm/mach-ps2/iop-registers.h | 19 +++++++++ drivers/ps2/Makefile | 1 + drivers/ps2/iop-registers.c | 39 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/iop-registers.h create mode 100644 drivers/ps2/Makefile create mode 100644 drivers/ps2/iop-registers.c diff --git a/arch/mips/include/asm/mach-ps2/iop-registers.h b/arch/mips/include/asm/mach-ps2/iop-registers.h new file mode 100644 index 000000000000..b4db423150de --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/iop-registers.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 I/O processor (IOP) registers + * + * Copyright (C) 2017-2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_IOP_REGISTERS_H +#define __ASM_MACH_PS2_IOP_REGISTERS_H + +#include + +#define IOP_DMA_DPCR2_OHCI 0x08000000 /* USB OHCI */ +#define IOP_DMA_DPCR2_DEV9 0x00000080 /* DEV9 (Expansion Bay, USB) */ + +void iop_set_dma_dpcr2(const u32 mask); +void iop_clr_dma_dpcr2(const u32 mask); + +#endif /* __ASM_MACH_PS2_IOP_REGISTERS_H */ diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile new file mode 100644 index 000000000000..e53976ddb3e4 --- /dev/null +++ b/drivers/ps2/Makefile @@ -0,0 +1 @@ +obj-m += iop-registers.o diff --git a/drivers/ps2/iop-registers.c b/drivers/ps2/iop-registers.c new file mode 100644 index 000000000000..0ea7603b91a3 --- /dev/null +++ b/drivers/ps2/iop-registers.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 I/O processor (IOP) registers + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include + +#include + +#include + +#define IOP_DMA_DPCR2 0x1f801570 + +static DEFINE_SPINLOCK(reg_lock); + +void iop_set_dma_dpcr2(const u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(®_lock, flags); + outl(inl(IOP_DMA_DPCR2) | mask, IOP_DMA_DPCR2); + spin_unlock_irqrestore(®_lock, flags); +} +EXPORT_SYMBOL_GPL(iop_set_dma_dpcr2); + +void iop_clr_dma_dpcr2(const u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(®_lock, flags); + outl(inl(IOP_DMA_DPCR2) & ~mask, IOP_DMA_DPCR2); + spin_unlock_irqrestore(®_lock, flags); +} +EXPORT_SYMBOL_GPL(iop_clr_dma_dpcr2); + +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:57:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125427 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 343341395 for ; Sun, 1 Sep 2019 15:57:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0915C233A2 for ; Sun, 1 Sep 2019 15:57:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726260AbfIAP5S (ORCPT ); Sun, 1 Sep 2019 11:57:18 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58288 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAP5S (ORCPT ); Sun, 1 Sep 2019 11:57:18 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id B502C402D7 for ; Sun, 1 Sep 2019 17:57:14 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3AJvnQ-zMmvQ for ; Sun, 1 Sep 2019 17:57:13 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id D5A863FC34 for ; Sun, 1 Sep 2019 17:57:13 +0200 (CEST) Date: Sun, 1 Sep 2019 17:57:12 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 052/120] MIPS: PS2: SIF: Sub-system interface reset of the I/O processor (IOP) Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The sub-system interface (SIF) is the interface to exchange data between the sub (input/output) processor (IOP) and the main (R5900) processor and other devices connected to the main bus[1]. The IOP handles, in whole or in part, most of the peripheral devices, including for example USB OHCI interrupts. DMA controllers (DMACs) for the IOP and the R5900 operate in cooperation through a bidirectional FIFO in the SIF. There are three DMA channels: SIF0 (sub-to-main), SIF1 (main-to-sub) and SIF2 (bidirectional). Data is transferred in packets with a tag attached to each packet. The tag contains the memory addresses in the IOP and R5900 address spaces and the size of the data to transfer. There are two mailbox type registers, the SMFLAG (sub-to-main) and MSFLAG (main-to-sub), used to indicate certain events. The MAINADDR and SUBADDR registers indicate the R5900 and IOP addresses where SIF commands are transferred by the DMAC. The IOP can assert interrupts via IRQ_INTC_SBUS. This SIF kernel module resets the IOP during initialisation. The IOP follows a certain boot protocol, with the following steps: 1. The kernel allocates a DMA memory buffer that the IOP can use to send commands. The kernel advertises this buffer by writing to the MAINADDR register. 2. The kernel reads the provisional SUBADDR register to obtain the corresponding command buffer for the IOP. 3. The kernel clears the SIF_STATUS_BOOTEND flag in the SMFLAG register. 4. The kernel issues the SIF_CMD_RESET_CMD command to the IOP. 5. The kernel indicates that the SIF and system commands are ready by setting the SIF_STATUS_SIFINIT and SIF_STATUS_CMDINIT flags in the SMFLAG register. 6. The kernel waits for the IOP to set the SIF_STATUS_BOOTEND flag in the SMFLAG register. 7. The kernel indicates that the boot is completed by writing updating its MAINADDR and setting the SIF_STATUS_CMDINIT and SIF_STATUS_BOOTEND flags in the MSFLAG register. The SIF_UNKNF260 register is set to 0xff. 8. The kernel reads the final SUBADDR register to obtain the command buffer for the IOP. References: [1] "EE Overview", version 6.0, Sony Computer Entertainment Inc., p. 47. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/sif.h | 72 +++++ drivers/ps2/Makefile | 1 + drivers/ps2/sif.c | 414 +++++++++++++++++++++++++++ 3 files changed, 487 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/sif.h create mode 100644 drivers/ps2/sif.c diff --git a/arch/mips/include/asm/mach-ps2/sif.h b/arch/mips/include/asm/mach-ps2/sif.h new file mode 100644 index 000000000000..94da96bd21d1 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/sif.h @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 sub-system interface (SIF) + * + * The SIF is an interface unit to the input/output processor (IOP). + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_SIF_H +#define __ASM_MACH_PS2_SIF_H + +#include +#include + +#include "iop-memory.h" + +#define SIF_MAINADDR 0x1000f200 /* EE to IOP command buffer */ +#define SIF_SUBADDR 0x1000f210 /* IOP to EE command buffer */ +#define SIF_MSFLAG 0x1000f220 /* EE to IOP flag */ +#define SIF_SMFLAG 0x1000f230 /* IOP to EE flag */ +#define SIF_SUBCTRL 0x1000f240 +#define SIF_UNKNF260 0x1000f260 + +/* Status flags for the sub-to-main (SM) and main-to-sub (MS) SIF registers. */ +#define SIF_STATUS_SIFINIT 0x10000 /* SIF initialised */ +#define SIF_STATUS_CMDINIT 0x20000 /* SIF CMD initialised */ +#define SIF_STATUS_BOOTEND 0x40000 /* IOP bootup completed */ + +#define SIF_CMD_ID_SYS 0x80000000 +#define SIF_CMD_ID_USR 0x00000000 + +#define SIF_CMD_CHANGE_SADDR (SIF_CMD_ID_SYS | 0x00) +#define SIF_CMD_WRITE_SREG (SIF_CMD_ID_SYS | 0x01) +#define SIF_CMD_INIT_CMD (SIF_CMD_ID_SYS | 0x02) +#define SIF_CMD_RESET_CMD (SIF_CMD_ID_SYS | 0x03) +#define SIF_CMD_RPC_END (SIF_CMD_ID_SYS | 0x08) +#define SIF_CMD_RPC_BIND (SIF_CMD_ID_SYS | 0x09) +#define SIF_CMD_RPC_CALL (SIF_CMD_ID_SYS | 0x0a) +#define SIF_CMD_RPC_RDATA (SIF_CMD_ID_SYS | 0x0c) +#define SIF_CMD_IRQ_RELAY (SIF_CMD_ID_SYS | 0x20) +#define SIF_CMD_PRINTK (SIF_CMD_ID_SYS | 0x21) + +#define SIF_SID_ID_SYS 0x80000000 +#define SIF_SID_ID_USR 0x00000000 + +#define SIF_SID_FILE_IO (SIF_SID_ID_SYS | 0x01) +#define SIF_SID_HEAP (SIF_SID_ID_SYS | 0x03) +#define SIF_SID_LOAD_MODULE (SIF_SID_ID_SYS | 0x06) +#define SIF_SID_IRQ_RELAY (SIF_SID_ID_SYS | 0x20) + +#define SIF_CMD_PACKET_MAX 112 +#define SIF_CMD_PACKET_DATA_MAX 96 + +/** + * struct sif_cmd_header - 16-byte SIF command header + * @packet_size: min 1x16 for header only, max 7*16 bytes + * @data_size: data size in bytes + * @data_addr: data address or zero + * @cmd: command number + * @opt: optional argument + */ +struct sif_cmd_header +{ + u32 packet_size : 8; + u32 data_size : 24; + u32 data_addr; + u32 cmd; + u32 opt; +}; + +#endif /* __ASM_MACH_PS2_SIF_H */ diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index e53976ddb3e4..ef561a802bdd 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1 +1,2 @@ obj-m += iop-registers.o +obj-m += sif.o diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c new file mode 100644 index 000000000000..6564af245880 --- /dev/null +++ b/drivers/ps2/sif.c @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 sub-system interface (SIF) + * + * Copyright (C) 2019 Fredrik Noring + */ + +/** + * DOC: The sub-system interface (SIF) for the input/output processor (IOP) + * + * The SIF is the interface to exchange data between the sub (input/output) + * processor (IOP) and the main (R5900) processor and other devices connected + * to the main bus. The IOP handles, in whole or in part, most of the + * peripheral devices, including for example USB OHCI interrupts. + * + * DMA controllers (DMACs) for the IOP and the R5900 operate in cooperation + * through a bidirectional FIFO in the SIF. There are three DMA channels: + * SIF0 (sub-to-main), SIF1 (main-to-sub) and SIF2 (bidirectional). + * + * Data is transferred in packets with a tag attached to each packet. The + * tag contains the memory addresses in the IOP and R5900 address spaces + * and the size of the data to transfer. + * + * There are two mailbox type registers, the SMFLAG (sub-to-main) and + * MSFLAG (main-to-sub), used to indicate certain events. The MAINADDR + * and SUBADDR registers indicate the R5900 and IOP addresses where SIF + * commands are transferred by the DMAC. + * + * The IOP can assert interrupts via %IRQ_INTC_SBUS. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define IOP_RESET_ARGS "rom0:UDNL rom0:OSDCNF" + +#define SIF0_BUFFER_SIZE PAGE_SIZE +#define SIF1_BUFFER_SIZE PAGE_SIZE + +static iop_addr_t iop_buffer; /* Address of IOP SIF DMA receive address */ +static void *sif0_buffer; +static void *sif1_buffer; + +/** + * sif_write_msflag - write to set main-to-sub flag register bits + * @mask: MSFLAG register bit values to set + */ +static void sif_write_msflag(u32 mask) +{ + outl(mask, SIF_MSFLAG); +} + +/** + * sif_write_smflag - write to clear sub-to-main flag register bits + * @mask: SMFLAG register bit values to clear + */ +static void sif_write_smflag(u32 mask) +{ + outl(mask, SIF_SMFLAG); +} + +/** + * sif_read_smflag - read the sub-to-main flag register + * + * Return: SMFLAG register value + */ +static u32 sif_read_smflag(void) +{ + u32 a = inl(SIF_SMFLAG); + u32 b; + + do { + b = a; + + a = inl(SIF_SMFLAG); + } while (a != b); /* Ensure SMFLAG reading is stable */ + + return a; +} + +static bool completed(bool (*condition)(void)) +{ + const unsigned long timeout = jiffies + 5*HZ; + + do { + if (condition()) + return true; + + msleep(1); + } while (time_is_after_jiffies(timeout)); + + return false; +} + +static bool sif_smflag_cmdinit(void) +{ + return (sif_read_smflag() & SIF_STATUS_CMDINIT) != 0; +} + +static bool sif_smflag_bootend(void) +{ + return (sif_read_smflag() & SIF_STATUS_BOOTEND) != 0; +} + +static bool sif1_busy(void) +{ + return (inl(DMAC_SIF1_CHCR) & DMAC_CHCR_BUSY) != 0; +} + +static bool sif1_ready(void) +{ + size_t countout = 50000; /* About 5 s */ + + while (sif1_busy() && countout > 0) { + udelay(100); + countout--; + } + + return countout > 0; +} + +/* Bytes to 32-bit word count. */ +static u32 nbytes_to_wc(size_t nbytes) +{ + const u32 wc = nbytes / 4; + + BUG_ON(nbytes & 0x3); /* Word count must align */ + BUG_ON(nbytes != (size_t)wc * 4); + + return wc; +} + +/* Bytes to 128-bit quadword count. */ +static u32 nbytes_to_qwc(size_t nbytes) +{ + const size_t qwc = nbytes / 16; + + BUG_ON(nbytes & 0xf); /* Quadword count must align */ + BUG_ON(qwc > 0xffff); /* QWC DMA field is only 16 bits */ + + return qwc; +} + +static int sif1_write_ert_int_0(const struct sif_cmd_header *header, + bool ert, bool int_0, iop_addr_t dst, const void *src, size_t nbytes) +{ + const size_t header_size = header != NULL ? sizeof(*header) : 0; + const size_t aligned_size = ALIGN(header_size + nbytes, 16); + const struct iop_dma_tag iop_dma_tag = { + .ert = ert, + .int_0 = int_0, + .addr = dst, + .wc = nbytes_to_wc(aligned_size) + }; + const size_t dma_nbytes = sizeof(iop_dma_tag) + aligned_size; + u8 *dma_buffer = sif1_buffer; + dma_addr_t madr; + + if (!aligned_size) + return 0; + if (dma_nbytes > SIF1_BUFFER_SIZE) + return -EINVAL; + if (!sif1_ready()) + return -EBUSY; + + memcpy(&dma_buffer[0], &iop_dma_tag, sizeof(iop_dma_tag)); + memcpy(&dma_buffer[sizeof(iop_dma_tag)], header, header_size); + memcpy(&dma_buffer[sizeof(iop_dma_tag) + header_size], src, nbytes); + + madr = virt_to_phys(dma_buffer); + dma_cache_wback((unsigned long)dma_buffer, dma_nbytes); + + outl(madr, DMAC_SIF1_MADR); + outl(nbytes_to_qwc(dma_nbytes), DMAC_SIF1_QWC); + outl(DMAC_CHCR_SENDN_TIE, DMAC_SIF1_CHCR); + + return 0; +} + +static int sif1_write(const struct sif_cmd_header *header, + iop_addr_t dst, const void *src, size_t nbytes) +{ + return sif1_write_ert_int_0(header, false, false, dst, src, nbytes); +} + +static int sif1_write_irq(const struct sif_cmd_header *header, + iop_addr_t dst, const void *src, size_t nbytes) +{ + return sif1_write_ert_int_0(header, true, true, dst, src, nbytes); +} + +static int sif_cmd_opt_copy(u32 cmd_id, u32 opt, const void *pkt, + size_t pktsize, iop_addr_t dst, const void *src, size_t nbytes) +{ + const struct sif_cmd_header header = { + .packet_size = sizeof(header) + pktsize, + .data_size = nbytes, + .data_addr = dst, + .cmd = cmd_id, + .opt = opt + }; + int err; + + if (pktsize > SIF_CMD_PACKET_DATA_MAX) + return -EINVAL; + + err = sif1_write(NULL, dst, src, nbytes); + if (!err) + err = sif1_write_irq(&header, iop_buffer, pkt, pktsize); + + return err; +} + +static int sif_cmd_copy(u32 cmd_id, const void *pkt, size_t pktsize, + iop_addr_t dst, const void *src, size_t nbytes) +{ + return sif_cmd_opt_copy(cmd_id, 0, pkt, pktsize, dst, src, nbytes); +} + +static int sif_cmd(u32 cmd_id, const void *pkt, size_t pktsize) +{ + return sif_cmd_copy(cmd_id, pkt, pktsize, 0, NULL, 0); +} + +static int iop_reset_arg(const char *arg) +{ + const size_t arglen = strlen(arg) + 1; + struct { + u32 arglen; + u32 mode; + char arg[79 + 1]; /* Including NUL */ + } reset_pkt = { + .arglen = arglen, + .mode = 0 + }; + int err; + + if (arglen > sizeof(reset_pkt.arg)) + return -EINVAL; + memcpy(reset_pkt.arg, arg, arglen); + + sif_write_smflag(SIF_STATUS_BOOTEND); + + err = sif_cmd(SIF_CMD_RESET_CMD, &reset_pkt, sizeof(reset_pkt)); + if (err) + return err; + + sif_write_smflag(SIF_STATUS_SIFINIT | SIF_STATUS_CMDINIT); + + return completed(sif_smflag_bootend) ? 0 : -EIO; +} + +static int iop_reset(void) +{ + return iop_reset_arg(IOP_RESET_ARGS); +} + +static int sif_read_subaddr(dma_addr_t *subaddr) +{ + if (!completed(sif_smflag_cmdinit)) + return -EIO; + + *subaddr = inl(SIF_SUBADDR); + + return 0; +} + +static void sif_write_mainaddr_bootend(dma_addr_t mainaddr) +{ + outl(0xff, SIF_UNKNF260); + outl(mainaddr, SIF_MAINADDR); + sif_write_msflag(SIF_STATUS_CMDINIT | SIF_STATUS_BOOTEND); +} + +static void put_dma_buffers(void) +{ + free_page((unsigned long)sif1_buffer); + free_page((unsigned long)sif0_buffer); +} + +static int get_dma_buffers(void) +{ + sif0_buffer = (void *)__get_free_page(GFP_DMA); + sif1_buffer = (void *)__get_free_page(GFP_DMA); + + if (sif0_buffer == NULL || + sif1_buffer == NULL) { + put_dma_buffers(); + return -ENOMEM; + } + + return 0; +} + +static void sif_disable_dma(void) +{ + outl(DMAC_CHCR_STOP, DMAC_SIF0_CHCR); + outl(0, DMAC_SIF0_MADR); + outl(0, DMAC_SIF0_QWC); + inl(DMAC_SIF0_QWC); + + outl(DMAC_CHCR_STOP, DMAC_SIF1_CHCR); +} + +/** + * sif_init - initialise the SIF with a reset + * + * The IOP follows a certain boot protocol, with the following steps: + * + * 1. The kernel allocates a DMA memory buffer that the IOP can use to send + * commands. The kernel advertises this buffer by writing to the MAINADDR + * register. + * + * 2. The kernel reads the provisional SUBADDR register to obtain the + * corresponding command buffer for the IOP. + * + * 3. The kernel clears the %SIF_STATUS_BOOTEND flag in the SMFLAG register. + * + * 4. The kernel issues the %SIF_CMD_RESET_CMD command to the IOP. + * + * 5. The kernel indicates that the SIF and system commands are ready by + * setting the %SIF_STATUS_SIFINIT and %SIF_STATUS_CMDINIT flags in the + * SMFLAG register. + * + * 6. The kernel waits for the IOP to set the %SIF_STATUS_BOOTEND flag in + * the SMFLAG register. + * + * 7. The kernel indicates that the boot is completed by writing updating + * its MAINADDR and setting the %SIF_STATUS_CMDINIT and %SIF_STATUS_BOOTEND + * flags in the MSFLAG register. The %SIF_UNKNF260 register is set to 0xff. + * + * 8. The kernel reads the final SUBADDR register to obtain the command + * buffer for the IOP. + * + * Return: 0 on success, otherwise a negative error number + */ +static int __init sif_init(void) +{ + int err; + + BUILD_BUG_ON(sizeof(struct sif_cmd_header) != 16); + + sif_disable_dma(); + + err = get_dma_buffers(); + if (err) { + pr_err("sif: Failed to allocate DMA buffers with %d\n", err); + goto err_dma_buffers; + } + + /* Read provisional SUBADDR in preparation for the IOP reset. */ + err = sif_read_subaddr(&iop_buffer); + if (err) { + pr_err("sif: Failed to read provisional SUBADDR with %d\n", + err); + goto err_provisional_subaddr; + } + + /* Write provisional MAINADDR in preparation for the IOP reset. */ + sif_write_mainaddr_bootend(virt_to_phys(sif0_buffer)); + + err = iop_reset(); + if (err) { + pr_err("sif: Failed to reset the IOP with %d\n", err); + goto err_iop_reset; + } + + /* Write final MAINADDR and indicate end of boot. */ + sif_write_mainaddr_bootend(virt_to_phys(sif0_buffer)); + + /* Read final SUBADDR. */ + err = sif_read_subaddr(&iop_buffer); + if (err) { + pr_err("sif: Failed to read final SUBADDR with %d\n", err); + goto err_final_subaddr; + } + + return 0; + +err_final_subaddr: +err_iop_reset: +err_provisional_subaddr: + put_dma_buffers(); + +err_dma_buffers: + return err; +} + +static void __exit sif_exit(void) +{ + sif_disable_dma(); + + put_dma_buffers(); +} + +module_init(sif_init); +module_exit(sif_exit); + +MODULE_DESCRIPTION("PlayStation 2 sub-system interface (SIF)"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 15:57:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125429 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 14D90112C for ; Sun, 1 Sep 2019 15:57:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F0A372339D for ; Sun, 1 Sep 2019 15:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728644AbfIAP56 (ORCPT ); Sun, 1 Sep 2019 11:57:58 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58346 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAP56 (ORCPT ); Sun, 1 Sep 2019 11:57:58 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 8C081402D7 for ; Sun, 1 Sep 2019 17:57:56 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wUMcICxGXh7L for ; Sun, 1 Sep 2019 17:57:55 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id D61853FC34 for ; Sun, 1 Sep 2019 17:57:55 +0200 (CEST) Date: Sun, 1 Sep 2019 17:57:54 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 053/120] MIPS: PS2: IOP: Define error numbers, descriptions and errno mapping Message-ID: <8e1a8a4e97c9415d0e1483c7d0a7b9b5fbee8890.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org IOP ROM modules use a set of special numbers to indicate error conditions of various kinds. These are translated into approximate kernel error numbers. Some of the IOP error numbers are unclear or unknown. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/iop-error.h | 76 ++++++++++++++++++++++ drivers/ps2/sif.c | 39 +++++++++++ 2 files changed, 115 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/iop-error.h diff --git a/arch/mips/include/asm/mach-ps2/iop-error.h b/arch/mips/include/asm/mach-ps2/iop-error.h new file mode 100644 index 000000000000..c01bcad28a99 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/iop-error.h @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) error codes + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_IOP_ERROR_H +#define __ASM_MACH_PS2_IOP_ERROR_H + +#define IOP_ERRORS(E) \ + E(BADEXCE, 50, EINVAL, "Bad exception") \ + E(NOEXCE, 51, ENOENT, "Exception not found") \ + E(BUSYEXCE, 52, EBUSY, "Exception in use") \ + \ + E(INIRQ, 100, EPERM, "In IRQ context") \ + E(BADIRQ, 101, EINVAL, "Bad IRQ") \ + E(CPUINTD, 102, EPERM, "CPU interrupts disabled") \ + E(INTD, 103, EPERM, "Interrupts disabled") \ + E(BUSYHAND, 104, EBUSY, "Handler in use") \ + E(NOHAND, 105, ENOENT, "Handler not found") \ + \ + E(NOTIMER, 150, ENOENT, "Timer not found") \ + E(BADTIMER, 151, EINVAL, "Bad timer") \ + \ + E(BUSYUNIT, 160, EBUSY, "Unit in use") \ + E(NOUNIT, 161, ENOENT, "Unit not found") \ + E(NOROMDIR, 162, ENOENT, "ROM directory not found") \ + \ + E(LINK, 200, ENOEXEC, "Module linking error") \ + E(BADOBJ, 201, ENOEXEC, "Object not module") \ + E(NOMOD, 202, ENOENT, "Module not found") \ + E(NOENT, 203, ENOENT, "No such file") \ + E(FILE, 204, EIO, "File error") \ + E(BUSYMEM, 205, EBUSY, "Memory in use") \ + \ + E(NOMEM, 400, ENOMEM, "Out of memory") \ + E(BADATTR, 401, EINVAL, "Bad attribute") \ + E(BADENTRY, 402, EINVAL, "Bad entry") \ + E(BADPRIO, 403, EINVAL, "Bad priority") \ + E(BADSTSZ, 404, EINVAL, "Bad stack size") \ + E(BADMODE, 405, EINVAL, "Bad mode") \ + E(BADTHR, 406, EINVAL, "Bad thread") \ + E(NOTHR, 407, ESRCH, "Thread not found") \ + E(NOSEM, 408, ENOENT, "Semaphore not found") \ + E(NOEVF, 409, ENXIO, "ENOEVF") /* FIXME */ \ + E(NOMBX, 410, ENXIO, "ENOMBX") /* FIXME */ \ + E(NOVPL, 411, ENXIO, "ENOVPL") /* FIXME */ \ + E(NOFPL, 412, ENXIO, "ENOFPL") /* FIXME */ \ + E(DORM, 413, EINVAL, "EDORM") /* FIXME */ \ + E(NODORM, 414, ENOENT, "ENODORM") /* FIXME */ \ + E(NOSUSP, 415, ENOENT, "ENOSUSP") /* FIXME */ \ + E(BADWAIT, 416, EINVAL, "EBADWAIT") /* FIXME */ \ + E(NOWAIT, 417, ENOENT, "ENOWAIT") /* FIXME */ \ + E(RELWAIT, 418, EINVAL, "ERELWAIT") /* FIXME */ \ + E(SEMZERO, 419, EINVAL, "ESEMZERO") /* FIXME */ \ + E(SEMOVF, 420, EINVAL, "ESEMOVF") /* FIXME */ \ + E(EVFCOND, 421, EINVAL, "EEVFCOND") /* FIXME */ \ + E(EVFMULTI, 422, EINVAL, "EEVFMULTI") /* FIXME */ \ + E(EVFILPAT, 423, EINVAL, "EEVFILPAT") /* FIXME */ \ + E(MBOXNOMSG, 424, ENOENT, "EMBOXNOMSG") /* FIXME */ \ + E(WAITDEL, 425, EINVAL, "EWAITDEL") /* FIXME */ \ + E(INVMEMBLK, 426, EINVAL, "EINVMEMBLK") /* FIXME */ \ + E(INVMEMSZ, 427, ENOSPC, "EINVMEMSZ") /* FIXME */ + +enum iop_error { +#define IOP_ERROR_ENUM(identifier, number, errno, description) \ + IOP_E##identifier = number, + IOP_ERRORS(IOP_ERROR_ENUM) +}; + +int errno_for_iop_error(int ioperr); + +const char *iop_error_message(int ioperr); + +#endif /* __ASM_MACH_PS2_IOP_ERROR_H */ diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 6564af245880..8320c5b68d17 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -315,6 +316,44 @@ static void sif_disable_dma(void) outl(DMAC_CHCR_STOP, DMAC_SIF1_CHCR); } +/** + * errno_for_iop_error - kernel error number corresponding to a given IOP error + * @ioperr: IOP error number + * + * Return: approximative kernel error number + */ +int errno_for_iop_error(int ioperr) +{ + switch (ioperr) { +#define IOP_ERROR_ERRNO(identifier, number, errno, description) \ + case -IOP_E##identifier: return -errno; + IOP_ERRORS(IOP_ERROR_ERRNO) + } + + return -1000 < ioperr && ioperr < 0 ? -EINVAL : ioperr; +} +EXPORT_SYMBOL_GPL(errno_for_iop_error); + +/** + * iop_error_message - message corresponding to a given IOP error + * @ioperr: IOP error number + * + * Return: error message string + */ +const char *iop_error_message(int ioperr) +{ + switch (ioperr) { + case 0: return "Success"; + case 1: return "Error"; +#define IOP_ERROR_MSG(identifier, number, errno, description) \ + case IOP_E##identifier: return description; + IOP_ERRORS(IOP_ERROR_MSG) + } + + return "Unknown error"; +} +EXPORT_SYMBOL_GPL(iop_error_message); + /** * sif_init - initialise the SIF with a reset * From patchwork Sun Sep 1 15:58:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125431 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6E90112C for ; Sun, 1 Sep 2019 15:58:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AD3EB2339D for ; Sun, 1 Sep 2019 15:58:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728667AbfIAP6N (ORCPT ); Sun, 1 Sep 2019 11:58:13 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58368 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAP6N (ORCPT ); Sun, 1 Sep 2019 11:58:13 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id EE42C402D7 for ; Sun, 1 Sep 2019 17:58:10 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rxyDDRi3tQsW for ; Sun, 1 Sep 2019 17:58:10 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 358233FC34 for ; Sun, 1 Sep 2019 17:58:10 +0200 (CEST) Date: Sun, 1 Sep 2019 17:58:10 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 054/120] MIPS: PS2: SIF: SIF register write command support Message-ID: <3710c85c9408ca152a894141ff668162c1506f1f.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The SIF register write command is used to establish the remote procedure call (RPC) protocol between the IOP and the kernel. Its full use is unclear. Only register zero (SIF_SREG_RPCINIT) will be used in a subsequent change. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/sif.h | 5 ++ drivers/ps2/sif.c | 75 ++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/sif.h b/arch/mips/include/asm/mach-ps2/sif.h index 94da96bd21d1..9d660155cc5f 100644 --- a/arch/mips/include/asm/mach-ps2/sif.h +++ b/arch/mips/include/asm/mach-ps2/sif.h @@ -69,4 +69,9 @@ struct sif_cmd_header u32 opt; }; +typedef void (*sif_cmd_cb)(const struct sif_cmd_header *header, + const void *data, void *arg); + +int sif_request_cmd(u32 cmd_id, sif_cmd_cb cb, void *arg); + #endif /* __ASM_MACH_PS2_SIF_H */ diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 8320c5b68d17..0edcda0b166d 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -51,10 +51,29 @@ #define SIF0_BUFFER_SIZE PAGE_SIZE #define SIF1_BUFFER_SIZE PAGE_SIZE +static DEFINE_SPINLOCK(sregs_lock); +static s32 sregs[32]; + static iop_addr_t iop_buffer; /* Address of IOP SIF DMA receive address */ static void *sif0_buffer; static void *sif1_buffer; +static void cmd_write_sreg(const struct sif_cmd_header *header, + const void *data, void *arg) +{ + unsigned long flags; + const struct { + u32 reg; + s32 val; + } *packet = data; + + BUG_ON(packet->reg >= ARRAY_SIZE(sregs)); + + spin_lock_irqsave(&sregs_lock, flags); + sregs[packet->reg] = packet->val; + spin_unlock_irqrestore(&sregs_lock, flags); +} + /** * sif_write_msflag - write to set main-to-sub flag register bits * @mask: MSFLAG register bit values to set @@ -236,6 +255,34 @@ static int sif_cmd(u32 cmd_id, const void *pkt, size_t pktsize) return sif_cmd_copy(cmd_id, pkt, pktsize, 0, NULL, 0); } +static struct sif_cmd_handler *handler_from_cid(u32 cmd_id) +{ + enum { CMD_HANDLER_MAX = 64 }; + + static struct sif_cmd_handler sys_cmds[CMD_HANDLER_MAX]; + static struct sif_cmd_handler usr_cmds[CMD_HANDLER_MAX]; + + const u32 id = cmd_id & ~SIF_CMD_ID_SYS; + struct sif_cmd_handler *cmd_handlers = + (cmd_id & SIF_CMD_ID_SYS) != 0 ? sys_cmds : usr_cmds; + + return id < CMD_HANDLER_MAX ? &cmd_handlers[id] : NULL; +} + +int sif_request_cmd(u32 cmd_id, sif_cmd_cb cb, void *arg) +{ + struct sif_cmd_handler *handler = handler_from_cid(cmd_id); + + if (handler == NULL) + return -EINVAL; + + handler->cb = cb; + handler->arg = arg; + + return 0; +} +EXPORT_SYMBOL_GPL(sif_request_cmd); + static int iop_reset_arg(const char *arg) { const size_t arglen = strlen(arg) + 1; @@ -306,6 +353,25 @@ static int get_dma_buffers(void) return 0; } +static int sif_request_cmds(void) +{ + const struct { + u32 cmd_id; + sif_cmd_cb cb; + struct cmd_data *arg; + } cmds[] = { + { SIF_CMD_WRITE_SREG, cmd_write_sreg, NULL }, + }; + int err = 0; + size_t i; + + for (i = 0; i < ARRAY_SIZE(cmds) && err == 0; i++) + err = sif_request_cmd(cmds[i].cmd_id, + cmds[i].cb, cmds[i].arg); + + return err; +} + static void sif_disable_dma(void) { outl(DMAC_CHCR_STOP, DMAC_SIF0_CHCR); @@ -384,6 +450,8 @@ EXPORT_SYMBOL_GPL(iop_error_message); * 8. The kernel reads the final SUBADDR register to obtain the command * buffer for the IOP. * + * 9. Register SIF commands to enable remote procedure calls (RPCs). + * * Return: 0 on success, otherwise a negative error number */ static int __init sif_init(void) @@ -427,8 +495,15 @@ static int __init sif_init(void) goto err_final_subaddr; } + err = sif_request_cmds(); + if (err) { + pr_err("sif: Failed to request commands with %d\n", err); + goto err_request_commands; + } + return 0; +err_request_commands: err_final_subaddr: err_iop_reset: err_provisional_subaddr: From patchwork Sun Sep 1 15:58:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125433 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BC531112C for ; Sun, 1 Sep 2019 15:58:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A3D98233A2 for ; Sun, 1 Sep 2019 15:58:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728672AbfIAP6j (ORCPT ); Sun, 1 Sep 2019 11:58:39 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58452 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAP6j (ORCPT ); Sun, 1 Sep 2019 11:58:39 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 9EC483F53F for ; Sun, 1 Sep 2019 17:58:37 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SLy7WBHKZBmJ for ; Sun, 1 Sep 2019 17:58:37 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 05CFE3F52B for ; Sun, 1 Sep 2019 17:58:36 +0200 (CEST) Date: Sun, 1 Sep 2019 17:58:36 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 055/120] MIPS: PS2: SIF: Respond to remote procedure call (RPC) bind command Message-ID: <1e53a1edfcd2c49b32574bde040178c97be11e52.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The IOP can service remote procedure calls (RPCs) from the main (R5900) processor. The first step is to send a bind command that the IOP will respond to, to establish a client connection. The main processor responds by issuing a bind end command to the IOP. Allocating IOP memory and linking IOP modules are examples of IOP RPC services that will be used in subsequent changes. IOP memory is needed for USB OHCI support. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/sif.h | 11 +++++++ drivers/ps2/sif.c | 49 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/sif.h b/arch/mips/include/asm/mach-ps2/sif.h index 9d660155cc5f..3d163980a4be 100644 --- a/arch/mips/include/asm/mach-ps2/sif.h +++ b/arch/mips/include/asm/mach-ps2/sif.h @@ -74,4 +74,15 @@ typedef void (*sif_cmd_cb)(const struct sif_cmd_header *header, int sif_request_cmd(u32 cmd_id, sif_cmd_cb cb, void *arg); +struct sif_rpc_client +{ + iop_addr_t server; + iop_addr_t server_buffer; + + size_t client_size_max; + void *client_buffer; + + struct completion done; +}; + #endif /* __ASM_MACH_PS2_SIF_H */ diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 0edcda0b166d..7d0b120398d1 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -51,6 +51,35 @@ #define SIF0_BUFFER_SIZE PAGE_SIZE #define SIF1_BUFFER_SIZE PAGE_SIZE +struct sif_rpc_packet_header { + u32 rec_id; + void *pkt_addr; + u32 rpc_id; +}; + +struct sif_rpc_request_end_packet { + struct sif_rpc_packet_header header; + struct sif_rpc_client *client; + u32 client_id; + + iop_addr_t server; + iop_addr_t server_buffer; + + void *client_buffer; +}; + +struct sif_rpc_bind_packet { + struct sif_rpc_packet_header header; + struct sif_rpc_client *client; + u32 server_id; +}; + +struct sif_cmd_handler +{ + sif_cmd_cb cb; + void *arg; +}; + static DEFINE_SPINLOCK(sregs_lock); static s32 sregs[32]; @@ -269,6 +298,21 @@ static struct sif_cmd_handler *handler_from_cid(u32 cmd_id) return id < CMD_HANDLER_MAX ? &cmd_handlers[id] : NULL; } +static void cmd_rpc_bind(const struct sif_cmd_header *header, + const void *data, void *arg) +{ + const struct sif_rpc_bind_packet *bind = data; + const struct sif_rpc_request_end_packet packet = { + .client = bind->client, + .client_id = SIF_CMD_RPC_BIND, + }; + int err; + + err = sif_cmd(SIF_CMD_RPC_END, &packet, sizeof(packet)); + if (err) + pr_err_once("sif: cmd_rpc_bind failed with %d\n", err); +} + int sif_request_cmd(u32 cmd_id, sif_cmd_cb cb, void *arg) { struct sif_cmd_handler *handler = handler_from_cid(cmd_id); @@ -361,6 +405,8 @@ static int sif_request_cmds(void) struct cmd_data *arg; } cmds[] = { { SIF_CMD_WRITE_SREG, cmd_write_sreg, NULL }, + + { SIF_CMD_RPC_BIND, cmd_rpc_bind, NULL }, }; int err = 0; size_t i; @@ -458,6 +504,9 @@ static int __init sif_init(void) { int err; + BUILD_BUG_ON(sizeof(struct sif_rpc_packet_header) != 12); + BUILD_BUG_ON(sizeof(struct sif_rpc_request_end_packet) != 32); + BUILD_BUG_ON(sizeof(struct sif_rpc_bind_packet) != 20); BUILD_BUG_ON(sizeof(struct sif_cmd_header) != 16); sif_disable_dma(); From patchwork Sun Sep 1 15:58:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125435 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6826112C for ; Sun, 1 Sep 2019 15:58:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A52C8233A2 for ; Sun, 1 Sep 2019 15:58:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728677AbfIAP6y (ORCPT ); Sun, 1 Sep 2019 11:58:54 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:57494 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAP6y (ORCPT ); Sun, 1 Sep 2019 11:58:54 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 54D503F73E for ; Sun, 1 Sep 2019 17:58:52 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ci7sWiqfD8Nk for ; Sun, 1 Sep 2019 17:58:51 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id AC47E3F708 for ; Sun, 1 Sep 2019 17:58:51 +0200 (CEST) Date: Sun, 1 Sep 2019 17:58:51 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 056/120] MIPS: PS2: SIF: Respond to RPC bind end command Message-ID: <07edaf69eae2bfa41daae262be2d6aac233a2a48.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The IOP responds with a bind end to the main processor's corresponding command, containing the IOP server memory address to store RPC data. Signed-off-by: Fredrik Noring --- drivers/ps2/sif.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 7d0b120398d1..095d11810499 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -298,6 +298,28 @@ static struct sif_cmd_handler *handler_from_cid(u32 cmd_id) return id < CMD_HANDLER_MAX ? &cmd_handlers[id] : NULL; } +static void cmd_rpc_end(const struct sif_cmd_header *header, + const void *data, void *arg) +{ + const struct sif_rpc_request_end_packet *packet = data; + struct sif_rpc_client *client = packet->client; + + switch (packet->client_id) { + case SIF_CMD_RPC_CALL: + break; + + case SIF_CMD_RPC_BIND: + client->server = packet->server; + client->server_buffer = packet->server_buffer; + break; + + default: + BUG(); + } + + complete_all(&client->done); +} + static void cmd_rpc_bind(const struct sif_cmd_header *header, const void *data, void *arg) { @@ -406,6 +428,7 @@ static int sif_request_cmds(void) } cmds[] = { { SIF_CMD_WRITE_SREG, cmd_write_sreg, NULL }, + { SIF_CMD_RPC_END, cmd_rpc_end, NULL }, { SIF_CMD_RPC_BIND, cmd_rpc_bind, NULL }, }; int err = 0; From patchwork Sun Sep 1 15:59:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125437 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F1C5F112C for ; Sun, 1 Sep 2019 15:59:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CF66D2339D for ; Sun, 1 Sep 2019 15:59:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728687AbfIAP7K (ORCPT ); Sun, 1 Sep 2019 11:59:10 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:42470 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbfIAP7K (ORCPT ); Sun, 1 Sep 2019 11:59:10 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id AEC323F684 for ; Sun, 1 Sep 2019 17:59:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wV-fxDc96UUm for ; Sun, 1 Sep 2019 17:59:08 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 118A03F615 for ; Sun, 1 Sep 2019 17:59:07 +0200 (CEST) Date: Sun, 1 Sep 2019 17:59:07 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 057/120] MIPS: PS2: SIF: Reset the SIF0 (sub-to-main) DMA controller Message-ID: <4a489e4ef6239afa79af1faa72d8cd9ce4e045e2.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Put the SIF0 DMA controller in a known state with a reset. Signed-off-by: Fredrik Noring --- drivers/ps2/sif.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 095d11810499..d077a0a97e02 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -251,6 +251,13 @@ static int sif1_write_irq(const struct sif_cmd_header *header, return sif1_write_ert_int_0(header, true, true, dst, src, nbytes); } +static void sif0_reset_dma(void) +{ + outl(0, DMAC_SIF0_QWC); + outl(0, DMAC_SIF0_MADR); + outl(DMAC_CHCR_RECVC_TIE, DMAC_SIF0_CHCR); +} + static int sif_cmd_opt_copy(u32 cmd_id, u32 opt, const void *pkt, size_t pktsize, iop_addr_t dst, const void *src, size_t nbytes) { @@ -521,6 +528,8 @@ EXPORT_SYMBOL_GPL(iop_error_message); * * 9. Register SIF commands to enable remote procedure calls (RPCs). * + * 10. Reset the SIF0 (sub-to-main) DMA controller. + * * Return: 0 on success, otherwise a negative error number */ static int __init sif_init(void) @@ -573,6 +582,8 @@ static int __init sif_init(void) goto err_request_commands; } + sif0_reset_dma(); + return 0; err_request_commands: From patchwork Sun Sep 1 15:59:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125439 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 722EC112C for ; Sun, 1 Sep 2019 15:59:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 59D4A233A2 for ; Sun, 1 Sep 2019 15:59:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728753AbfIAP7g (ORCPT ); Sun, 1 Sep 2019 11:59:36 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:42514 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728734AbfIAP7g (ORCPT ); Sun, 1 Sep 2019 11:59:36 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 9C7353F684 for ; Sun, 1 Sep 2019 17:59:34 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Zr7hUvFCrHSd for ; Sun, 1 Sep 2019 17:59:33 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id E74BC3F615 for ; Sun, 1 Sep 2019 17:59:33 +0200 (CEST) Date: Sun, 1 Sep 2019 17:59:33 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 058/120] MIPS: PS2: SIF: Handle SIF0 (sub-to-main) RPCs via interrupts Message-ID: <4f70dc50d49675c21ef1e835e21ebbb9dc95a256.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The SIF0 DMA controller asserts an interrupt on RPC completion. The kernel invokes the corresponding callback in the command table, and then resets the SIF0 DMA to receive the next command. Signed-off-by: Fredrik Noring --- drivers/ps2/sif.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index d077a0a97e02..fac1a5117d1c 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -164,11 +164,21 @@ static bool sif_smflag_bootend(void) return (sif_read_smflag() & SIF_STATUS_BOOTEND) != 0; } +static bool sif0_busy(void) +{ + return (inl(DMAC_SIF0_CHCR) & DMAC_CHCR_BUSY) != 0; +} + static bool sif1_busy(void) { return (inl(DMAC_SIF1_CHCR) & DMAC_CHCR_BUSY) != 0; } +/* + * sif1_ready may be called via cmd_rpc_bind that is a response from + * SIF_CMD_RPC_BIND via sif0_dma_handler from IRQ_DMAC_SIF0. Thus we + * currently have to busy-wait here if SIF1 is busy. + */ static bool sif1_ready(void) { size_t countout = 50000; /* About 5 s */ @@ -305,6 +315,48 @@ static struct sif_cmd_handler *handler_from_cid(u32 cmd_id) return id < CMD_HANDLER_MAX ? &cmd_handlers[id] : NULL; } +static void cmd_call_handler( + const struct sif_cmd_header *header, const void *data) +{ + const struct sif_cmd_handler *handler = handler_from_cid(header->cmd); + + if (!handler || !handler->cb) { + pr_err_once("sif: Invalid command 0x%x ignored\n", header->cmd); + return; + } + + handler->cb(header, data, handler->arg); +} + +static irqreturn_t sif0_dma_handler(int irq, void *dev_id) +{ + const struct sif_cmd_header *header = sif0_buffer; + const void *payload = &header[1]; + + if (sif0_busy()) + return IRQ_NONE; + + dma_cache_inv((unsigned long)sif0_buffer, SIF_CMD_PACKET_MAX); + + if (header->data_size) + dma_cache_inv((unsigned long)phys_to_virt(header->data_addr), + header->data_size); + + if (header->packet_size < sizeof(*header) || + header->packet_size > SIF_CMD_PACKET_MAX) { + pr_err_once("sif: Invalid command header size %u bytes\n", + header->packet_size); + goto err; + } + + cmd_call_handler(header, payload); + +err: + sif0_reset_dma(); /* Reset DMA for the next incoming packet. */ + + return IRQ_HANDLED; +} + static void cmd_rpc_end(const struct sif_cmd_header *header, const void *data, void *arg) { @@ -530,6 +582,8 @@ EXPORT_SYMBOL_GPL(iop_error_message); * * 10. Reset the SIF0 (sub-to-main) DMA controller. * + * 11. Service SIF0 RPCs via interrupts. + * * Return: 0 on success, otherwise a negative error number */ static int __init sif_init(void) @@ -584,8 +638,17 @@ static int __init sif_init(void) sif0_reset_dma(); + err = request_irq(IRQ_DMAC_SIF0, sif0_dma_handler, 0, "SIF0 DMA", NULL); + if (err) { + pr_err("sif: Failed to setup SIF0 handler with %d\n", err); + goto err_irq_sif0; + } + return 0; +err_irq_sif0: + sif_disable_dma(); + err_request_commands: err_final_subaddr: err_iop_reset: @@ -600,6 +663,8 @@ static void __exit sif_exit(void) { sif_disable_dma(); + free_irq(IRQ_DMAC_SIF0, NULL); + put_dma_buffers(); } From patchwork Sun Sep 1 15:59:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125441 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AC771112C for ; Sun, 1 Sep 2019 15:59:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8AC82233A2 for ; Sun, 1 Sep 2019 15:59:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728734AbfIAP7v (ORCPT ); Sun, 1 Sep 2019 11:59:51 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58538 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAP7v (ORCPT ); Sun, 1 Sep 2019 11:59:51 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 8A0773F53F for ; Sun, 1 Sep 2019 17:59:49 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oT0zFHAzfnQI for ; Sun, 1 Sep 2019 17:59:48 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id D70403F52B for ; Sun, 1 Sep 2019 17:59:48 +0200 (CEST) Date: Sun, 1 Sep 2019 17:59:48 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 059/120] MIPS: PS2: SIF: Enable the IOP to issue SIF commands Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Send the SIF_CMD_INIT_CMD command with option argument 0 to let the IOP issue SIF commands. The supplied address is the MAINADDR. Signed-off-by: Fredrik Noring --- drivers/ps2/sif.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index fac1a5117d1c..b6c348974bdb 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -441,6 +441,13 @@ static int iop_reset(void) return iop_reset_arg(IOP_RESET_ARGS); } +static int sif_cmd_init(dma_addr_t cmd_buffer) +{ + const struct sif_cmd_change_addr_packet cmd = { .addr = cmd_buffer }; + + return sif_cmd_opt(SIF_CMD_INIT_CMD, 0, &cmd, sizeof(cmd)); +} + static int sif_read_subaddr(dma_addr_t *subaddr) { if (!completed(sif_smflag_cmdinit)) @@ -584,6 +591,8 @@ EXPORT_SYMBOL_GPL(iop_error_message); * * 11. Service SIF0 RPCs via interrupts. * + * 12. Enable the IOP to issue SIF commands. + * * Return: 0 on success, otherwise a negative error number */ static int __init sif_init(void) @@ -644,8 +653,17 @@ static int __init sif_init(void) goto err_irq_sif0; } + err = sif_cmd_init(virt_to_phys(sif0_buffer)); + if (err) { + pr_err("sif: Failed to initialise commands with %d\n", err); + goto err_cmd_init; + } + return 0; +err_cmd_init: + free_irq(IRQ_DMAC_SIF0, NULL); + err_irq_sif0: sif_disable_dma(); From patchwork Sun Sep 1 16:00:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125443 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3FCDB112C for ; Sun, 1 Sep 2019 16:00:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 26D5C233A2 for ; Sun, 1 Sep 2019 16:00:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728763AbfIAQAG (ORCPT ); Sun, 1 Sep 2019 12:00:06 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:42542 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQAF (ORCPT ); Sun, 1 Sep 2019 12:00:05 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 83BD03F695 for ; Sun, 1 Sep 2019 18:00:03 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UeXzNYOBe5jT for ; Sun, 1 Sep 2019 18:00:02 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id AF39F3F615 for ; Sun, 1 Sep 2019 18:00:02 +0200 (CEST) Date: Sun, 1 Sep 2019 18:00:02 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 060/120] MIPS: PS2: SIF: Enable the IOP to issue SIF RPCs Message-ID: <84fc3fb4961e1b598b772889d28817819d93f74e.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Send the SIF_CMD_INIT_CMD command with option argument 1 to let the IOP issue remote procedure calls (RPCs). Wait for the IOP to acknowledge by writing a nonzero value to the SIF_SREG_RPCINIT SIF register. Signed-off-by: Fredrik Noring --- drivers/ps2/sif.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index b6c348974bdb..7a5aab785237 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -51,6 +51,8 @@ #define SIF0_BUFFER_SIZE PAGE_SIZE #define SIF1_BUFFER_SIZE PAGE_SIZE +#define SIF_SREG_RPCINIT 0 + struct sif_rpc_packet_header { u32 rec_id; void *pkt_addr; @@ -74,6 +76,10 @@ struct sif_rpc_bind_packet { u32 server_id; }; +struct sif_cmd_change_addr_packet { + iop_addr_t addr; +}; + struct sif_cmd_handler { sif_cmd_cb cb; @@ -103,6 +109,25 @@ static void cmd_write_sreg(const struct sif_cmd_header *header, spin_unlock_irqrestore(&sregs_lock, flags); } +static s32 read_sreg(u32 reg) +{ + unsigned long flags; + s32 val; + + BUG_ON(reg >= ARRAY_SIZE(sregs)); + + spin_lock_irqsave(&sregs_lock, flags); + val = sregs[reg]; + spin_unlock_irqrestore(&sregs_lock, flags); + + return val; +} + +static bool sif_sreg_rpcinit(void) +{ + return read_sreg(SIF_SREG_RPCINIT) != 0; +} + /** * sif_write_msflag - write to set main-to-sub flag register bits * @mask: MSFLAG register bit values to set @@ -296,6 +321,11 @@ static int sif_cmd_copy(u32 cmd_id, const void *pkt, size_t pktsize, return sif_cmd_opt_copy(cmd_id, 0, pkt, pktsize, dst, src, nbytes); } +static int sif_cmd_opt(u32 cmd_id, u32 opt, const void *pkt, size_t pktsize) +{ + return sif_cmd_opt_copy(cmd_id, opt, pkt, pktsize, 0, NULL, 0); +} + static int sif_cmd(u32 cmd_id, const void *pkt, size_t pktsize) { return sif_cmd_copy(cmd_id, pkt, pktsize, 0, NULL, 0); @@ -448,6 +478,17 @@ static int sif_cmd_init(dma_addr_t cmd_buffer) return sif_cmd_opt(SIF_CMD_INIT_CMD, 0, &cmd, sizeof(cmd)); } +static int sif_rpc_init(void) +{ + int err; + + err = sif_cmd_opt(SIF_CMD_INIT_CMD, 1, NULL, 0); + if (err) + return err; + + return completed(sif_sreg_rpcinit) ? 0 : -EIO; +} + static int sif_read_subaddr(dma_addr_t *subaddr) { if (!completed(sif_smflag_cmdinit)) @@ -593,6 +634,8 @@ EXPORT_SYMBOL_GPL(iop_error_message); * * 12. Enable the IOP to issue SIF commands. * + * 13. Enable the IOP to issue SIF RPCs. + * * Return: 0 on success, otherwise a negative error number */ static int __init sif_init(void) @@ -603,6 +646,7 @@ static int __init sif_init(void) BUILD_BUG_ON(sizeof(struct sif_rpc_request_end_packet) != 32); BUILD_BUG_ON(sizeof(struct sif_rpc_bind_packet) != 20); BUILD_BUG_ON(sizeof(struct sif_cmd_header) != 16); + BUILD_BUG_ON(sizeof(struct sif_cmd_change_addr_packet) != 4); sif_disable_dma(); @@ -659,8 +703,15 @@ static int __init sif_init(void) goto err_cmd_init; } + err = sif_rpc_init(); + if (err) { + pr_err("sif: Failed to initialise RPC with %d\n", err); + goto err_rpc_init; + } + return 0; +err_rpc_init: err_cmd_init: free_irq(IRQ_DMAC_SIF0, NULL); From patchwork Sun Sep 1 16:01:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125445 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1A2A714DE for ; Sun, 1 Sep 2019 16:01:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 018F12339D for ; Sun, 1 Sep 2019 16:01:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728830AbfIAQBv (ORCPT ); Sun, 1 Sep 2019 12:01:51 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:42688 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQBv (ORCPT ); Sun, 1 Sep 2019 12:01:51 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 626F33F63C for ; Sun, 1 Sep 2019 18:01:49 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ToJMRHal35WH for ; Sun, 1 Sep 2019 18:01:48 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id B3E6A3F58C for ; Sun, 1 Sep 2019 18:01:48 +0200 (CEST) Date: Sun, 1 Sep 2019 18:01:48 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 061/120] MIPS: PS2: SIF: sif_rpc_bind() to request an RPC server connection Message-ID: <560734ac45b85db15b6ad002e433c3db979084dd.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org This is the first initialisation step to perform remote procedure calls. A PAGE_SIZE buffer is allocated to store RPC data. A future improvement is to make the buffer size adjustable. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/sif.h | 2 ++ drivers/ps2/sif.c | 38 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/sif.h b/arch/mips/include/asm/mach-ps2/sif.h index 3d163980a4be..1d9a7ede2fb5 100644 --- a/arch/mips/include/asm/mach-ps2/sif.h +++ b/arch/mips/include/asm/mach-ps2/sif.h @@ -85,4 +85,6 @@ struct sif_rpc_client struct completion done; }; +int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id); + #endif /* __ASM_MACH_PS2_SIF_H */ diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 7a5aab785237..ecb26239518c 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -387,6 +387,44 @@ static irqreturn_t sif0_dma_handler(int irq, void *dev_id) return IRQ_HANDLED; } +/** + * sif_rpc_bind - request a connection to an IOP RPC server + * @client: RPC client object to initialise + * @server_id: identification number for the requested IOP RPC server + * + * A %PAGE_SIZE buffer is allocated to store RPC data. A future improvement is + * to make its size adjustable. + * + * Return: 0 on success, otherwise a negative error number + */ +int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id) +{ + const struct sif_rpc_bind_packet bind = { + .client = client, + .server_id = server_id, + }; + int err; + + memset(client, 0, sizeof(*client)); + init_completion(&client->done); + + client->client_size_max = SIF0_BUFFER_SIZE; + client->client_buffer = (void *)__get_free_page(GFP_DMA); + if (client->client_buffer == NULL) + return -ENOMEM; + + err = sif_cmd(SIF_CMD_RPC_BIND, &bind, sizeof(bind)); + if (err) { + free_page((unsigned long)client->client_buffer); + return err; + } + + wait_for_completion(&client->done); + + return client->server ? 0 : -ENXIO; +} +EXPORT_SYMBOL_GPL(sif_rpc_bind); + static void cmd_rpc_end(const struct sif_cmd_header *header, const void *data, void *arg) { From patchwork Sun Sep 1 16:02:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125447 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BAF7C14DE for ; Sun, 1 Sep 2019 16:02:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 98B942339D for ; Sun, 1 Sep 2019 16:02:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728840AbfIAQCJ (ORCPT ); Sun, 1 Sep 2019 12:02:09 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58732 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQCJ (ORCPT ); Sun, 1 Sep 2019 12:02:09 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 431483F53F for ; Sun, 1 Sep 2019 18:02:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5p1iUJeqOgia for ; Sun, 1 Sep 2019 18:02:07 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 86BFB3F52B for ; Sun, 1 Sep 2019 18:02:07 +0200 (CEST) Date: Sun, 1 Sep 2019 18:02:07 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 062/120] MIPS: PS2: SIF: sif_rpc_unbind() to release an RPC server connection Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/sif.h | 1 + drivers/ps2/sif.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/sif.h b/arch/mips/include/asm/mach-ps2/sif.h index 1d9a7ede2fb5..5a3128920c9a 100644 --- a/arch/mips/include/asm/mach-ps2/sif.h +++ b/arch/mips/include/asm/mach-ps2/sif.h @@ -86,5 +86,6 @@ struct sif_rpc_client }; int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id); +void sif_rpc_unbind(struct sif_rpc_client *client); #endif /* __ASM_MACH_PS2_SIF_H */ diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index ecb26239518c..3c098a46832c 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -395,6 +395,8 @@ static irqreturn_t sif0_dma_handler(int irq, void *dev_id) * A %PAGE_SIZE buffer is allocated to store RPC data. A future improvement is * to make its size adjustable. * + * The connection can be released with sif_rpc_unbind(). + * * Return: 0 on success, otherwise a negative error number */ int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id) @@ -425,6 +427,20 @@ int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id) } EXPORT_SYMBOL_GPL(sif_rpc_bind); +/** + * sif_rpc_unbind - release a connection to an IOP RPC server + * @client: RPC client object to release + * + * The connection must have been established with sif_rpc_bind(). + */ +void sif_rpc_unbind(struct sif_rpc_client *client) +{ + free_page((unsigned long)client->client_buffer); + + /* FIXME: Release the IOP RPC server part */ +} +EXPORT_SYMBOL_GPL(sif_rpc_unbind); + static void cmd_rpc_end(const struct sif_cmd_header *header, const void *data, void *arg) { From patchwork Sun Sep 1 16:02:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125451 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2C76F14E5 for ; Sun, 1 Sep 2019 16:02:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 141DF2339D for ; Sun, 1 Sep 2019 16:02:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728848AbfIAQCw (ORCPT ); Sun, 1 Sep 2019 12:02:52 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:57772 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQCw (ORCPT ); Sun, 1 Sep 2019 12:02:52 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id F17E23F73E for ; Sun, 1 Sep 2019 18:02:50 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id d_36Y4uHjhaA for ; Sun, 1 Sep 2019 18:02:50 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 2CCB53F708 for ; Sun, 1 Sep 2019 18:02:49 +0200 (CEST) Date: Sun, 1 Sep 2019 18:02:48 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 063/120] MIPS: PS2: SIF: sif_rpc() to issue a remote procedure call Message-ID: <61ca193962cdb57416226ec942def139585d6d1a.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org This is the actual function to perform IOP procedure calls. For simplicity a call is synchronous. It is certainly possible to make calls more efficient, asynchronous, and so on, but ease of use is often more important than performance, for example when allocating IOP memory during initialisation of a driver. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/sif.h | 3 ++ drivers/ps2/sif.c | 78 ++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/sif.h b/arch/mips/include/asm/mach-ps2/sif.h index 5a3128920c9a..d0e59692c3c3 100644 --- a/arch/mips/include/asm/mach-ps2/sif.h +++ b/arch/mips/include/asm/mach-ps2/sif.h @@ -88,4 +88,7 @@ struct sif_rpc_client int sif_rpc_bind(struct sif_rpc_client *client, u32 server_id); void sif_rpc_unbind(struct sif_rpc_client *client); +int sif_rpc(struct sif_rpc_client *client, u32 rpc_id, + const void *send, size_t send_size, void *recv, size_t recv_size); + #endif /* __ASM_MACH_PS2_SIF_H */ diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 3c098a46832c..5c3866c460af 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -76,6 +76,20 @@ struct sif_rpc_bind_packet { u32 server_id; }; +struct sif_rpc_call_packet { + struct sif_rpc_packet_header header; + struct sif_rpc_client *client; + u32 rpc_id; + + u32 send_size; + + dma_addr_t recv_addr; + u32 recv_size; + u32 recv_mode; + + iop_addr_t server; +}; + struct sif_cmd_change_addr_packet { iop_addr_t addr; }; @@ -441,6 +455,68 @@ void sif_rpc_unbind(struct sif_rpc_client *client) } EXPORT_SYMBOL_GPL(sif_rpc_unbind); +static int sif_rpc_dma(struct sif_rpc_client *client, u32 rpc_id, + const void *send, size_t send_size, size_t recv_size) +{ + const struct sif_rpc_call_packet call = { + .rpc_id = rpc_id, + .send_size = send_size, + .recv_addr = virt_to_phys(client->client_buffer), + .recv_size = recv_size, + .recv_mode = 1, + .client = client, + .server = client->server + }; + int err; + + if (call.send_size != send_size) + return -EINVAL; + if (recv_size > client->client_size_max) + return -EINVAL; + + reinit_completion(&client->done); + + err = sif_cmd_copy(SIF_CMD_RPC_CALL, &call, sizeof(call), + client->server_buffer, send, send_size); + if (err) + return err; + + wait_for_completion(&client->done); + + if (recv_size > 0) + dma_cache_inv((unsigned long)client->client_buffer, recv_size); + + return 0; +} + +/** + * sif_rpc - issue a remote procedure call (RPC) + * @client: RPC client object initialised with sif_rpc_bind() + * @rpc_id: identification number of remote procedure to call + * @send: data to send with the RPC via DMA, or %NULL if @send_size is zero + * @send_size: size in bytes of the data to send + * @recv: data to receive from the RPC via DMA, or %NULL if @recv_size is zero + * @recv_size: size in bytes of the data to receive + * + * Due to DMA hardware restrictions, the @send buffer must align with 16-byte + * memory boundaries and @send_size is rounded up to a 16-byte multiple. + * + * FIXME: Lift these send restrictions and use memcpy similar to receive? + * + * Return: 0 on success, otherwise a negative error number + */ +int sif_rpc(struct sif_rpc_client *client, u32 rpc_id, + const void *send, size_t send_size, void *recv, size_t recv_size) +{ + int err = sif_rpc_dma(client, rpc_id, send, send_size, recv_size); + + if (err == 0) + memcpy(recv, client->client_buffer, recv_size); + + return err; +} +EXPORT_SYMBOL_GPL(sif_rpc); + static void cmd_rpc_end(const struct sif_cmd_header *header, const void *data, void *arg) { @@ -699,6 +775,8 @@ static int __init sif_init(void) BUILD_BUG_ON(sizeof(struct sif_rpc_packet_header) != 12); BUILD_BUG_ON(sizeof(struct sif_rpc_request_end_packet) != 32); BUILD_BUG_ON(sizeof(struct sif_rpc_bind_packet) != 20); + BUILD_BUG_ON(sizeof(struct sif_rpc_call_packet) != 40); + BUILD_BUG_ON(sizeof(struct sif_cmd_header) != 16); BUILD_BUG_ON(sizeof(struct sif_cmd_change_addr_packet) != 4); From patchwork Sun Sep 1 16:03:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125453 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1186C14E5 for ; Sun, 1 Sep 2019 16:03:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E45612339D for ; Sun, 1 Sep 2019 16:03:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728863AbfIAQDG (ORCPT ); Sun, 1 Sep 2019 12:03:06 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58832 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQDG (ORCPT ); Sun, 1 Sep 2019 12:03:06 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id CEC7B3FC34 for ; Sun, 1 Sep 2019 18:03:04 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DN2xY3Z4xV6m for ; Sun, 1 Sep 2019 18:03:04 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 300593F53F for ; Sun, 1 Sep 2019 18:03:04 +0200 (CEST) Date: Sun, 1 Sep 2019 18:03:04 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 064/120] MIPS: PS2: IOP: Permit /dev/mem to access IOP memory Message-ID: <63369b9b67d63891d34e854ca9110da78415d19b.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/iop.h | 21 +++++++++++++++++++++ arch/mips/ps2/memory.c | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/iop.h diff --git a/arch/mips/include/asm/mach-ps2/iop.h b/arch/mips/include/asm/mach-ps2/iop.h new file mode 100644 index 000000000000..65585451e743 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/iop.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_IOP_H +#define __ASM_MACH_PS2_IOP_H + +#define IOP_RAM_BASE 0x1c000000 +#define IOP_RAM_SIZE 0x200000 + +#define IOP_OHCI_BASE 0x1f801600 + +/** + * iop_addr_t - I/O processor (IOP) bus address + */ +typedef u32 iop_addr_t; + +#endif /* __ASM_MACH_PS2_IOP_H */ diff --git a/arch/mips/ps2/memory.c b/arch/mips/ps2/memory.c index c513b6912bb0..51614b6d0515 100644 --- a/arch/mips/ps2/memory.c +++ b/arch/mips/ps2/memory.c @@ -13,11 +13,13 @@ #include #include +#include #include int valid_phys_addr_range(phys_addr_t addr, size_t size) { return addr + size <= __pa(high_memory) || + (IOP_RAM_BASE <= addr && addr + size <= IOP_RAM_BASE + IOP_RAM_SIZE) || (ROM0_BASE <= addr && addr + size <= ROM0_BASE + ROM0_SIZE) || (ROM1_BASE <= addr && addr + size <= ROM1_BASE + ROM1_SIZE); } From patchwork Sun Sep 1 16:03:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A8E114DE for ; Sun, 1 Sep 2019 16:03:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 22A37233A2 for ; Sun, 1 Sep 2019 16:03:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728874AbfIAQDq (ORCPT ); Sun, 1 Sep 2019 12:03:46 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:58934 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQDq (ORCPT ); Sun, 1 Sep 2019 12:03:46 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 8F0B23F53F for ; Sun, 1 Sep 2019 18:03:44 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id egvDC5WhRQ4S for ; Sun, 1 Sep 2019 18:03:43 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id D15693F52B for ; Sun, 1 Sep 2019 18:03:43 +0200 (CEST) Date: Sun, 1 Sep 2019 18:03:43 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 065/120] MIPS: PS2: IOP: I/O processor memory support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/iop-memory.h | 21 ++++++++ drivers/ps2/Makefile | 1 + drivers/ps2/iop-memory.c | 56 +++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/iop-memory.h create mode 100644 drivers/ps2/iop-memory.c diff --git a/arch/mips/include/asm/mach-ps2/iop-memory.h b/arch/mips/include/asm/mach-ps2/iop-memory.h new file mode 100644 index 000000000000..6efdb490c7b9 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/iop-memory.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 I/O processor (IOP) memory + * + * Copyright (C) 2018 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_IOP_MEMORY_H +#define __ASM_MACH_PS2_IOP_MEMORY_H + +#include + +#include + +iop_addr_t iop_phys_to_bus(phys_addr_t paddr); + +phys_addr_t iop_bus_to_phys(iop_addr_t baddr); + +void *iop_bus_to_virt(iop_addr_t baddr); + +#endif /* __ASM_MACH_PS2_IOP_MEMORY_H */ diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index ef561a802bdd..6f193007ebc6 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,2 +1,3 @@ +obj-m += iop-memory.o obj-m += iop-registers.o obj-m += sif.o diff --git a/drivers/ps2/iop-memory.c b/drivers/ps2/iop-memory.c new file mode 100644 index 000000000000..829d7174da0e --- /dev/null +++ b/drivers/ps2/iop-memory.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) memory + * + * Copyright (C) 2018 Fredrik Noring + */ + +#include +#include +#include +#include + +#include + +/** + * iop_phys_to_bus - kernel physical to I/O processor (IOP) bus address + * @paddr: kernel physical address + * + * Context: any + * Return: I/O processor (IOP) bus address + */ +iop_addr_t iop_phys_to_bus(phys_addr_t paddr) +{ + return (u32)paddr - IOP_RAM_BASE; +} +EXPORT_SYMBOL(iop_phys_to_bus); + +/** + * iop_bus_to_phys - I/O processor (IOP) bus address to kernel physical + * @baddr: I/O processor (IOP) bus address + * + * Context: any + * Return: kernel physical address + */ +phys_addr_t iop_bus_to_phys(iop_addr_t baddr) +{ + return (u32)baddr + IOP_RAM_BASE; +} +EXPORT_SYMBOL(iop_bus_to_phys); + +/** + * iop_bus_to_virt - I/O processor (IOP) bus address to kernel virtual + * @baddr: I/O processor (IOP) bus address + * + * Context: any + * Return: kernel virtual address + */ +void *iop_bus_to_virt(iop_addr_t baddr) +{ + return phys_to_virt(iop_bus_to_phys(baddr)); +} +EXPORT_SYMBOL(iop_bus_to_virt); + +MODULE_DESCRIPTION("PlayStation 2 input/output processor (IOP) memory"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:10:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125457 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 92CE214DE for ; Sun, 1 Sep 2019 16:10:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7028E233A2 for ; Sun, 1 Sep 2019 16:10:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728779AbfIAQKm (ORCPT ); Sun, 1 Sep 2019 12:10:42 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:58412 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAQKm (ORCPT ); Sun, 1 Sep 2019 12:10:42 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id A76E23F73E; Sun, 1 Sep 2019 18:10:40 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yzvVOPONVFVy; Sun, 1 Sep 2019 18:10:40 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 671063F752; Sun, 1 Sep 2019 18:10:39 +0200 (CEST) Date: Sun, 1 Sep 2019 18:10:39 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 066/120] FIXME: Export _dma_cache_{wback,wback_inv,inv} Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Commit e58cfbfb32d1 ("MIPS: remove the _dma_cache_wback_inv export") removes EXPORT_SYMBOL(_dma_cache_wback_inv) but what are the acceptable alternatives? Streaming DMA mappings? dma_cache_wback_inv() and dma_cache_inv() are used in subsequent changes, but I suppose these must be changed to something appropriate. The current DMA handling is very simple, although the hardware is quite capable (for example, with scatter-gather lists, chaining and so on). Signed-off-by: Fredrik Noring --- arch/mips/mm/cache.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 33b409391ddb..a01923b30086 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -62,6 +62,10 @@ void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); void (*_dma_cache_wback)(unsigned long start, unsigned long size); void (*_dma_cache_inv)(unsigned long start, unsigned long size); +EXPORT_SYMBOL(_dma_cache_wback_inv); +EXPORT_SYMBOL(_dma_cache_wback); +EXPORT_SYMBOL(_dma_cache_inv); + #endif /* CONFIG_DMA_NONCOHERENT */ /* From patchwork Sun Sep 1 16:10:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125459 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0013A1510 for ; Sun, 1 Sep 2019 16:10:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C83A021872 for ; Sun, 1 Sep 2019 16:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728883AbfIAQK6 (ORCPT ); Sun, 1 Sep 2019 12:10:58 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:59584 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAQK6 (ORCPT ); Sun, 1 Sep 2019 12:10:58 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id BE7733F53F for ; Sun, 1 Sep 2019 18:10:54 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CeZlxmr5glAE for ; Sun, 1 Sep 2019 18:10:53 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id BFD9D3F52B for ; Sun, 1 Sep 2019 18:10:53 +0200 (CEST) Date: Sun, 1 Sep 2019 18:10:53 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 067/120] MIPS: PS2: IOP: Module linking support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org IOP modules are IRX objects based on the executable and linkable format (ELF). All valid IOP modules have a special .iopmod section containing the module name, version, etc. When the IOP is reset, a set of modules are automatically linked from read-only memory (ROM). Non-ROM modules are handled as firmware by the IOP module linker. IOP modules may import and export any number of library functions, including non at all. Imported libraries must be resolved and prelinked before the given module is allowed to link itself. Other modules can link with its exported libraries. IOP modules begin to execute their entry function immediately after linking. The modules can either stay resident in the IOP, and provide services, or unlink themselves when exiting the entry function. Many modules provide remote procedure call (RPC) services via the sub-system interface (SIF). Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/iop-module.h | 13 + drivers/Makefile | 1 + drivers/ps2/Makefile | 1 + drivers/ps2/iop-module.c | 277 ++++++++++++++++++++ 4 files changed, 292 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/iop-module.h create mode 100644 drivers/ps2/iop-module.c diff --git a/arch/mips/include/asm/mach-ps2/iop-module.h b/arch/mips/include/asm/mach-ps2/iop-module.h new file mode 100644 index 000000000000..f61141031de0 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/iop-module.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) module linker + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_IOP_MODULE_H +#define __ASM_MACH_PS2_IOP_MODULE_H + +int iop_module_request(const char *name, int version, const char *arg); + +#endif /* __ASM_MACH_PS2_IOP_MODULE_H */ diff --git a/drivers/Makefile b/drivers/Makefile index 6d37564e783c..1ed5b83dc528 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -141,6 +141,7 @@ obj-y += clocksource/ endif obj-$(CONFIG_DCA) += dca/ obj-$(CONFIG_HID) += hid/ +obj-$(CONFIG_SONY_PS2) += ps2/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index 6f193007ebc6..b04e4d3c3374 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,3 +1,4 @@ obj-m += iop-memory.o +obj-m += iop-module.o obj-m += iop-registers.o obj-m += sif.o diff --git a/drivers/ps2/iop-module.c b/drivers/ps2/iop-module.c new file mode 100644 index 000000000000..0e4a2173c001 --- /dev/null +++ b/drivers/ps2/iop-module.c @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) module linker + * + * Copyright (C) 2019 Fredrik Noring + */ + +/** + * DOC: PlayStation 2 input/output processor (IOP) module linker + * + * IOP modules are IRX objects based on the executable and linkable format + * (ELF). All valid IOP modules have a special `.iopmod` section containing + * the module name, version, etc. + * + * When the IOP is reset, a set of modules are automatically linked from + * read-only memory (ROM). Non-ROM modules are handled as firmware by the + * IOP module linker. + * + * IOP modules may import and export any number of library functions, + * including non at all. Imported libraries must be resolved and prelinked + * before the given module is allowed to link itself. Other modules can link + * with its exported libraries. + * + * IOP modules begin to execute their entry function immediately after linking. + * The modules can either stay resident in the IOP, and provide services, or + * unlink themselves when exiting the entry function. Many modules provide + * remote procedure call (RPC) services via the sub-system interface (SIF). + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uapi/linux/elf.h" + +#include +#include +#include +#include +#include +#include + +enum iop_module_rpc_ops { + rpo_mod_load = 0, + rpo_elf_load = 1, + rpo_set_addr = 2, + rpo_get_addr = 3, + rpo_mg_mod_load = 4, + rpo_mg_elf_load = 5, + rpo_mod_buf_load = 6, + rpo_mod_stop = 7, + rpo_mod_unload = 8, + rpo_search_mod_by_name = 9, + rpo_search_mod_by_address = 10 +}; + +/** The @iop_module_lock must be taken for all IOP module linking operations */ +static DEFINE_MUTEX(iop_module_lock); + +static struct device *iop_module_device; +static struct sif_rpc_client load_file_rpc_client; + +#define IOPMOD_MAX_PATH 252 +#define IOPMOD_MAX_ARG 252 + +/** + * major_version - major version of version in BCD + * @version: 16-bit version in BCD, with 8-bit minor and 8-bit major + * + * Return: major version + */ +static unsigned int major_version(unsigned int version) +{ + return bcd2bin((version >> 8) & 0xff); +} + +/** + * minor_version - minor version of version in BCD + * @version: 16-bit version in BCD, with 8-bit minor and 8-bit major + * + * Return: minor version + */ +static unsigned int minor_version(unsigned int version) +{ + return bcd2bin(version & 0xff); +} + +/** + * iop_module_link_buffer - link IOP module given in buffer + * @buf: buffer containing the IOP module to link + * @nbyte: size in bytes of given buffer + * @arg: arguments to the IOP module entry function, or %NULL + * + * Return: 0 on success, otherwise a negative error number + */ +static int iop_module_link_buffer(const void *buf, size_t nbyte, + const char *arg) +{ + const char * const arg_ = arg ? arg : ""; + const size_t arg_size = strlen(arg_) + 1; + struct { + u32 addr; + u32 arg_size; + char filepath[IOPMOD_MAX_PATH]; + char arg[IOPMOD_MAX_ARG]; + } link = { + .addr = iop_alloc(nbyte), + .arg_size = arg_size + }; + struct { + s32 status; + u32 modres; + } result; + int err; + + BUILD_BUG_ON(sizeof(link) != 512); + + if (!link.addr) + return -ENOMEM; + + /* Copy the module to IOP memory. */ + memcpy(iop_bus_to_virt(link.addr), buf, nbyte); + + /* Make the module visible to the IOP. */ + dma_cache_wback((unsigned long)iop_bus_to_virt(link.addr), nbyte); + + if (arg_size >= sizeof(link.arg)) { + err = -EOVERFLOW; + goto err_out; + } + memcpy(link.arg, arg_, arg_size); + + err = sif_rpc(&load_file_rpc_client, rpo_mod_buf_load, + &link, sizeof(link), &result, sizeof(result)); + if (err < 0) + goto err_out; + + if (result.status < 0) { + pr_err("iop-module: %s: sif_rpc failed with %d: %s\n", __func__, + result.status, iop_error_message(result.status)); + err = errno_for_iop_error(result.status); + goto err_out; + } + + iop_free(link.addr); + return 0; + +err_out: + iop_free(link.addr); + return err; +} + +static int iop_module_request_firmware( + const char *name, int version, const char *arg); + +/** + * iop_module_request_firmware - link IOP module as firmware + * @name: name of requested module + * @version: requested version in BCD, where major must match with a least + * the same minor + * @arg: module arguments or %NULL + * + * Return: 0 on success, otherwise a negative error number + */ +static int iop_module_request_firmware( + const char *name, int version, const char *arg) +{ + const struct firmware *fw = NULL; + const struct elf32_hdr *ehdr; + char filepath[32]; + int err; + + pr_debug("iop-module: %s module linking as firmware\n", name); + + if (snprintf(filepath, sizeof(filepath), + "ps2/%s.irx", name) == sizeof(filepath) - 1) { + err = -ENAMETOOLONG; + goto err_name; + } + + err = request_firmware(&fw, filepath, iop_module_device); + if (err < 0) + goto err_request; + + ehdr = (const struct elf32_hdr *)fw->data; + + err = iop_module_link_buffer(fw->data, fw->size, arg); + +err_request: +err_name: + + if (err < 0) + pr_err("iop-module: %s module version %u.%u request failed with %d\n", + filepath, major_version(version), + minor_version(version), err); + + release_firmware(fw); + + return err; +} + +/** + * iop_module_request - link requested IOP module unless it is already linked + * @name: name of requested module + * @version: requested version in BCD, where major must match with a least + * the same minor + * @arg: module arguments or %NULL + * + * Module library dependencies are resolved and prelinked as necessary. Module + * files are handled as firmware by the IOP module linker. + * + * IOP module link requests are only permitted if the major versions match + * and the version is at least of the same minor as the requested version. + * + * Context: mutex + * Return: 0 on success, otherwise a negative error number + */ +int iop_module_request(const char *name, int version, const char *arg) +{ + int err; + + mutex_lock(&iop_module_lock); + + pr_debug("iop-module: %s module version %u.%u requested%s%s\n", + name, major_version(version), minor_version(version), + arg ? " with argument " : "", arg ? arg : ""); + + err = iop_module_request_firmware(name, version, arg); + + if (err) + pr_debug("iop-module: %s module request resulted in %d\n", + name, err); + else + pr_debug("iop-module: %s module request successful\n", name); + + mutex_unlock(&iop_module_lock); + + return err; +} +EXPORT_SYMBOL_GPL(iop_module_request); + +static int __init iop_module_init(void) +{ + int err; + + iop_module_device = root_device_register("iop-module"); + if (!iop_module_device) { + pr_err("iop-module: Failed to register root device\n"); + return -ENOMEM; + } + + err = sif_rpc_bind(&load_file_rpc_client, SIF_SID_LOAD_MODULE); + if (err < 0) { + pr_err("iop-module: Failed to bind load module with %d\n", err); + goto err_bind; + } + + return 0; + +err_bind: + root_device_unregister(iop_module_device); + + return err; +} + +module_init(iop_module_init); + +MODULE_DESCRIPTION("PlayStation 2 input/output processor (IOP) module linker"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:11:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125461 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3D4DB14E5 for ; Sun, 1 Sep 2019 16:11:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2005421872 for ; Sun, 1 Sep 2019 16:11:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728888AbfIAQLI (ORCPT ); Sun, 1 Sep 2019 12:11:08 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:43518 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAQLH (ORCPT ); Sun, 1 Sep 2019 12:11:07 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 8C4D73F615 for ; Sun, 1 Sep 2019 18:11:05 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EWSrkz_Cubo7 for ; Sun, 1 Sep 2019 18:11:04 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id C89273F58C for ; Sun, 1 Sep 2019 18:11:04 +0200 (CEST) Date: Sun, 1 Sep 2019 18:11:04 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 068/120] MIPS: PS2: IOP: Verify that modules are IRX objects Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org IOP modules are checked, mainly to print helpful error messages in case of mistakes. IOP modules must have an .iopmod section with the special ELF type SHT_LOPROC+0x80. Signed-off-by: Fredrik Noring --- drivers/ps2/iop-module.c | 154 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/drivers/ps2/iop-module.c b/drivers/ps2/iop-module.c index 0e4a2173c001..d332a7d1af60 100644 --- a/drivers/ps2/iop-module.c +++ b/drivers/ps2/iop-module.c @@ -69,6 +69,140 @@ static struct sif_rpc_client load_file_rpc_client; #define IOPMOD_MAX_PATH 252 #define IOPMOD_MAX_ARG 252 +#define IOPMOD_MAX_LIBRARY_NAME 8 + +#define IOPMOD_NO_ID 0xffffffff + +#define SHT_IOPMOD (SHT_LOPROC + 0x80) + +/** + * struct irx_iopmod - special .iopmod section with module name, version, etc. + * @id_addr: address of a special identification structure, or %IOPMOD_NO_ID + * @entry_addr: module entry address to begin executing code + * @unknown: FIXME + * @text_size: size in bytes of text section + * @data_size: size in bytes of data section + * @bss_size: size in bytes of BSS section + * @version: module version in BCD + * @name: NUL-terminated name of module + */ +struct irx_iopmod { + u32 id_addr; + u32 entry_addr; + u32 unknown; + u32 text_size; + u32 data_size; + u32 bss_size; + u16 version; + char name[0]; +}; + +/** + * elf_ent_for_offset - pointer given an ELF offset + * @offset: ELF offset + * @ehdr: ELF header of module + * + * Return: pointer for a given ELF offset + */ +static const void *elf_ent_for_offset(Elf32_Off offset, + const struct elf32_hdr *ehdr) +{ + return &((const u8 *)ehdr)[offset]; +} + +/** + * elf_first_section - first ELF section + * @ehdr: ELF header of module + * + * Return: pointer to the first ELF section, or %NULL if it does not exist + */ +static const struct elf32_shdr *elf_first_section(const struct elf32_hdr *ehdr) +{ + return ehdr->e_shnum ? elf_ent_for_offset(ehdr->e_shoff, ehdr) : NULL; +} + +/** + * elf_next_section - next ELF section + * @shdr: header of current section + * @ehdr: ELF header of module + * + * Return: section following the current section, or %NULL + */ +static const struct elf32_shdr *elf_next_section( + const struct elf32_shdr *shdr, const struct elf32_hdr *ehdr) +{ + const struct elf32_shdr *next = &shdr[1]; + const struct elf32_shdr *past = &elf_first_section(ehdr)[ehdr->e_shnum]; + + return next == past ? NULL: next; +} + +/** + * elf_for_each_section - iterate over all ELF sections + * @shdr: &struct elf32_shdr loop cursor + * @ehdr: ELF header of module to iterate + */ +#define elf_for_each_section(shdr, ehdr) \ + for ((shdr) = elf_first_section((ehdr)); \ + (shdr); \ + (shdr) = elf_next_section((shdr), (ehdr))) + +/** + * elf_first_section_with_type - first section with given type + * @type: type of section to search for + * @ehdr: ELF header of module to search + * + * Return: pointer to the first occurrence of the section, or %NULL if it does + * not exist + */ +static const struct elf32_shdr *elf_first_section_with_type( + Elf32_Word type, const struct elf32_hdr *ehdr) +{ + const struct elf32_shdr *shdr; + + elf_for_each_section (shdr, ehdr) + if (shdr->sh_type == type) + return shdr; + + return NULL; +} + +/** + * elf_identify - does the buffer contain an ELF object? + * @buffer: pointer to data to identify + * @size: size in bytes of buffer + * + * Return: %true if the buffer looks like an ELF object, otherwise %false + */ +static bool elf_identify(const void *buffer, size_t size) +{ + const struct elf32_hdr *ehdr = buffer; + + if (size < sizeof(*ehdr)) + return false; + + return ehdr->e_ident[EI_MAG0] == ELFMAG0 && + ehdr->e_ident[EI_MAG1] == ELFMAG1 && + ehdr->e_ident[EI_MAG2] == ELFMAG2 && + ehdr->e_ident[EI_MAG3] == ELFMAG3 && + ehdr->e_ident[EI_VERSION] == EV_CURRENT; +} + +/** + * irx_iopmod - give .iopmod section pointer, if it exists + * @ehdr: ELF header of module + * + * The .iopmod section is specific to IOP (IRX) modules. + * + * Return: .iopmod section pointer, or %NULL + */ +static const struct irx_iopmod *irx_iopmod(const struct elf32_hdr *ehdr) +{ + const struct elf32_shdr *shdr = + elf_first_section_with_type(SHT_IOPMOD, ehdr); + + return shdr ? elf_ent_for_offset(shdr->sh_offset, ehdr) : NULL; +} /** * major_version - major version of version in BCD @@ -92,6 +226,18 @@ static unsigned int minor_version(unsigned int version) return bcd2bin(version & 0xff); } +/** + * irx_identify - does the buffer contain an IRX object? + * @buffer: pointer to data to identify + * @size: size in bytes of buffer + * + * Return: %true if the buffer looks like an IRX object, otherwise %false + */ +static bool irx_identify(const void *buffer, size_t size) +{ + return elf_identify(buffer, size) && irx_iopmod(buffer) != NULL; +} + /** * iop_module_link_buffer - link IOP module given in buffer * @buf: buffer containing the IOP module to link @@ -189,10 +335,18 @@ static int iop_module_request_firmware( if (err < 0) goto err_request; + if (!irx_identify(fw->data, fw->size)) { + pr_err("iop-module: %s module is not an IRX object\n", + filepath); + err = -ENOEXEC; + goto err_identify; + } + ehdr = (const struct elf32_hdr *)fw->data; err = iop_module_link_buffer(fw->data, fw->size, arg); +err_identify: err_request: err_name: From patchwork Sun Sep 1 16:11:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125463 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 59F2114DE for ; Sun, 1 Sep 2019 16:11:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 422EA233A2 for ; Sun, 1 Sep 2019 16:11:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728877AbfIAQLd (ORCPT ); Sun, 1 Sep 2019 12:11:33 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:59680 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAQLc (ORCPT ); Sun, 1 Sep 2019 12:11:32 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 2F9133F52B for ; Sun, 1 Sep 2019 18:11:31 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4T9eZSUFd1WE for ; Sun, 1 Sep 2019 18:11:30 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 7F8653F53F for ; Sun, 1 Sep 2019 18:11:30 +0200 (CEST) Date: Sun, 1 Sep 2019 18:11:30 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 069/120] MIPS: PS2: IOP: Module version compatibility verification Message-ID: <83c5eb267a56f26ff166ece6c8d9fbf56f0b875f.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org IOP module link requests are only permitted if the major versions match and the module version is at least of the same minor as the requested version. The IOP module version is read from the special .iopmod section. Signed-off-by: Fredrik Noring --- drivers/ps2/iop-module.c | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/ps2/iop-module.c b/drivers/ps2/iop-module.c index d332a7d1af60..532b3cce91c0 100644 --- a/drivers/ps2/iop-module.c +++ b/drivers/ps2/iop-module.c @@ -12,6 +12,10 @@ * (ELF). All valid IOP modules have a special `.iopmod` section containing * the module name, version, etc. * + * IOP module link requests are only permitted if the major versions match + * and the module version is at least of the same minor as the requested + * version. + * * When the IOP is reset, a set of modules are automatically linked from * read-only memory (ROM). Non-ROM modules are handled as firmware by the * IOP module linker. @@ -226,6 +230,34 @@ static unsigned int minor_version(unsigned int version) return bcd2bin(version & 0xff); } +/** + * version_compatible - is the version compatible with the requested version? + * @version: version to check + * @version_request: requested version + * + * Return: %true if the major versions match and the version to check is at + * least of the same minor as the requested version, otherwise %false + */ +static bool version_compatible(int version, int requested_version) +{ + return major_version(version) == major_version(requested_version) && + minor_version(version) >= minor_version(requested_version); +} + +/** + * irx_version_compatible - is the module compatible with the requested version? + * @ehdr: ELF header of module to check + * @requested_version: request version + * + * Return: %true if the major versions match and the module version is at + * least of the same minor as the requested version, otherwise %false + */ +static bool irx_version_compatible(const struct elf32_hdr *ehdr, + int requested_version) +{ + return version_compatible(irx_iopmod(ehdr)->version, requested_version); +} + /** * irx_identify - does the buffer contain an IRX object? * @buffer: pointer to data to identify @@ -344,8 +376,20 @@ static int iop_module_request_firmware( ehdr = (const struct elf32_hdr *)fw->data; + if (!irx_version_compatible(ehdr, version)) { + pr_err("iop-module: %s module version %u.%u is incompatible with requested version %u.%u\n", + filepath, + major_version(irx_iopmod(ehdr)->version), + minor_version(irx_iopmod(ehdr)->version), + major_version(version), + minor_version(version)); + err = -ENOEXEC; + goto err_incompatible; + } + err = iop_module_link_buffer(fw->data, fw->size, arg); +err_incompatible: err_identify: err_request: err_name: From patchwork Sun Sep 1 16:11:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125465 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3907814E5 for ; Sun, 1 Sep 2019 16:11:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1684E21872 for ; Sun, 1 Sep 2019 16:11:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728912AbfIAQLx (ORCPT ); Sun, 1 Sep 2019 12:11:53 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:59704 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAQLx (ORCPT ); Sun, 1 Sep 2019 12:11:53 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 0DEEF3FC34 for ; Sun, 1 Sep 2019 18:11:50 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3rd1GH9mSbm4 for ; Sun, 1 Sep 2019 18:11:49 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 36DBF3F53F for ; Sun, 1 Sep 2019 18:11:49 +0200 (CEST) Date: Sun, 1 Sep 2019 18:11:49 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 070/120] MIPS: PS2: IOP: Avoid linking already linked library modules Message-ID: <7030b6576dad761807bcaf047c9dda404a6d1016.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org As a simplification the IOP module linker assumes that modules with exported libraries are resident. The primary effect is that it refuses to link modules exporting libraries with the same names more than once, even if the they may have been unlinked in the IOP. This is because the IOP module linker maintains its own list of exported libraries, rather than asking the IOP about them, which remains to be implemented. For now it is assumed that modules do not unlink themselves. The IOP module linker also assumes that if a module exports a library it has the same name as the module. The simplifies resolving dependencies. In general, and with most ROM modules, the module name is not the same as the exported library names. A single module may export multiple libraries, but that is currently not not fully supported with IOP modules for Linux, due to dependency resolving limitations. Signed-off-by: Fredrik Noring --- drivers/ps2/iop-module.c | 282 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) diff --git a/drivers/ps2/iop-module.c b/drivers/ps2/iop-module.c index 532b3cce91c0..ef7b254bb2cf 100644 --- a/drivers/ps2/iop-module.c +++ b/drivers/ps2/iop-module.c @@ -29,6 +29,20 @@ * The modules can either stay resident in the IOP, and provide services, or * unlink themselves when exiting the entry function. Many modules provide * remote procedure call (RPC) services via the sub-system interface (SIF). + * + * As a simplification the IOP module linker assumes that modules with + * exported libraries are resident. The primary effect is that it refuses to + * link modules exporting libraries with the same names more than once, even + * if the they may have been unlinked in the IOP. This is because the IOP + * module linker maintains its own list of exported libraries, rather than + * asking the IOP about them, which remains to be implemented. + * + * The IOP module linker also assumes that if a module exports a library it + * has the same name as the module. The simplifies resolving dependencies. In + * general, and with most ROM modules, the module name is not the same as the + * exported library names. A single module may export multiple libraries, but + * that is currently not not fully supported with IOP modules for Linux, due + * to dependency resolving limitations. */ #include @@ -70,12 +84,15 @@ static DEFINE_MUTEX(iop_module_lock); static struct device *iop_module_device; static struct sif_rpc_client load_file_rpc_client; +static LIST_HEAD(linked_libraries); #define IOPMOD_MAX_PATH 252 #define IOPMOD_MAX_ARG 252 #define IOPMOD_MAX_LIBRARY_NAME 8 #define IOPMOD_NO_ID 0xffffffff +#define IOPMOD_IMPORT_MAGIC 0x41e00000 +#define IOPMOD_EXPORT_MAGIC 0x41c00000 #define SHT_IOPMOD (SHT_LOPROC + 0x80) @@ -101,6 +118,93 @@ struct irx_iopmod { char name[0]; }; +/** + * struct irx_import_link - link entry for an imported library + * @jr: unconditional MIPS I jump to return address instruction + * @jr.target: jump target, to be resolved by the IOP linker + * @jr.op: operation code for the jump register instruction + * @li: 16-bit load immediate pseudo-instruction + * @li.imm: index of the imported library link entry + * @li.rt: `$0` register + * @li.rs: `$0` register + * @li.op: operation code for the load immediate pseudo-instruction + */ +struct irx_import_link { + struct { + u32 target : 26; + u32 op : 6; + } jr; + struct { + u32 imm : 16; + u32 rt : 5; + u32 rs : 5; + u32 op : 6; + } li; +}; + +/** + * struct irx_import_library - link entry table for an imported library + * @magic: %IOPMOD_IMPORT_MAGIC marks the beginning of the link entry table + * @zero: always zero + * @version: 16-bit version in BCD, with 8-bit minor and 8-bit major + * @name: library name, not NUL terminated unless shorter than + * %IOPMOD_MAX_LIBRARY_NAME characters + * @link: array of imported link entries, with the terminating entry zero + * + * The &struct irx_import_library resides in the .text section of the module. + */ +struct irx_import_library { + u32 magic; + u32 zero; + u32 version; + char name[IOPMOD_MAX_LIBRARY_NAME]; + struct irx_import_link link[0]; +}; + +/** + * struct irx_export_link - link entry for an exported library + * @addr: address to link + */ +struct irx_export_link { + u32 addr; +}; + +/** + * struct irx_export_library - link entry table for an exported library + * @magic: %IOPMOD_EXPORT_MAGIC marks the beginning of the link entry table + * @zero: always zero + * @version: 16-bit version in BCD, with 8-bit minor and 8-bit major + * @name: library name, not NUL terminated unless shorter than + * %IOPMOD_MAX_LIBRARY_NAME characters + * @link: array of exported link entries, with the terminating entry zero + * + * The &struct irx_export_library resides in the .text section of the module. + */ +struct irx_export_library { + u32 magic; + u32 zero; + u32 version; + char name[IOPMOD_MAX_LIBRARY_NAME]; + struct irx_export_link link[0]; +}; + +/** + * struct library_entry - list of linked libraries + * @list: linked list of library entries + * @name: library name, not NUL terminated unless shorter than + * %IOPMOD_MAX_LIBRARY_NAME characters + * @version: 16-bit version in BCD, with 8-bit minor and 8-bit major + * + * The IOP module linker maintains its own list of linked libraries, rather + * than asking the IOP about them, which remains to be implemented. + */ +struct library_entry { + struct list_head list; + + char name[IOPMOD_MAX_LIBRARY_NAME]; + int version; +}; + /** * elf_ent_for_offset - pointer given an ELF offset * @offset: ELF offset @@ -151,6 +255,37 @@ static const struct elf32_shdr *elf_next_section( (shdr); \ (shdr) = elf_next_section((shdr), (ehdr))) +/** + * elf_strings - base of ELF module string table + * @ehdr: ELF header of module + * + * Return: pointer to base of ELF module table + */ +static const char *elf_strings(const struct elf32_hdr *ehdr) +{ + const struct elf32_shdr *shdr; + + if (ehdr->e_shstrndx == SHN_UNDEF) + return NULL; + + shdr = &elf_first_section(ehdr)[ehdr->e_shstrndx]; + + return elf_ent_for_offset(shdr->sh_offset, ehdr); +} + +/** + * elf_section_name - name of section + * @shdr: header of section to provide name for + * @ehdr: ELF header of module for section + * + * Return: name of given section + */ +static const char *elf_section_name(const struct elf32_shdr *shdr, + const struct elf32_hdr *ehdr) +{ + return &elf_strings(ehdr)[shdr->sh_name]; +} + /** * elf_first_section_with_type - first section with given type * @type: type of section to search for @@ -171,6 +306,26 @@ static const struct elf32_shdr *elf_first_section_with_type( return NULL; } +/** + * elf_first_section_with_name - first section with given name + * @name: name of section to search for + * @ehdr: ELF header of module to search + * + * Return: pointer to the first occurrence of the section, or %NULL if it does + * not exist + */ +static const struct elf32_shdr *elf_first_section_with_name( + const char *name, const struct elf32_hdr *ehdr) +{ + const struct elf32_shdr *shdr; + + elf_for_each_section (shdr, ehdr) + if (strcmp(elf_section_name(shdr, ehdr), name) == 0) + return shdr; + + return NULL; +} + /** * elf_identify - does the buffer contain an ELF object? * @buffer: pointer to data to identify @@ -192,6 +347,69 @@ static bool elf_identify(const void *buffer, size_t size) ehdr->e_ident[EI_VERSION] == EV_CURRENT; } +/** + * library_entry - find occurrence of 4-byte magic integer + * @library: import or export library starting pointer + * @magic: 4-byte magic integer to search for + * @ehdr: ELF header of module to search + * + * The %IOPMOD_IMPORT_MAGIC and %IOPMOD_EXPORT_MAGIC 4-byte integers are used + * to mark libraries that are imported and exported by the module. + * + * Return: library entry following the current library entry, or %NULL + */ +static const void *library_entry(const void *library, u32 magic, + const struct elf32_hdr *ehdr) +{ + const struct elf32_shdr *shdr = + elf_first_section_with_name(".text", ehdr); + const u32 *text = elf_ent_for_offset(shdr->sh_offset, ehdr); + const size_t length = shdr->sh_size / sizeof(*text); + const size_t index = library ? ((u32 *)library - text) + 1 : 0; + size_t i; + + for (i = index; i < length; i++) + if (text[i] == magic) + return &text[i]; + + return NULL; +} + +/** + * irx_first_export_library - first exported library entry + * @ehdr: ELF header of module + * + * Return: first exported library entry, or %NULL + */ +static const struct irx_export_library *irx_first_export_library( + const struct elf32_hdr *ehdr) +{ + return library_entry(NULL, IOPMOD_EXPORT_MAGIC, ehdr); +} + +/** + * irx_next_export_library - next exported library entry + * @library: current library entry + * @ehdr: ELF header of module + * + * Return: exported library entry following the current library entry, or %NULL + */ +static const struct irx_export_library *irx_next_export_library( + const struct irx_export_library *library, const struct elf32_hdr *ehdr) +{ + return library_entry(library, IOPMOD_EXPORT_MAGIC, ehdr); +} + +/** + * irx_for_each_export_library - iterate over exported libraries + * @library: &struct irx_export_library loop cursor + * @ehdr: ELF header of module to iterate + */ +#define irx_for_each_export_library(library, ehdr) \ + for ((library) = irx_first_export_library(ehdr); \ + (library); \ + (library) = irx_next_export_library((library), (ehdr))) + /** * irx_iopmod - give .iopmod section pointer, if it exists * @ehdr: ELF header of module @@ -270,6 +488,58 @@ static bool irx_identify(const void *buffer, size_t size) return elf_identify(buffer, size) && irx_iopmod(buffer) != NULL; } +/** + * library_provided_by_firmware - is the library provided by linked firmware? + * @name: name of the library to search for + * + * Return: %true if some previously linked firmware provides the library, + * otherwise %false + */ +static bool library_provided_by_firmware(const char *name) +{ + const struct library_entry *library; + + list_for_each_entry (library, &linked_libraries, list) + if (strncmp(name, library->name, sizeof(library->name)) == 0) + return true; + + return false; +} + +/** + * register_libraries - register libraries provided by the given module + * @ehdr: IOP module + * + * FIXME: Libraries are maintained in a linked list by the kernel as a + * simplification. This list is not updated if the modules providing the + * libraries are unlinked. In principle one could query the IOP about its + * modules, but that has not been implemented yet. For now it is assumed + * the modules do not unlink themselves. + * + * Return: 0 on success, otherwise a negative error number + */ +static int register_libraries(const struct elf32_hdr *ehdr) +{ + const struct irx_export_library *library; + + irx_for_each_export_library (library, ehdr) { + struct library_entry *entry = + kmalloc(sizeof(*entry), GFP_KERNEL); + + if (!entry) + return -ENOMEM; + + *entry = (struct library_entry) { + .version = library->version, + }; + memcpy(entry->name, library->name, IOPMOD_MAX_LIBRARY_NAME); + + list_add(&entry->list, &linked_libraries); + } + + return 0; +} + /** * iop_module_link_buffer - link IOP module given in buffer * @buf: buffer containing the IOP module to link @@ -327,9 +597,16 @@ static int iop_module_link_buffer(const void *buf, size_t nbyte, goto err_out; } + err = register_libraries(buf); + if (err < 0) + goto err_libraries; + iop_free(link.addr); return 0; +err_libraries: + /* FIXME: Unlink module here */ + err_out: iop_free(link.addr); return err; @@ -355,6 +632,11 @@ static int iop_module_request_firmware( char filepath[32]; int err; + if (library_provided_by_firmware(name)) { + pr_debug("iop-module: %s module is already provided\n", name); + return 0; + } + pr_debug("iop-module: %s module linking as firmware\n", name); if (snprintf(filepath, sizeof(filepath), From patchwork Sun Sep 1 16:12:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125467 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 21FDB14DE for ; Sun, 1 Sep 2019 16:12:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 00F34233A2 for ; Sun, 1 Sep 2019 16:12:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728952AbfIAQME (ORCPT ); Sun, 1 Sep 2019 12:12:04 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:59714 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAQME (ORCPT ); Sun, 1 Sep 2019 12:12:04 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 472053FC34 for ; Sun, 1 Sep 2019 18:12:02 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DqmCMQl7jYQL for ; Sun, 1 Sep 2019 18:12:01 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 8AA0F3F53F for ; Sun, 1 Sep 2019 18:12:01 +0200 (CEST) Date: Sun, 1 Sep 2019 18:12:01 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 071/120] MIPS: PS2: IOP: Resolve module dependencies Message-ID: <94f1123ecafe2bab02de14ba3e516a957ee16c34.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org As a simplification it is assumed that if a ROM file provides the given library dependency, then the ROM file has been prelinked into the IOP. Hopefully, ROM file dependencies will be kept to a minimum, and new modules are instead tailored for Linux. Signed-off-by: Fredrik Noring --- drivers/ps2/iop-module.c | 166 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/drivers/ps2/iop-module.c b/drivers/ps2/iop-module.c index ef7b254bb2cf..bb4814b5d3c4 100644 --- a/drivers/ps2/iop-module.c +++ b/drivers/ps2/iop-module.c @@ -375,6 +375,64 @@ static const void *library_entry(const void *library, u32 magic, return NULL; } +/** + * irx_first_import_library - first imported library entry + * @ehdr: ELF header of module + * + * Return: first imported library entry, or %NULL + */ +static const struct irx_import_library *irx_first_import_library( + const struct elf32_hdr *ehdr) +{ + return library_entry(NULL, IOPMOD_IMPORT_MAGIC, ehdr); +} + +/** + * same_import_library - are the two imported libraries the same? + * @a: first imported library + * @b: second imported library + * + * Return: %true if the libraries have the same name, otherwise %false + */ +static bool same_import_library( + const struct irx_import_library *a, + const struct irx_import_library *b) +{ + return strncmp(a->name, b->name, sizeof(a->name)) == 0; +} + +/** + * irx_next_import_library - next imported library entry + * @library: current library entry + * @ehdr: ELF header of module + * + * Return: imported library entry following the current library entry, or %NULL + */ +static const struct irx_import_library *irx_next_import_library( + const struct irx_import_library *library, const struct elf32_hdr *ehdr) +{ + const struct irx_import_library *next = library; + + while (next) { + if (!same_import_library(next, library)) + return next; + + next = library_entry(next, IOPMOD_IMPORT_MAGIC, ehdr); + } + + return next; +} + +/** + * irx_for_each_import_library - iterate over imported libraries + * @library: &struct irx_import_library loop cursor + * @ehdr: ELF header of module to iterate + */ +#define irx_for_each_import_library(library, ehdr) \ + for ((library) = irx_first_import_library((ehdr)); \ + (library); \ + (library) = irx_next_import_library((library), (ehdr))) + /** * irx_first_export_library - first exported library entry * @ehdr: ELF header of module @@ -488,6 +546,45 @@ static bool irx_identify(const void *buffer, size_t size) return elf_identify(buffer, size) && irx_iopmod(buffer) != NULL; } +/** + * library_provided_by_module - is the library provided by the module? + * @name: name of the library to search for + * @ehdr: ELF header of module + * + * Return: %true if the module provides the library, otherwise %false + */ +static bool library_provided_by_module(const char *name, + const struct elf32_hdr *ehdr) +{ + const struct irx_export_library *library; + + irx_for_each_export_library (library, ehdr) + if (strncmp(name, library->name, sizeof(library->name)) == 0) + return true; + + return false; +} + +/** + * library_provided_by_rom - is the library provided by the ROM directory? + * @name: name of the library to search for + * @dir: ROM directory + * + * Return: %true if some ROM file in the ROM directory provides the library, + * otherwise %false + */ +static bool library_provided_by_rom(const char *name, const struct rom_dir dir) +{ + struct rom_file file; + + rom_for_each_file (file, dir) + if (irx_identify(file.data, file.size)) + if (library_provided_by_module(name, file.data)) + return true; + + return false; +} + /** * library_provided_by_firmware - is the library provided by linked firmware? * @name: name of the library to search for @@ -506,6 +603,24 @@ static bool library_provided_by_firmware(const char *name) return false; } +/** + * library_provided - is the library provided? + * @name: name of the library to search for + * + * As a simplification it is assumed that if a ROM file provides the given + * library, then the ROM file has been prelinked into the IOP. + * + * The IOP linker will deal with issues related to version compatibility. + * + * Return: %true if the library is provided, otherwise %false + */ +static bool library_provided(const char *name) +{ + return library_provided_by_rom(name, rom0_dir) || + library_provided_by_rom(name, rom1_dir) || + library_provided_by_firmware(name); +} + /** * register_libraries - register libraries provided by the given module * @ehdr: IOP module @@ -615,6 +730,52 @@ static int iop_module_link_buffer(const void *buf, size_t nbyte, static int iop_module_request_firmware( const char *name, int version, const char *arg); +/** + * iop_module_request_dependencies - resolve and prelink dependencies for + * requested IOP module + * @ehdr: IOP module to request dependencies for + * @requesting_name: name of IOP module requesting dependencies + * + * Return: 0 on success, otherwise a negative error number + */ +static int iop_module_request_dependencies(const struct elf32_hdr *ehdr, + const char *requesting_name) +{ + const struct irx_import_library *library; + + irx_for_each_import_library (library, ehdr) { + char library_name[sizeof(library->name) + 1] = { }; + int err; + + /* Convert the library name to a NUL-terminated string. */ + memcpy(library_name, library->name, sizeof(library->name)); + + if (library_provided(library_name)) { + pr_debug("iop-module: %s dependency on %s provided\n", + requesting_name, library_name); + continue; + } + + pr_debug("iop-module: %s module depends on %s library version %u.%u\n", + requesting_name, library_name, + major_version(library->version), + minor_version(library->version)); + + err = iop_module_request_firmware( + library_name, library->version, NULL); + if (err < 0) { + pr_err("iop-module: %s dependency on %s failed to resolve with %d\n", + requesting_name, library_name, err); + return err; + } + + pr_debug("iop-module: %s dependency on %s resolved\n", + requesting_name, library_name); + } + + return 0; +} + /** * iop_module_request_firmware - link IOP module as firmware * @name: name of requested module @@ -669,8 +830,13 @@ static int iop_module_request_firmware( goto err_incompatible; } + err = iop_module_request_dependencies(ehdr, name); + if (err < 0) + goto err_dependency; + err = iop_module_link_buffer(fw->data, fw->size, arg); +err_dependency: err_incompatible: err_identify: err_request: From patchwork Sun Sep 1 16:12:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125469 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 82CD714DE for ; Sun, 1 Sep 2019 16:12:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6B98E233A2 for ; Sun, 1 Sep 2019 16:12:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728961AbfIAQMP (ORCPT ); Sun, 1 Sep 2019 12:12:15 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:58630 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbfIAQMP (ORCPT ); Sun, 1 Sep 2019 12:12:15 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 70D1D3F752 for ; Sun, 1 Sep 2019 18:12:13 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YtAymFzjaPTx for ; Sun, 1 Sep 2019 18:12:12 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id C1A913F73E for ; Sun, 1 Sep 2019 18:12:12 +0200 (CEST) Date: Sun, 1 Sep 2019 18:12:12 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 072/120] MIPS: PS2: IOP: SIF printk command support Message-ID: <53102a0102944d3c118f5cfc8cda3210284f59d6.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Allow IOP modules to print kernel messages, with kernel log levels. This greatly simplifies debugging of subsequent IOP modules. IOP messages are prefixed with "iop: " in the kernel log. Signed-off-by: Fredrik Noring --- drivers/ps2/iop-module.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/ps2/iop-module.c b/drivers/ps2/iop-module.c index bb4814b5d3c4..18020b3673d3 100644 --- a/drivers/ps2/iop-module.c +++ b/drivers/ps2/iop-module.c @@ -892,6 +892,30 @@ int iop_module_request(const char *name, int version, const char *arg) } EXPORT_SYMBOL_GPL(iop_module_request); +/** + * cmd_printk - IOP module kernel log printk command + * @header: SIF command header + * @void: message to print + * @arg: optional argument to sif_request_cmd, set to %NULL + * + * The command allows IOP modules to print kernel messages, with kernel log + * levels. This greatly simplifies debugging of subsequent IOP modules. IOP + * messages are prefixed with "iop: " in the kernel log. + */ +static void cmd_printk(const struct sif_cmd_header *header, + const void *data, void *arg) +{ + const char *msg = data; + + if (msg[0] == KERN_SOH[0]) { + const char fmt[] = { msg[0], msg[1], + 'i', 'o', 'p', ':', ' ', '%', 's', '\0' }; + + printk(fmt, &msg[2]); + } else + printk("iop: %s", msg); +} + static int __init iop_module_init(void) { int err; @@ -902,6 +926,12 @@ static int __init iop_module_init(void) return -ENOMEM; } + err = sif_request_cmd(SIF_CMD_PRINTK, cmd_printk, NULL); + if (err < 0) { + pr_err("iop-module: Failed request printk cmd with %d\n", err); + goto err_printk; + } + err = sif_rpc_bind(&load_file_rpc_client, SIF_SID_LOAD_MODULE); if (err < 0) { pr_err("iop-module: Failed to bind load module with %d\n", err); @@ -910,6 +940,7 @@ static int __init iop_module_init(void) return 0; +err_printk: err_bind: root_device_unregister(iop_module_device); From patchwork Sun Sep 1 16:16:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125483 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0D2271399 for ; Sun, 1 Sep 2019 16:16:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E97C9233A2 for ; Sun, 1 Sep 2019 16:16:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728863AbfIAQQZ (ORCPT ); Sun, 1 Sep 2019 12:16:25 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:43984 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728848AbfIAQQZ (ORCPT ); Sun, 1 Sep 2019 12:16:25 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id D28733F63C for ; Sun, 1 Sep 2019 18:16:22 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sqZkzGQXo5OL for ; Sun, 1 Sep 2019 18:16:22 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 292CD3F58C for ; Sun, 1 Sep 2019 18:16:22 +0200 (CEST) Date: Sun, 1 Sep 2019 18:16:21 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 073/120] MIPS: PS2: IOP: Heap memory allocate and free Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The IOP heap memory operations are serviced by an IOP module linked from read-only memory (ROM). Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/iop-heap.h | 19 +++++ drivers/ps2/Makefile | 1 + drivers/ps2/iop-heap.c | 90 +++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/iop-heap.h create mode 100644 drivers/ps2/iop-heap.c diff --git a/arch/mips/include/asm/mach-ps2/iop-heap.h b/arch/mips/include/asm/mach-ps2/iop-heap.h new file mode 100644 index 000000000000..ee96e2ffba83 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/iop-heap.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) heap memory + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_IOP_HEAP_H +#define __ASM_MACH_PS2_IOP_HEAP_H + +#include + +#include + +iop_addr_t iop_alloc(size_t nbyte); + +int iop_free(iop_addr_t baddr); + +#endif /* __ASM_MACH_PS2_IOP_HEAP_H */ diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index b04e4d3c3374..02a5756cb059 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,3 +1,4 @@ +obj-m += iop-heap.o obj-m += iop-memory.o obj-m += iop-module.o obj-m += iop-registers.o diff --git a/drivers/ps2/iop-heap.c b/drivers/ps2/iop-heap.c new file mode 100644 index 000000000000..f803401f59e5 --- /dev/null +++ b/drivers/ps2/iop-heap.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) heap memory + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include + +#include +#include +#include + +/** + * enum iop_heap_rpc_ops - I/O processor (IOP) heap RPC operations + * @rpo_alloc: allocate IOP memory + * @rpo_free: free IOP memory + * @rpo_load: FIXME + */ +enum iop_heap_rpc_ops { + rpo_alloc = 1, + rpo_free = 2, + rpo_load = 3, +}; + +static struct sif_rpc_client iop_heap_rpc; + +/** + * iop_alloc - allocate IOP memory + * @nbyte: number of bytes to allocate + * + * Context: sleep + * Return: IOP address, or zero if the allocation failed + */ +iop_addr_t iop_alloc(size_t nbyte) +{ + const u32 size_arg = nbyte; + u32 iop_addr; + + if (size_arg != nbyte) + return 0; + + return sif_rpc(&iop_heap_rpc, rpo_alloc, + &size_arg, sizeof(size_arg), + &iop_addr, sizeof(iop_addr)) < 0 ? 0 : iop_addr; +} +EXPORT_SYMBOL(iop_alloc); + +/** + * iop_free - free previously allocated IOP memory + * @baddr: IOP address, or zero + * + * Context: sleep + * Return: 0 on success, otherwise a negative error number + */ +int iop_free(iop_addr_t baddr) +{ + const u32 addr_arg = baddr; + s32 status; + int err; + + if (!baddr) + return 0; + + err = sif_rpc(&iop_heap_rpc, rpo_free, + &addr_arg, sizeof(addr_arg), + &status, sizeof(status)); + + return err < 0 ? err : errno_for_iop_error(status); +} +EXPORT_SYMBOL(iop_free); + +static int __init iop_heap_init(void) +{ + return sif_rpc_bind(&iop_heap_rpc, SIF_SID_HEAP); +} + +static void __exit iop_heap_exit(void) +{ + sif_rpc_unbind(&iop_heap_rpc); +} + +module_init(iop_heap_init); +module_exit(iop_heap_exit); + +MODULE_DESCRIPTION("PlayStation 2 input/output processor (IOP) heap memory"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:16:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125485 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 047BE1399 for ; Sun, 1 Sep 2019 16:16:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DFE1F233A2 for ; Sun, 1 Sep 2019 16:16:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728877AbfIAQQm (ORCPT ); Sun, 1 Sep 2019 12:16:42 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44044 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728874AbfIAQQm (ORCPT ); Sun, 1 Sep 2019 12:16:42 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id CE12D3F63C for ; Sun, 1 Sep 2019 18:16:40 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id k6V134FyPbiP for ; Sun, 1 Sep 2019 18:16:40 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 39B563F58C for ; Sun, 1 Sep 2019 18:16:40 +0200 (CEST) Date: Sun, 1 Sep 2019 18:16:40 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 074/120] MIPS: PS2: SIF: Request RPC IRQ command Message-ID: <109dfd3e0eee7af923c8451c8f0e1f8f665375f1.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/irq.h | 5 +++++ arch/mips/ps2/intc-irq.c | 6 ++++++ drivers/ps2/sif.c | 11 +++++++++++ 3 files changed, 22 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/irq.h b/arch/mips/include/asm/mach-ps2/irq.h index 16c96aa7ca09..64d3fbf4789e 100644 --- a/arch/mips/include/asm/mach-ps2/irq.h +++ b/arch/mips/include/asm/mach-ps2/irq.h @@ -74,4 +74,9 @@ int __init intc_irq_init(void); int __init dmac_irq_init(void); +/* + * IRQs asserted by the I/O processor (IOP) via the sub-system interface (SIF). + */ +void intc_sif_irq(unsigned int irq); + #endif /* __ASM_MACH_PS2_IRQ_H */ diff --git a/arch/mips/ps2/intc-irq.c b/arch/mips/ps2/intc-irq.c index 36cdc3dd31ca..08659758e85f 100644 --- a/arch/mips/ps2/intc-irq.c +++ b/arch/mips/ps2/intc-irq.c @@ -85,6 +85,12 @@ static struct irqaction cascade_intc_irqaction = { .handler = intc_cascade, }; +void intc_sif_irq(unsigned int irq) +{ + do_IRQ(irq); +} +EXPORT_SYMBOL_GPL(intc_sif_irq); + int __init intc_irq_init(void) { size_t i; diff --git a/drivers/ps2/sif.c b/drivers/ps2/sif.c index 5c3866c460af..a7f4f00a539c 100644 --- a/drivers/ps2/sif.c +++ b/drivers/ps2/sif.c @@ -568,6 +568,16 @@ int sif_request_cmd(u32 cmd_id, sif_cmd_cb cb, void *arg) } EXPORT_SYMBOL_GPL(sif_request_cmd); +static void cmd_irq_relay(const struct sif_cmd_header *header, + const void *data, void *arg) +{ + const struct { + u32 irq; + } *packet = data; + + intc_sif_irq(packet->irq); +} + static int iop_reset_arg(const char *arg) { const size_t arglen = strlen(arg) + 1; @@ -664,6 +674,7 @@ static int sif_request_cmds(void) struct cmd_data *arg; } cmds[] = { { SIF_CMD_WRITE_SREG, cmd_write_sreg, NULL }, + { SIF_CMD_IRQ_RELAY, cmd_irq_relay, NULL }, { SIF_CMD_RPC_END, cmd_rpc_end, NULL }, { SIF_CMD_RPC_BIND, cmd_rpc_bind, NULL }, From patchwork Sun Sep 1 16:17:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125487 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A40B13B1 for ; Sun, 1 Sep 2019 16:17:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 178A9233A2 for ; Sun, 1 Sep 2019 16:17:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728775AbfIAQRT (ORCPT ); Sun, 1 Sep 2019 12:17:19 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:59124 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAQRT (ORCPT ); Sun, 1 Sep 2019 12:17:19 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 8F0A63F7B1 for ; Sun, 1 Sep 2019 18:17:17 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3cldcrmmP36D for ; Sun, 1 Sep 2019 18:17:16 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id A49E63F752 for ; Sun, 1 Sep 2019 18:17:16 +0200 (CEST) Date: Sun, 1 Sep 2019 18:17:16 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 075/120] MIPS: PS2: IOP: IRQ support Message-ID: <8d4f6f44a2ff5024836a7f1a152c6cd7ab6bdfa2.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org IOP interrupts are not directly available to the kernel. IOP IRQs are instead serviced by an IRQ relay module, and then forwarded to the kernel by remote procedure calls (RPCs) via the sub-system interface (SIF). The IRQ relay module can also forward IRQs via the SMFLAG (sub-to-main) register. This is more efficient, but the number of flags is limited. Currently only RPC forwarding is implemented in the kernel. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/irq.h | 49 ++++++- drivers/ps2/Makefile | 1 + drivers/ps2/iop-irq.c | 186 +++++++++++++++++++++++++++ 3 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 drivers/ps2/iop-irq.c diff --git a/arch/mips/include/asm/mach-ps2/irq.h b/arch/mips/include/asm/mach-ps2/irq.h index 64d3fbf4789e..57b3e539ad92 100644 --- a/arch/mips/include/asm/mach-ps2/irq.h +++ b/arch/mips/include/asm/mach-ps2/irq.h @@ -13,7 +13,7 @@ #define INTC_STAT 0x1000f000 /* Flags are cleared by writing 1 */ #define INTC_MASK 0x1000f010 /* Bits are reversed by writing 1 */ -#define NR_IRQS 56 +#define NR_IRQS 128 /* * The interrupt controller (INTC) arbitrates interrupts from peripheral @@ -71,6 +71,53 @@ #define IRQ_C0_DMAC 51 #define IRQ_C0_IRQ7 55 +/* Input/output processor (IOP) */ +#define IOP_IRQ_BASE 64 +#define IRQ_IOP_VBLANK 64 +#define IRQ_IOP_SBUS 65 +#define IRQ_IOP_CDVD 66 +#define IRQ_IOP_DMA 67 +#define IRQ_IOP_RTC0 68 +#define IRQ_IOP_RTC1 69 +#define IRQ_IOP_RTC2 70 +#define IRQ_IOP_SIO0 71 +#define IRQ_IOP_SIO1 72 +#define IRQ_IOP_SPU 73 +#define IRQ_IOP_PIO 74 +#define IRQ_IOP_EVBLANK 75 +#define IRQ_IOP_DVD 76 +#define IRQ_IOP_DEV9 77 +#define IRQ_IOP_RTC3 78 +#define IRQ_IOP_RTC4 79 +#define IRQ_IOP_RTC5 80 +#define IRQ_IOP_SIO2 81 +#define IRQ_IOP_HTR0 82 +#define IRQ_IOP_HTR1 83 +#define IRQ_IOP_HTR2 84 +#define IRQ_IOP_HTR3 85 +#define IRQ_IOP_USB 86 +#define IRQ_IOP_EXTR 87 +#define IRQ_IOP_ILINK 88 +#define IRQ_IOP_ILNKDMA 89 + +#define IRQ_IOP_DMAC_MDEC_IN 96 /* Ch 0 */ +#define IRQ_IOP_DMAC_MDEC_OUT 97 /* Ch 1 */ +#define IRQ_IOP_DMAC_SIF2 98 /* Ch 2 */ +#define IRQ_IOP_DMAC_CDVD 99 /* Ch 3 */ +#define IRQ_IOP_DMAC_SPU 100 /* Ch 4 */ +#define IRQ_IOP_DMAC_PIO 101 /* Ch 5 */ +#define IRQ_IOP_DMAC_GPU_OTC 102 /* Ch 6 */ +#define IRQ_IOP_DMAC_BE 103 /* Bus error */ +#define IRQ_IOP_DMAC_SPU2 104 /* Ch 7 */ +#define IRQ_IOP_DMAC_DEV9 105 /* Ch 8 */ +#define IRQ_IOP_DMAC_SIF0 106 /* Ch 9 */ +#define IRQ_IOP_DMAC_SIF1 107 /* Ch 10 */ +#define IRQ_IOP_DMAC_SIO2_IN 108 /* Ch 11 */ +#define IRQ_IOP_DMAC_SIO2_OUT 109 /* Ch 12 */ + +#define IRQ_IOP_SW1 126 /* R3000A Software Interrupt 1 */ +#define IRQ_IOP_SW2 127 /* R3000A Software Interrupt 2 */ + int __init intc_irq_init(void); int __init dmac_irq_init(void); diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index 02a5756cb059..dd00eff52ef3 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,4 +1,5 @@ obj-m += iop-heap.o +obj-m += iop-irq.o obj-m += iop-memory.o obj-m += iop-module.o obj-m += iop-registers.o diff --git a/drivers/ps2/iop-irq.c b/drivers/ps2/iop-irq.c new file mode 100644 index 000000000000..859a3f64dd00 --- /dev/null +++ b/drivers/ps2/iop-irq.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 input/output processor (IOP) IRQs + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include + +#include +#include +#include + +/** + * enum iop_irq_relay_rpc_ops - IOP IRQ relay RPC operations + * @rpo_request_irq: request IRQ mapping + * @rpo_release_irq: release IRQ mapping + * @rpo_remap_irq: remap existing IRQ mapping + */ +enum iop_irq_relay_rpc_ops { + rpo_request_irq = 1, + rpo_release_irq = 2, + rpo_remap_irq = 3, +}; + +/** + * struct iop_rpc_relay_map - IOP IRQ relay mapping + * @u8 iop: IOP IRQ map source + * @u8 map: main IRQ map target + * @u8 rpc: %true for RPC relay, %false for SMFLAG relay + */ +struct iop_rpc_relay_map { + u8 iop; + u8 map; + u8 rpc; +}; + +/** + * struct iop_rpc_relay_release - IOP IRQ relay to release + * @iop: IOP IRQ to release mapping for + */ +struct iop_rpc_relay_release { + u8 iop; +}; + +static struct sif_rpc_client iop_irq_rpc; + +static unsigned int iop_irq_startup(struct irq_data *data) +{ + static bool irq_relay = false; + + const struct iop_rpc_relay_map arg = { + .iop = data->irq - IOP_IRQ_BASE, + .map = data->irq, + .rpc = true, /* FIXME: Also implement SMFLAG relay */ + }; + s32 status; + int err; + + BUG_ON(in_irq()); + + if (!irq_relay) { + int id; + + /* + * The main reason for requesting the IOP IRQ relay module here + * instead of in irqrelay_init() is that now the console may be + * visible to print messages if there are problems. + */ + id = iop_module_request("irqrelay", 0x0100, NULL); + if (id < 0) + return id; + + err = sif_rpc_bind(&iop_irq_rpc, SIF_SID_IRQ_RELAY); + if (err < 0) { + pr_err("%s: sif_rpc_bind failed with %d\n", + __func__, err); + return err; + } + + irq_relay = true; + } + + err = sif_rpc(&iop_irq_rpc, rpo_request_irq, + &arg, sizeof(arg), + &status, sizeof(status)); + + pr_debug("%s: err %d status %d\n", __func__, err, status); + + return err < 0 ? err : status; +} + +static void iop_irq_shutdown(struct irq_data *data) +{ + const struct iop_rpc_relay_release arg = { + .iop = data->irq - IOP_IRQ_BASE, + }; + s32 status; + int err; + + BUG_ON(in_irq()); + + err = sif_rpc(&iop_irq_rpc, rpo_release_irq, + &arg, sizeof(arg), + &status, sizeof(status)); + + pr_debug("%s: err %d status %d\n", __func__, err, status); +} + +#define IOP_IRQ_TYPE(irq_, name_) \ + { \ + .irq = irq_, \ + .irq_chip = { \ + .name = name_, \ + .irq_startup = iop_irq_startup, \ + .irq_shutdown = iop_irq_shutdown, \ + } \ + } + +static struct { + unsigned int irq; + struct irq_chip irq_chip; +} iop_irqs[] = { + IOP_IRQ_TYPE(IRQ_IOP_VBLANK, "IOP VBLANK"), + IOP_IRQ_TYPE(IRQ_IOP_SBUS, "IOP SBUS"), + IOP_IRQ_TYPE(IRQ_IOP_CDVD, "IOP CDVD"), + IOP_IRQ_TYPE(IRQ_IOP_DMA, "IOP DMA"), + IOP_IRQ_TYPE(IRQ_IOP_RTC0, "IOP RTC0"), + IOP_IRQ_TYPE(IRQ_IOP_RTC1, "IOP RTC1"), + IOP_IRQ_TYPE(IRQ_IOP_RTC2, "IOP RTC2"), + IOP_IRQ_TYPE(IRQ_IOP_SIO0, "IOP SIO0"), + IOP_IRQ_TYPE(IRQ_IOP_SIO1, "IOP SIO1"), + IOP_IRQ_TYPE(IRQ_IOP_SPU, "IOP SPU"), + IOP_IRQ_TYPE(IRQ_IOP_PIO, "IOP PIO"), + IOP_IRQ_TYPE(IRQ_IOP_EVBLANK, "IOP EVBLANK"), + IOP_IRQ_TYPE(IRQ_IOP_DVD, "IOP DVD"), + IOP_IRQ_TYPE(IRQ_IOP_DEV9, "IOP DEV9"), + IOP_IRQ_TYPE(IRQ_IOP_RTC3, "IOP RTC3"), + IOP_IRQ_TYPE(IRQ_IOP_RTC4, "IOP RTC4"), + IOP_IRQ_TYPE(IRQ_IOP_RTC5, "IOP RTC5"), + IOP_IRQ_TYPE(IRQ_IOP_SIO2, "IOP SIO2"), + IOP_IRQ_TYPE(IRQ_IOP_HTR0, "IOP HTR0"), + IOP_IRQ_TYPE(IRQ_IOP_HTR1, "IOP HTR1"), + IOP_IRQ_TYPE(IRQ_IOP_HTR2, "IOP HTR2"), + IOP_IRQ_TYPE(IRQ_IOP_HTR3, "IOP HTR3"), + IOP_IRQ_TYPE(IRQ_IOP_USB, "IOP USB"), + IOP_IRQ_TYPE(IRQ_IOP_EXTR, "IOP EXTR"), + IOP_IRQ_TYPE(IRQ_IOP_ILINK, "IOP iLink"), + IOP_IRQ_TYPE(IRQ_IOP_ILNKDMA, "IOP ILink DMA"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_MDEC_IN, "IOP DMAC MDEC IN"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_MDEC_OUT, "IOP DMAC MDEC OUT"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_SIF2, "IOP DMAC SIF2"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_CDVD, "IOP DMAC CDVD"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_SPU, "IOP DMAC SPU"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_PIO, "IOP DMAC PIO"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_GPU_OTC, "IOP DMAC GPU OTC"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_BE, "IOP DMAC BE"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_SPU2, "IOP DMAC SPU2"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_DEV9, "IOP DMAC DEV9"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_SIF0, "IOP DMAC SIF0"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_SIF1, "IOP DMAC SIF1"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_SIO2_IN, "IOP DMAC SIO2 IN"), + IOP_IRQ_TYPE(IRQ_IOP_DMAC_SIO2_OUT, "IOP DMAC SIO2 OUT"), + IOP_IRQ_TYPE(IRQ_IOP_SW1, "IOP SW1"), + IOP_IRQ_TYPE(IRQ_IOP_SW2, "IOP SW2"), +}; + +static int __init iop_irq_init(void) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(iop_irqs); i++) + irq_set_chip_and_handler(iop_irqs[i].irq, + &iop_irqs[i].irq_chip, handle_level_irq); + + return 0; +} +// FIXME: subsys_initcall(iop_irq_init); +module_init(iop_irq_init); + +MODULE_DESCRIPTION("PlayStation 2 input/output processor (IOP) IRQs"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:17:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125489 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0D71914DE for ; Sun, 1 Sep 2019 16:17:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CDCA520657 for ; Sun, 1 Sep 2019 16:17:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728677AbfIAQRz (ORCPT ); Sun, 1 Sep 2019 12:17:55 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:60206 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAQRz (ORCPT ); Sun, 1 Sep 2019 12:17:55 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id EA83A3FC34 for ; Sun, 1 Sep 2019 18:17:51 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QbEEVNTHL-ag for ; Sun, 1 Sep 2019 18:17:51 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 0D8B33F62D for ; Sun, 1 Sep 2019 18:17:50 +0200 (CEST) Date: Sun, 1 Sep 2019 18:17:50 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 076/120] MIPS: PS2: GS: Define privileged Graphics Synthesizer registers Message-ID: <51240db505d6c5acf84b80f044ce5393dfa907fd.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org All privileged GS registers are write-only except CSR (system status) and SIGLBLID (signal and label id)[1][2]. Reading write-only registers is emulated by shadow registers in memory. Reading unwritten registers is not permitted. Predicate functions indicate whether registers are readable. The following privileged registers are available: Register | Description ---------+--------------------------------------------------- PMODE | PCRTC mode setting SMODE1 | Mode setting related to video synchronisation SMODE2 | Mode setting related to video synchronisation SYNCH1 | Mode setting related to video synchronisation SYNCH2 | Mode setting related to video synchronisation SYNCHV | Mode setting related to video synchronisation SRFSH | DRAM refresh DISPFB1 | Setting for rectangular area read output circuit 1 DISPLAY1 | Setting for rectangular area read output circuit 1 DISPFB2 | Setting for rectangular area read output circuit 2 DISPLAY2 | Setting for rectangular area read output circuit 2 EXTBUF | Feedback write buffer setting EXTDATA | Feedback write setting EXTWRITE | Feedback write control BGCOLOR | Background colour setting CSR | System status IMR | Interrupt mask control BUSDIR | Host interface bus switching SIGLBLID | Signal and label identification value read ---------+--------------------------------------------------- References: [1] "EE User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 26. [2] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 142-157, 159. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs-registers.h | 548 ++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/gs-registers.h diff --git a/arch/mips/include/asm/mach-ps2/gs-registers.h b/arch/mips/include/asm/mach-ps2/gs-registers.h new file mode 100644 index 000000000000..ab59c751190f --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/gs-registers.h @@ -0,0 +1,548 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 privileged Graphics Synthesizer (GS) registers + * + * Copyright (C) 2019 Fredrik Noring + */ + +/** + * DOC: Privileged Graphics Synthesizer (GS) registers + * + * All privileged GS registers are write-only except CSR (system status) + * and SIGLBLID (signal and label id). Reading write-only registers is + * emulated by shadow registers in memory. Reading unwritten registers + * is not permitted. Predicate functions indicate whether registers are + * readable. + */ + +#ifndef __ASM_MACH_PS2_GS_REGISTERS_H +#define __ASM_MACH_PS2_GS_REGISTERS_H + +#include + +/* Privileged GS registers must be accessed using LD/SD instructions. */ + +#define GS_PMODE 0x12000000 /* (WO) PCRTC mode setting */ +#define GS_SMODE1 0x12000010 /* (WO) Sync */ +#define GS_SMODE2 0x12000020 /* (WO) Sync */ +#define GS_SRFSH 0x12000030 /* (WO) DRAM refresh */ +#define GS_SYNCH1 0x12000040 /* (WO) Sync */ +#define GS_SYNCH2 0x12000050 /* (WO) Sync */ +#define GS_SYNCV 0x12000060 /* (WO) Sync */ +#define GS_DISPFB1 0x12000070 /* (WO) Rectangle read output circuit 1 */ +#define GS_DISPLAY1 0x12000080 /* (WO) Rectangle read output circuit 1 */ +#define GS_DISPFB2 0x12000090 /* (WO) Rectangle read output circuit 2 */ +#define GS_DISPLAY2 0x120000a0 /* (WO) Rectangle read output circuit 2 */ +#define GS_EXTBUF 0x120000b0 /* (WO) Feedback write buffer */ +#define GS_EXTDATA 0x120000c0 /* (WO) Feedback write setting */ +#define GS_EXTWRITE 0x120000d0 /* (WO) Feedback write function control */ +#define GS_BGCOLOR 0x120000e0 /* (WO) Background color setting */ +#define GS_CSR 0x12001000 /* (RW) System status */ +#define GS_IMR 0x12001010 /* (WO) Interrupt mask control */ +#define GS_BUSDIR 0x12001040 /* (WO) Host interface bus switching */ +#define GS_SIGLBLID 0x12001080 /* (RW) Signal and label id */ + +/** + * enum gs_pmode_mmod - &gs_pmode.mmod alpha blending value + * @gs_mmod_circuit1: FIXME + * @gs_mmod_alp: FIXME + */ +enum gs_pmode_mmod { + gs_mmod_circuit1, + gs_mmod_alp +}; + +/** + * enum gs_pmode_amod - &gs_pmode.amod OUT1 alpha output + * @gs_amod_circuit1: FIXME + * @gs_amod_circuit2: FIXME + */ +enum gs_pmode_amod { + gs_amod_circuit1, + gs_amod_circuit2 +}; + +/** + * enum gs_pmode_slbg - &gs_pmode.slbg alpha blending method + * @gs_slbg_circuit2: FIXME + * @gs_slbg_bgcolor: FIXME + */ +enum gs_pmode_slbg { + gs_slbg_circuit2, + gs_slbg_bgcolor +}; + +/** + * struct gs_pmode - PMODE privileged Graphics Synthesizer register + * @en1: enable read circuit 1 + * @en2: enable read circuit 2 + * @crtmd: CRT output switching (always 001) + * @mmod: alpha blending value + * @amod: OUT1 alpha output + * @slbg: alpha blending method + * @alp: fixed alpha (0xff = 1.0) + * @zero: must be zero + */ +struct gs_pmode { + u64 en1 : 1; + u64 en2 : 1; + u64 crtmd : 3; + u64 mmod : 1; + u64 amod : 1; + u64 slbg : 1; + u64 alp : 8; + u64 zero : 1; + u64 : 47; +}; + +/** + * enum gs_smode1_cmod - &gs_smode1.cmod value + * @gs_cmod_vesa: VESA + * @gs_cmod_ntsc: NTSC broadcast + * @gs_cmod_pal: PAL broadcast + */ +enum gs_smode1_cmod { + gs_cmod_vesa, + /* Reserved */ + gs_cmod_ntsc = 2, + gs_cmod_pal +}; + +/** + * enum gs_smode1_gcont - &gs_smode1.gcont value + * @gs_gcont_rgbyc: Output RGBYc + * @gs_gcont_ycrcb: Output YCrCb + */ +enum gs_smode1_gcont { + gs_gcont_rgbyc, + gs_gcont_ycrcb +}; + +/** + * struct gs_smode1 - SMODE1 privileged Graphics Synthesizer register + * @rc: PLL reference divider + * @lc: PLL loop divider + * @t1248: PLL output divider + * @slck: FIXME + * @cmod: @enum gs_smode1_cmod display mode (PAL, NTSC or VESA) + * @ex: FIXME + * @prst: PLL reset + * @sint: PLL (phase-locked loop) + * @xpck: FIXME + * @pck2: FIXME + * @spml: FIXME + * @gcont: @enum gs_smode1_gcont select RGBYC or YCrCb + * @phs: HSync output + * @pvs: VSync output + * @pehs: FIXME + * @pevs: FIXME + * @clksel: FIXME + * @nvck: FIXME + * @slck2: FIXME + * @vcksel: FIXME + * @vhp: FIXME + * + * The video clock VCK = (13500000 * @lc) / ((@t1248 + 1) * @spml * @rc). + */ +struct gs_smode1 { + u64 rc : 3; + u64 lc : 7; + u64 t1248 : 2; + u64 slck : 1; + u64 cmod : 2; + u64 ex : 1; + u64 prst : 1; + u64 sint : 1; + u64 xpck : 1; + u64 pck2 : 2; + u64 spml : 4; + u64 gcont : 1; + u64 phs : 1; + u64 pvs : 1; + u64 pehs : 1; + u64 pevs : 1; + u64 clksel : 2; + u64 nvck : 1; + u64 slck2 : 1; + u64 vcksel : 2; + u64 vhp : 1; + u64 : 27; +}; + +/** + * enum gs_smode2_intm - &gs_smode2.intm interlace mode + * @gs_intm_progressive: progressive (noninterlace) mode + * @gs_intm_interlace: interlace mode + */ +enum gs_smode2_intm { + gs_intm_progressive, + gs_intm_interlace +}; + +/** + * enum gs_smode2_ffmd - &gs_smode2.ffmd FIELD or FRAME mode + * @gs_ffmd_field: + * @gs_ffmd_frame: + * + * In FIELD mode every other line is read: 0, 2, 4, ... / 1, 3, 5, ... + * + * In FRAME mode every line is read: 1, 2, 3, 4, 5, ... + */ +enum gs_smode2_ffmd { + gs_ffmd_field, + gs_ffmd_frame +}; + +/** + * enum gs_smode2_dpms - &gs_smode2.dpms VESA display power management + * signaling (DPMS) levels + * @gs_dpms_on: in use + * @gs_dpms_standby: blanked, low power + * @gs_dpms_suspend: blanked, lower power + * @gs_dpms_off: shut off, awaiting activity + */ +enum gs_smode2_dpms { + gs_dpms_on, + gs_dpms_standby, + gs_dpms_suspend, + gs_dpms_off +}; + +/** + * struct gs_smode2 - SMODE2 privileged Graphics Synthesizer register + * @intm: &enum gs_smode2_intm progressive or interlace mode + * @ffmd: &enum gs_smode2_ffmd FIELD or FRAME mode + * @dpms: &enum gs_smode2_dpms VESA display power management signaling (DPMS) + * level + */ +struct gs_smode2 { + u64 intm : 1; + u64 ffmd : 1; + u64 dpms : 2; + u64 : 60; +}; + +/** + * struct gs_srfsh - DRAM refresh privileged Graphics Synthesizer register + * @rfsh: FIXME + */ +struct gs_srfsh { + u64 rfsh : 4; /* FIXME: Number of bits? */ + u64 : 60; +}; + +/** + * struct gs_synch1 - SYNCH1 privileged Graphics Synthesizer register + * @hfp: horizontal front porch + * @hbp: horizontal back porch + * @hseq: FIXME + * @hsvs: FIXME + * @hs: FIXME + */ +struct gs_synch1 { + u64 hfp : 11; + u64 hbp : 11; + u64 hseq : 10; + u64 hsvs : 11; + u64 hs : 21; /* FIXME: Number of bits? */ +}; + +/** + * struct gs_synch2 - SYNCH2 privileged Graphics Synthesizer register + * @hf: FIXME + * @hb: FIXME + */ +struct gs_synch2 { + u64 hf : 11; + u64 hb : 11; + u64 : 42; +}; + +/** + * struct gs_syncv - SYNCHV privileged Graphics Synthesizer register + * @vfp: vertical front porch, halflines with color burst after video data + * @vfpe: halflines without color burst after @vfp + * @vbp: vertical back porch, halflines with color burst after @vbpe + * @vbpe: halflines without color burst after @vbp + * @vdp: halflines with with video data + * @vs: halflines with VSYNC + */ +struct gs_syncv { + u64 vfp : 10; + u64 vfpe : 10; + u64 vbp : 12; + u64 vbpe : 10; + u64 vdp : 11; + u64 vs : 11; +}; + +/** + * struct gs_dispfb - DISPFB privileged Graphics Synthesizer register + * @fbp: base pointer address/2048 + * @fbw: buffer width/64 + * @psm: pixel storage format FIXME + * @dbx: upper left x position + * @dby: upper left y position + */ +struct gs_dispfb { + u64 fbp : 9; + u64 fbw : 6; + u64 psm : 5; + u64 : 12; + u64 dbx : 11; + u64 dby : 11; + u64 : 10; +}; + +/** + * struct gs_display - DISPLAY privileged Graphics Synthesizer register + * @dx: display x position (VCK) + * @dy: display y position (px) + * @magh: horizontal magnification + * @magv: vertical magnification + * @dw: display area width-1 (VCK) + * @dh: display area height-1 (px) + * + * @magh and @magv are factor-1, so 0 is 1x, 1 is 2x, 2 is 3x, etc. + */ +struct gs_display { + u64 dx : 12; + u64 dy : 11; + u64 magh : 4; + u64 magv : 5; + u64 dw : 12; + u64 dh : 11; + u64 : 9; +}; + +/** + * enum gs_extbuf_fbin - &&gs_extbuf.fbin selection of input source + * @gs_fbin_out1: FIXME + * @gs_fbin_out2: FIXME + */ +enum gs_extbuf_fbin { + gs_fbin_out1, + gs_fbin_out2 +}; + +/* + * enum gs_extbuf_wffmd - &gs_extbuf.wffmd interlace mode + * @gs_wffmd_field: write to every other raster + * @gs_wffmd_frame: write to every raster + */ +enum gs_extbuf_wffmd { + gs_wffmd_field, + gs_wffmd_frame +}; + +/** + * enum gs_extbuf_emoda - &gs_extbuf.emoda processing of input alpha + * @gs_emoda_alpha: input alpha is written as it is + * @gs_emoda_y: FIXME + * @gs_emoda_yhalf: FIXME + * @gs_emoda_zero: FIXME + */ +enum gs_extbuf_emoda { + gs_emoda_alpha, + gs_emoda_y, + gs_emoda_yhalf, + gs_emoda_zero +}; + +/** + * enum gs_extbuf_emodc - &gs_extbuf.emodc processing of input color + * @gs_emodc_rgb: FIXME + * @gs_emodc_y: FIXME + * @gs_emodc_ycbcr: FIXME + * @gs_emodc_alpha: FIXME + */ +enum gs_extbuf_emodc { + gs_emodc_rgb, + gs_emodc_y, + gs_emodc_ycbcr, + gs_emodc_alpha +}; + +/** + * struct gs_extbuf - EXTBUF privileged Graphics Synthesizer register + * @exbp: buffer base pointer/64 + * @exbw: width of buffer/64 + * @fbin: @enum gs_extbuf_fbin selection of input source + * @wffmd: @enum gs_extbuf_wffmd interlace mode + * @emoda: @enum gs_extbuf_emoda processing of input alpha + * @emodc: @enum gs_extbuf_emodc processing of input color + * @wdx: upper left x position + * @wdy: upper left y position + */ +struct gs_extbuf { + u64 exbp : 14; + u64 exbw : 6; + u64 fbin : 2; + u64 wffmd : 1; + u64 emoda : 2; + u64 emodc : 2; + u64 : 5; + u64 wdx : 11; + u64 wdy : 11; + u64 : 10; +}; + +/** + * struct gs_extdata - EXTDATA privileged Graphics Synthesizer register + * @sx: upper left x position (VCK) + * @sy: upper left y position (VCK) + * @smph: horizontal sampling rate interval (VCK) + * @smpv: vertical sampling rate interval (VCK) + * @ww: rectangular area width-1 + * @wh: rectangular area height-1 + */ +struct gs_extdata { + u64 sx : 12; + u64 sy : 11; + u64 smph : 4; + u64 smpv : 2; + u64 : 3; + u64 ww : 12; + u64 wh : 11; + u64 : 9; +}; + +/** + * enum gs_extwrite_write - &gs_extwrite.write enable feedback write + * @gs_write_complete_current: FIXME + * @gs_write_start_next: FIXME + */ +enum gs_extwrite_write { + gs_write_complete_current, + gs_write_start_next +}; + +/** + * struct gs_extwrite - EXTWRITE privileged Graphics Synthesizer register + * @write: &enum gs_extwrite_write enable feedback write + */ +struct gs_extwrite { + u64 write : 1; + u64 : 63; +}; + +/** + * struct gs_bgcolor - BGCOLOR privileged Graphics Synthesizer register + * @r: red background color + * @g: green background color + * @b: blue background color + */ +struct gs_bgcolor { + u64 r : 8; + u64 g : 8; + u64 b : 8; + u64 : 40; +}; + +/** + * enum gs_csr_fifo - &gs_csr.fifo host interface FIFO status + * @gs_fifo_neither: neither empty nor almost full + * @gs_fifo_empty: FIXME + * @gs_fifo_almost_full: FIXME + */ +enum gs_csr_fifo { + gs_fifo_neither, + gs_fifo_empty, + gs_fifo_almost_full +}; + +/** + * enum gs_csr_field - &gs_csr.field field display currently FIXME + * @gs_field_even: FIXME + * @gs_field_odd: FIXME + */ +enum gs_csr_field { + gs_field_even, + gs_field_odd +}; + +/** + * struct gs_csr - CSR privileged Graphics Synthesizer register FIXME + * @signal: SIGNAL event control + * @finish: FINISH event control + * @hsint: HSync interrupt control + * @vsint: VSync interrupt control + * @edwint: rectangular area write termination interrupt control + * @zero: must be zero + * @flush: drawing suspend and FIFO clear (enabled during data write) + * @reset: Graphics Synthesizer reset (enabled during data write) + * @nfield: VSync sampled FIELD + * @field: &enum gs_csr_field field display currently + * @fifo: &enum gs_csr_fifo host interface FIFO status + * @rev: Graphics Synthesizer revision (hex) + * @id: Graphics Synthesizer id (hex) + */ +struct gs_csr { + u64 signal : 1; + u64 finish : 1; + u64 hsint : 1; + u64 vsint : 1; + u64 edwint : 1; + u64 zero : 2; + u64 : 1; + u64 flush : 1; + u64 reset : 1; + u64 : 2; + u64 nfield : 1; + u64 field : 1; + u64 fifo : 2; + u64 rev : 8; + u64 id : 8; + u64 : 32; +}; + +/** + * struct gs_imr - IMR privileged Graphics Synthesizer register FIXME + * @sigmsk: SIGNAL event interrupt mask + * @finishmsk: FINISH event interrupt mask + * @hsmsk: HSync interrupt mask + * @vsmsk: VSync interrupt mask + * @edwmsk: rectangular area write termination interrupt mask + * @ones: should be set to all ones (= 3) + */ +struct gs_imr { + u64 : 8; + u64 sigmsk : 1; + u64 finishmsk : 1; + u64 hsmsk : 1; + u64 vsmsk : 1; + u64 edwmsk : 1; + u64 ones : 2; + u64 : 49; +}; + +/** + * enum gs_busdir_dir - &gs_busdir.dir host to local direction, or vice versa + * @gs_dir_host_to_local: host to local bus transfer direction + * @gs_dir_local_to_host: local to host bus transfer direction + */ +enum gs_busdir_dir { + gs_dir_host_to_local, + gs_dir_local_to_host +}; + +/** + * struct gs_busdir - BUSDIR privileged Graphics Synthesizer register FIXME + * @dir: &enum gs_busdir_dir host to local direction, or vice versa + */ +struct gs_busdir { + u64 dir : 1; + u64 : 63; +}; + +/** + * struct gs_siglblid - SIGLBLID privileged Graphics Synthesizer register FIXME + * @sigid: id value set by SIGNAL register + * @lblid: id value set by LABEL register + */ +struct gs_siglblid { + u64 sigid : 32; + u64 lblid : 32; +}; + +#endif /* __ASM_MACH_PS2_GS_REGISTERS_H */ From patchwork Sun Sep 1 16:18:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125491 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9647113B1 for ; Sun, 1 Sep 2019 16:18:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 73A5B21872 for ; Sun, 1 Sep 2019 16:18:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728570AbfIAQSU (ORCPT ); Sun, 1 Sep 2019 12:18:20 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44238 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAQSU (ORCPT ); Sun, 1 Sep 2019 12:18:20 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id B6F443F65F for ; Sun, 1 Sep 2019 18:18:17 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fHsoRL-32Jy5 for ; Sun, 1 Sep 2019 18:18:17 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id EE5183F58C for ; Sun, 1 Sep 2019 18:18:16 +0200 (CEST) Date: Sun, 1 Sep 2019 18:18:16 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 077/120] MIPS: PS2: GS: Write privileged registers Message-ID: <758ac4deba96217ee4ec40dc06429951e4d4495c.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org All privileged Graphics Synthesizer register functions follow the same pattern. For example, the CSR register has the following functions: bool gs_valid_csr(void); void gs_writeq_csr(u64 value); gs_valid_csr() indicates whether CSR is readable, which is always true, since CSR is read-write in hardware. The IMR register however is write- only in hardware, so its shadow register is only valid and readable once it is written at least once. Reading nonvalid registers is not permitted. The following registers have functions: PMODE, SMODE1, SMODE2, SYNCH1, SYNCH2, SYNCV, SRFSH, DISPFB1, DISPLAY1, DISPFB2, DISPLAY2, EXTBUF, EXTDATA, EXTWRITE, BGCOLOR, CSR, IMR, BUSDIR and SIGLBLID. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs-registers.h | 48 +++++++ drivers/ps2/Makefile | 2 + drivers/ps2/gs-registers.c | 121 ++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 drivers/ps2/gs-registers.c diff --git a/arch/mips/include/asm/mach-ps2/gs-registers.h b/arch/mips/include/asm/mach-ps2/gs-registers.h index ab59c751190f..291b503447e4 100644 --- a/arch/mips/include/asm/mach-ps2/gs-registers.h +++ b/arch/mips/include/asm/mach-ps2/gs-registers.h @@ -545,4 +545,52 @@ struct gs_siglblid { u64 lblid : 32; }; +#define GS_DECLARE_VALID_REG(reg) \ + bool gs_valid_##reg(void) + +#define GS_DECLARE_WQ_REG(reg) \ + void gs_writeq_##reg(u64 value) + +#define GS_DECLARE_RW_REG(reg) \ + GS_DECLARE_VALID_REG(reg); \ + GS_DECLARE_WQ_REG(reg) + +/** + * DOC: + * + * All privileged Graphics Synthesizer register functions follow the same + * pattern. For example, the CSR register has the following functions:: + * + * bool gs_valid_csr(void); + * void gs_writeq_csr(u64 value); + * + * gs_valid_csr() indicates whether CSR is readable, which is always true, + * since CSR is read-write in hardware. The IMR register however is write- + * only in hardware, so its shadow register is only valid and readable once + * it is written at least once. Reading nonvalid registers is not permitted. + * + * The following registers have functions: PMODE, SMODE1, SMODE2, SRFSH, + * SYNCH1, SYNCH2, SYNCV, DISPFB1 , DISPLAY1, DISPFB2, DISPLAY2, EXTBUF, + * EXTDATA, EXTWRITE, BGCOLOR, CSR, IMR, BUSDIR and SIGLBLID. + */ +GS_DECLARE_RW_REG(pmode); +GS_DECLARE_RW_REG(smode1); +GS_DECLARE_RW_REG(smode2); +GS_DECLARE_RW_REG(srfsh); +GS_DECLARE_RW_REG(synch1); +GS_DECLARE_RW_REG(synch2); +GS_DECLARE_RW_REG(syncv); +GS_DECLARE_RW_REG(dispfb1 ); +GS_DECLARE_RW_REG(display1); +GS_DECLARE_RW_REG(dispfb2); +GS_DECLARE_RW_REG(display2); +GS_DECLARE_RW_REG(extbuf); +GS_DECLARE_RW_REG(extdata); +GS_DECLARE_RW_REG(extwrite); +GS_DECLARE_RW_REG(bgcolor); +GS_DECLARE_RW_REG(csr); +GS_DECLARE_RW_REG(imr); +GS_DECLARE_RW_REG(busdir); +GS_DECLARE_RW_REG(siglblid); + #endif /* __ASM_MACH_PS2_GS_REGISTERS_H */ diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index dd00eff52ef3..533ab86d6a58 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,3 +1,5 @@ +obj-$(CONFIG_PS2_GS) += gs-registers.o + obj-m += iop-heap.o obj-m += iop-irq.o obj-m += iop-memory.o diff --git a/drivers/ps2/gs-registers.c b/drivers/ps2/gs-registers.c new file mode 100644 index 000000000000..781604b874b5 --- /dev/null +++ b/drivers/ps2/gs-registers.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 privileged Graphics Synthesizer (GS) registers + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +/* Shadow write-only privileged Graphics Synthesizer registers. */ +static struct { + spinlock_t lock; /* Must be taken to access shadow registers. */ + + struct { + u64 value; + bool valid; /* True if value is written at least once. */ + } pmode, + smode1, + smode2, + srfsh, + synch1, + synch2, + syncv, + dispfb1, + display1, + dispfb2, + display2, + extbuf, + extdata, + extwrite, + bgcolor, + imr, + busdir; +} gs_registers = { + .lock = __SPIN_LOCK_UNLOCKED(gs_registers.lock), +}; + +/* Read-write registers are not shadowed and are always valid. */ +#define GS_DEFINE_VALID_RW_REG(reg, addr) \ + bool gs_valid_##reg(void) \ + { \ + return true; \ + } \ + EXPORT_SYMBOL_GPL(gs_valid_##reg) + +/* Read-write registers are not shadowed and trivially write. */ +#define GS_DEFINE_WQ_RW_REG(reg, addr) \ + void gs_writeq_##reg(u64 value) \ + { \ + outq(value, addr); \ + } \ + EXPORT_SYMBOL_GPL(gs_writeq_##reg) + +/* Write-only registers are shadowed and valid only if previously written. */ +#define GS_DEFINE_VALID_WO_REG(reg, addr) \ + bool gs_valid_##reg(void) \ + { \ + unsigned long flags; \ + bool valid; \ + spin_lock_irqsave(&gs_registers.lock, flags); \ + valid = gs_registers.reg.valid; \ + spin_unlock_irqrestore(&gs_registers.lock, flags); \ + return valid; \ + } \ + EXPORT_SYMBOL_GPL(gs_valid_##reg) + +/* Write-only registers are shadowed and reading requires a previous write. */ +#define GS_DEFINE_WQ_WO_REG(reg, addr) \ + void gs_writeq_##reg(u64 value) \ + { \ + unsigned long flags; \ + spin_lock_irqsave(&gs_registers.lock, flags); \ + gs_registers.reg.value = value; \ + gs_registers.reg.valid = true; \ + outq(value, addr); \ + spin_unlock_irqrestore(&gs_registers.lock, flags); \ + } \ + EXPORT_SYMBOL_GPL(gs_writeq_##reg) + +/* Only CSR and SIGLBLID are read-write (RW) with hardware. */ +#define GS_DEFINE_RW_REG(reg, addr) \ + GS_DEFINE_VALID_RW_REG(reg, addr); \ + GS_DEFINE_WQ_RW_REG(reg, addr) + +/* The rest are write-only (WO) with reading emulated by shadow registers. */ +#define GS_DEFINE_WO_REG(reg, addr) \ + GS_DEFINE_VALID_WO_REG(reg, addr); \ + GS_DEFINE_WQ_WO_REG(reg, addr) + +GS_DEFINE_WO_REG(pmode, GS_PMODE); +GS_DEFINE_WO_REG(smode1, GS_SMODE1); +GS_DEFINE_WO_REG(smode2, GS_SMODE2); +GS_DEFINE_WO_REG(srfsh, GS_SRFSH); +GS_DEFINE_WO_REG(synch1, GS_SYNCH1); +GS_DEFINE_WO_REG(synch2, GS_SYNCH2); +GS_DEFINE_WO_REG(syncv, GS_SYNCV); +GS_DEFINE_WO_REG(dispfb1, GS_DISPFB1); +GS_DEFINE_WO_REG(display1, GS_DISPLAY1); +GS_DEFINE_WO_REG(dispfb2, GS_DISPFB2); +GS_DEFINE_WO_REG(display2, GS_DISPLAY2); +GS_DEFINE_WO_REG(extbuf, GS_EXTBUF); +GS_DEFINE_WO_REG(extdata, GS_EXTDATA); +GS_DEFINE_WO_REG(extwrite, GS_EXTWRITE); +GS_DEFINE_WO_REG(bgcolor, GS_BGCOLOR); +GS_DEFINE_RW_REG(csr, GS_CSR); /* Read-write */ +GS_DEFINE_WO_REG(imr, GS_IMR); +GS_DEFINE_WO_REG(busdir, GS_BUSDIR); +GS_DEFINE_RW_REG(siglblid, GS_SIGLBLID); /* Read-write */ + +MODULE_DESCRIPTION("PlayStation 2 privileged Graphics Synthesizer registers"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:18:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125493 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D422513B1 for ; Sun, 1 Sep 2019 16:18:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BB67322CE9 for ; Sun, 1 Sep 2019 16:18:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728496AbfIAQSf (ORCPT ); Sun, 1 Sep 2019 12:18:35 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44300 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQSf (ORCPT ); Sun, 1 Sep 2019 12:18:35 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 505173F63C for ; Sun, 1 Sep 2019 18:18:33 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UBJatOIyCwLM for ; Sun, 1 Sep 2019 18:18:32 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 9AB143F58C for ; Sun, 1 Sep 2019 18:18:32 +0200 (CEST) Date: Sun, 1 Sep 2019 18:18:32 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 078/120] MIPS: PS2: GS: Read privileged registers Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org All privileged Graphics Synthesizer register functions follow the same pattern. For example, the reading the CSR register: u64 gs_readq_csr(void); Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs-registers.h | 5 ++++ drivers/ps2/gs-registers.c | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/gs-registers.h b/arch/mips/include/asm/mach-ps2/gs-registers.h index 291b503447e4..315a25c102c9 100644 --- a/arch/mips/include/asm/mach-ps2/gs-registers.h +++ b/arch/mips/include/asm/mach-ps2/gs-registers.h @@ -548,11 +548,15 @@ struct gs_siglblid { #define GS_DECLARE_VALID_REG(reg) \ bool gs_valid_##reg(void) +#define GS_DECLARE_RQ_REG(reg) \ + u64 gs_readq_##reg(void) + #define GS_DECLARE_WQ_REG(reg) \ void gs_writeq_##reg(u64 value) #define GS_DECLARE_RW_REG(reg) \ GS_DECLARE_VALID_REG(reg); \ + GS_DECLARE_RQ_REG(reg); \ GS_DECLARE_WQ_REG(reg) /** @@ -562,6 +566,7 @@ struct gs_siglblid { * pattern. For example, the CSR register has the following functions:: * * bool gs_valid_csr(void); + * u64 gs_readq_csr(void); * void gs_writeq_csr(u64 value); * * gs_valid_csr() indicates whether CSR is readable, which is always true, diff --git a/drivers/ps2/gs-registers.c b/drivers/ps2/gs-registers.c index 781604b874b5..debaf0153fbe 100644 --- a/drivers/ps2/gs-registers.c +++ b/drivers/ps2/gs-registers.c @@ -52,6 +52,14 @@ static struct { } \ EXPORT_SYMBOL_GPL(gs_valid_##reg) +/* Read-write registers are not shadowed and trivially read. */ +#define GS_DEFINE_RQ_RW_REG(reg, addr) \ + u64 gs_readq_##reg(void) \ + { \ + return inq(addr); \ + } \ + EXPORT_SYMBOL_GPL(gs_readq_##reg) + /* Read-write registers are not shadowed and trivially write. */ #define GS_DEFINE_WQ_RW_REG(reg, addr) \ void gs_writeq_##reg(u64 value) \ @@ -73,6 +81,20 @@ static struct { } \ EXPORT_SYMBOL_GPL(gs_valid_##reg) +/* Write-only registers are shadowed and reading requires a previous write. */ +#define GS_DEFINE_RQ_WO_REG(reg, addr) \ + u64 gs_readq_##reg(void) \ + { \ + unsigned long flags; \ + u64 value; \ + spin_lock_irqsave(&gs_registers.lock, flags); \ + WARN_ON_ONCE(!gs_registers.reg.valid); \ + value = gs_registers.reg.value; \ + spin_unlock_irqrestore(&gs_registers.lock, flags); \ + return value; \ + } \ + EXPORT_SYMBOL_GPL(gs_readq_##reg) + /* Write-only registers are shadowed and reading requires a previous write. */ #define GS_DEFINE_WQ_WO_REG(reg, addr) \ void gs_writeq_##reg(u64 value) \ @@ -89,11 +111,13 @@ static struct { /* Only CSR and SIGLBLID are read-write (RW) with hardware. */ #define GS_DEFINE_RW_REG(reg, addr) \ GS_DEFINE_VALID_RW_REG(reg, addr); \ + GS_DEFINE_RQ_RW_REG(reg, addr); \ GS_DEFINE_WQ_RW_REG(reg, addr) /* The rest are write-only (WO) with reading emulated by shadow registers. */ #define GS_DEFINE_WO_REG(reg, addr) \ GS_DEFINE_VALID_WO_REG(reg, addr); \ + GS_DEFINE_RQ_WO_REG(reg, addr); \ GS_DEFINE_WQ_WO_REG(reg, addr) GS_DEFINE_WO_REG(pmode, GS_PMODE); From patchwork Sun Sep 1 16:18:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125495 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0B76813B1 for ; Sun, 1 Sep 2019 16:19:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DD2F8233A2 for ; Sun, 1 Sep 2019 16:18:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728570AbfIAQS7 (ORCPT ); Sun, 1 Sep 2019 12:18:59 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44324 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQS7 (ORCPT ); Sun, 1 Sep 2019 12:18:59 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 02CBB3F63C for ; Sun, 1 Sep 2019 18:18:57 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7HR1CRSFTY7T for ; Sun, 1 Sep 2019 18:18:56 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 44EEA3F58C for ; Sun, 1 Sep 2019 18:18:56 +0200 (CEST) Date: Sun, 1 Sep 2019 18:18:56 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 079/120] MIPS: PS2: GS: Define privileged register structures Message-ID: <72856c09f705f922d240a38ff0532ed607e9cb42.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Read and write registers as structures, which simplifies notation. For example, the CSR register can be read and written with struct gs_csr: struct gs_csr gs_read_csr(void); void gs_write_csr(struct gs_csr value); Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs-registers.h | 53 +++++++------ drivers/ps2/gs-registers.c | 75 +++++++++++++------ 2 files changed, 83 insertions(+), 45 deletions(-) diff --git a/arch/mips/include/asm/mach-ps2/gs-registers.h b/arch/mips/include/asm/mach-ps2/gs-registers.h index 315a25c102c9..596e277a6940 100644 --- a/arch/mips/include/asm/mach-ps2/gs-registers.h +++ b/arch/mips/include/asm/mach-ps2/gs-registers.h @@ -554,10 +554,18 @@ struct gs_siglblid { #define GS_DECLARE_WQ_REG(reg) \ void gs_writeq_##reg(u64 value) -#define GS_DECLARE_RW_REG(reg) \ +#define GS_DECLARE_RS_REG(reg, str) \ + struct gs_##str gs_read_##reg(void) + +#define GS_DECLARE_WS_REG(reg, str) \ + void gs_write_##reg(struct gs_##str value) + +#define GS_DECLARE_RW_REG(reg, str) \ GS_DECLARE_VALID_REG(reg); \ GS_DECLARE_RQ_REG(reg); \ - GS_DECLARE_WQ_REG(reg) + GS_DECLARE_WQ_REG(reg); \ + GS_DECLARE_RS_REG(reg, str); \ + GS_DECLARE_WS_REG(reg, str) /** * DOC: @@ -569,6 +577,9 @@ struct gs_siglblid { * u64 gs_readq_csr(void); * void gs_writeq_csr(u64 value); * + * struct gs_csr gs_read_csr(void); + * void gs_write_csr(struct gs_csr value); + * * gs_valid_csr() indicates whether CSR is readable, which is always true, * since CSR is read-write in hardware. The IMR register however is write- * only in hardware, so its shadow register is only valid and readable once @@ -578,24 +589,24 @@ struct gs_siglblid { * SYNCH1, SYNCH2, SYNCV, DISPFB1 , DISPLAY1, DISPFB2, DISPLAY2, EXTBUF, * EXTDATA, EXTWRITE, BGCOLOR, CSR, IMR, BUSDIR and SIGLBLID. */ -GS_DECLARE_RW_REG(pmode); -GS_DECLARE_RW_REG(smode1); -GS_DECLARE_RW_REG(smode2); -GS_DECLARE_RW_REG(srfsh); -GS_DECLARE_RW_REG(synch1); -GS_DECLARE_RW_REG(synch2); -GS_DECLARE_RW_REG(syncv); -GS_DECLARE_RW_REG(dispfb1 ); -GS_DECLARE_RW_REG(display1); -GS_DECLARE_RW_REG(dispfb2); -GS_DECLARE_RW_REG(display2); -GS_DECLARE_RW_REG(extbuf); -GS_DECLARE_RW_REG(extdata); -GS_DECLARE_RW_REG(extwrite); -GS_DECLARE_RW_REG(bgcolor); -GS_DECLARE_RW_REG(csr); -GS_DECLARE_RW_REG(imr); -GS_DECLARE_RW_REG(busdir); -GS_DECLARE_RW_REG(siglblid); +GS_DECLARE_RW_REG(pmode, pmode); +GS_DECLARE_RW_REG(smode1, smode1); +GS_DECLARE_RW_REG(smode2, smode2); +GS_DECLARE_RW_REG(srfsh, srfsh); +GS_DECLARE_RW_REG(synch1, synch1); +GS_DECLARE_RW_REG(synch2, synch2); +GS_DECLARE_RW_REG(syncv, syncv); +GS_DECLARE_RW_REG(dispfb1 , dispfb); +GS_DECLARE_RW_REG(display1, display); +GS_DECLARE_RW_REG(dispfb2, dispfb); +GS_DECLARE_RW_REG(display2, display); +GS_DECLARE_RW_REG(extbuf, extbuf); +GS_DECLARE_RW_REG(extdata, extdata); +GS_DECLARE_RW_REG(extwrite, extwrite); +GS_DECLARE_RW_REG(bgcolor, bgcolor); +GS_DECLARE_RW_REG(csr, csr); +GS_DECLARE_RW_REG(imr, imr); +GS_DECLARE_RW_REG(busdir, busdir); +GS_DECLARE_RW_REG(siglblid, siglblid); #endif /* __ASM_MACH_PS2_GS_REGISTERS_H */ diff --git a/drivers/ps2/gs-registers.c b/drivers/ps2/gs-registers.c index debaf0153fbe..1bd1d072f4cf 100644 --- a/drivers/ps2/gs-registers.c +++ b/drivers/ps2/gs-registers.c @@ -108,37 +108,64 @@ static struct { } \ EXPORT_SYMBOL_GPL(gs_writeq_##reg) +/* Read registers as structures, which simplifies notation. */ +#define GS_DEFINE_RS_REG(reg, str) \ + struct gs_##str gs_read_##reg(void) \ + { \ + const u64 v = gs_readq_##reg(); \ + struct gs_##str value; \ + BUILD_BUG_ON(sizeof(v) != sizeof(value)); \ + memcpy(&value, &v, sizeof(v)); \ + return value; \ + } \ + EXPORT_SYMBOL_GPL(gs_read_##reg) + +/* Write registers as structures, which simplifies notation. */ +#define GS_DEFINE_WS_REG(reg, str) \ + void gs_write_##reg(struct gs_##str value) \ + { \ + u64 v; \ + BUILD_BUG_ON(sizeof(v) != sizeof(value)); \ + memcpy(&v, &value, sizeof(v)); \ + gs_writeq_##reg(v); \ + } \ + EXPORT_SYMBOL_GPL(gs_write_##reg) + /* Only CSR and SIGLBLID are read-write (RW) with hardware. */ -#define GS_DEFINE_RW_REG(reg, addr) \ +#define GS_DEFINE_RW_REG(reg, str, addr) \ GS_DEFINE_VALID_RW_REG(reg, addr); \ GS_DEFINE_RQ_RW_REG(reg, addr); \ - GS_DEFINE_WQ_RW_REG(reg, addr) + GS_DEFINE_WQ_RW_REG(reg, addr); \ + GS_DEFINE_RS_REG(reg, str); \ + GS_DEFINE_WS_REG(reg, str) /* The rest are write-only (WO) with reading emulated by shadow registers. */ -#define GS_DEFINE_WO_REG(reg, addr) \ +#define GS_DEFINE_WO_REG(reg, str, addr) \ GS_DEFINE_VALID_WO_REG(reg, addr); \ GS_DEFINE_RQ_WO_REG(reg, addr); \ - GS_DEFINE_WQ_WO_REG(reg, addr) - -GS_DEFINE_WO_REG(pmode, GS_PMODE); -GS_DEFINE_WO_REG(smode1, GS_SMODE1); -GS_DEFINE_WO_REG(smode2, GS_SMODE2); -GS_DEFINE_WO_REG(srfsh, GS_SRFSH); -GS_DEFINE_WO_REG(synch1, GS_SYNCH1); -GS_DEFINE_WO_REG(synch2, GS_SYNCH2); -GS_DEFINE_WO_REG(syncv, GS_SYNCV); -GS_DEFINE_WO_REG(dispfb1, GS_DISPFB1); -GS_DEFINE_WO_REG(display1, GS_DISPLAY1); -GS_DEFINE_WO_REG(dispfb2, GS_DISPFB2); -GS_DEFINE_WO_REG(display2, GS_DISPLAY2); -GS_DEFINE_WO_REG(extbuf, GS_EXTBUF); -GS_DEFINE_WO_REG(extdata, GS_EXTDATA); -GS_DEFINE_WO_REG(extwrite, GS_EXTWRITE); -GS_DEFINE_WO_REG(bgcolor, GS_BGCOLOR); -GS_DEFINE_RW_REG(csr, GS_CSR); /* Read-write */ -GS_DEFINE_WO_REG(imr, GS_IMR); -GS_DEFINE_WO_REG(busdir, GS_BUSDIR); -GS_DEFINE_RW_REG(siglblid, GS_SIGLBLID); /* Read-write */ + GS_DEFINE_WQ_WO_REG(reg, addr); \ + GS_DEFINE_RS_REG(reg, str); \ + GS_DEFINE_WS_REG(reg, str) + +GS_DEFINE_WO_REG(pmode, pmode, GS_PMODE); +GS_DEFINE_WO_REG(smode1, smode1, GS_SMODE1); +GS_DEFINE_WO_REG(smode2, smode2, GS_SMODE2); +GS_DEFINE_WO_REG(srfsh, srfsh, GS_SRFSH); +GS_DEFINE_WO_REG(synch1, synch1, GS_SYNCH1); +GS_DEFINE_WO_REG(synch2, synch2, GS_SYNCH2); +GS_DEFINE_WO_REG(syncv, syncv, GS_SYNCV); +GS_DEFINE_WO_REG(dispfb1, dispfb, GS_DISPFB1); +GS_DEFINE_WO_REG(display1, display, GS_DISPLAY1); +GS_DEFINE_WO_REG(dispfb2, dispfb, GS_DISPFB2); +GS_DEFINE_WO_REG(display2, display, GS_DISPLAY2); +GS_DEFINE_WO_REG(extbuf, extbuf, GS_EXTBUF); +GS_DEFINE_WO_REG(extdata, extdata, GS_EXTDATA); +GS_DEFINE_WO_REG(extwrite, extwrite, GS_EXTWRITE); +GS_DEFINE_WO_REG(bgcolor, bgcolor, GS_BGCOLOR); +GS_DEFINE_RW_REG(csr, csr, GS_CSR); /* Read-write */ +GS_DEFINE_WO_REG(imr, imr, GS_IMR); +GS_DEFINE_WO_REG(busdir, busdir, GS_BUSDIR); +GS_DEFINE_RW_REG(siglblid, siglblid, GS_SIGLBLID); /* Read-write */ MODULE_DESCRIPTION("PlayStation 2 privileged Graphics Synthesizer registers"); MODULE_AUTHOR("Fredrik Noring"); From patchwork Sun Sep 1 16:19:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125497 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AFAC913B1 for ; Sun, 1 Sep 2019 16:19:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8C0CD233A2 for ; Sun, 1 Sep 2019 16:19:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728616AbfIAQTx (ORCPT ); Sun, 1 Sep 2019 12:19:53 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44414 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAQTx (ORCPT ); Sun, 1 Sep 2019 12:19:53 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 76BF33F660 for ; Sun, 1 Sep 2019 18:19:51 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pvqKcEilYgdH for ; Sun, 1 Sep 2019 18:19:50 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id D3C8A3F58C for ; Sun, 1 Sep 2019 18:19:50 +0200 (CEST) Date: Sun, 1 Sep 2019 18:19:50 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 080/120] MIPS: PS2: GS: Define gs_xorq_imr() Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- Perhaps this function could have a better name? --- arch/mips/include/asm/mach-ps2/gs-registers.h | 8 ++++++++ drivers/ps2/gs-registers.c | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/gs-registers.h b/arch/mips/include/asm/mach-ps2/gs-registers.h index 596e277a6940..badcb3cce5c2 100644 --- a/arch/mips/include/asm/mach-ps2/gs-registers.h +++ b/arch/mips/include/asm/mach-ps2/gs-registers.h @@ -609,4 +609,12 @@ GS_DECLARE_RW_REG(imr, imr); GS_DECLARE_RW_REG(busdir, busdir); GS_DECLARE_RW_REG(siglblid, siglblid); +/** + * gs_xorq_imr - exclusive or (XOR) value with the IMR register + * @value: value to XOR with the IMR register + * + * Return: the resulting IMR value + */ +u64 gs_xorq_imr(u64 value); + #endif /* __ASM_MACH_PS2_GS_REGISTERS_H */ diff --git a/drivers/ps2/gs-registers.c b/drivers/ps2/gs-registers.c index 1bd1d072f4cf..8d2bdd26438d 100644 --- a/drivers/ps2/gs-registers.c +++ b/drivers/ps2/gs-registers.c @@ -167,6 +167,23 @@ GS_DEFINE_WO_REG(imr, imr, GS_IMR); GS_DEFINE_WO_REG(busdir, busdir, GS_BUSDIR); GS_DEFINE_RW_REG(siglblid, siglblid, GS_SIGLBLID); /* Read-write */ +u64 gs_xorq_imr(u64 value) +{ + unsigned long flags; + + spin_lock_irqsave(&gs_registers.lock, flags); + + WARN_ON_ONCE(!gs_registers.imr.valid); + value = value ^ gs_registers.imr.value; + gs_registers.imr.value = value; + outq(value, GS_IMR); + + spin_unlock_irqrestore(&gs_registers.lock, flags); + + return value; +} +EXPORT_SYMBOL_GPL(gs_xorq_imr); + MODULE_DESCRIPTION("PlayStation 2 privileged Graphics Synthesizer registers"); MODULE_AUTHOR("Fredrik Noring"); MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:20:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125499 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 619EF13B1 for ; Sun, 1 Sep 2019 16:20:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4802322CE9 for ; Sun, 1 Sep 2019 16:20:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728570AbfIAQUV (ORCPT ); Sun, 1 Sep 2019 12:20:21 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44434 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAQUU (ORCPT ); Sun, 1 Sep 2019 12:20:20 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 0DEEE3F660 for ; Sun, 1 Sep 2019 18:20:19 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id q01IsAAr1y7W for ; Sun, 1 Sep 2019 18:20:18 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 4803E3F58C for ; Sun, 1 Sep 2019 18:20:18 +0200 (CEST) Date: Sun, 1 Sep 2019 18:20:18 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 081/120] MIPS: PS2: GS: Privileged register write macros with named fields Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Graphics Synthesizer write macros simplifies register writing, allowing named fields in statements such as GS_WRITE_CSR( .flush = 1 ). The following registers have macros: PMODE, SMODE1, SMODE2, SRFSH, SYNCH1, SYNCH2, SYNCV, DISPLAY1, DISPLAY2, DISPFB1, DISPFB2, CSR and BUSDIR. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs-registers.h | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/gs-registers.h b/arch/mips/include/asm/mach-ps2/gs-registers.h index badcb3cce5c2..95243a35e26d 100644 --- a/arch/mips/include/asm/mach-ps2/gs-registers.h +++ b/arch/mips/include/asm/mach-ps2/gs-registers.h @@ -609,6 +609,32 @@ GS_DECLARE_RW_REG(imr, imr); GS_DECLARE_RW_REG(busdir, busdir); GS_DECLARE_RW_REG(siglblid, siglblid); +#define GS_WS_REG(reg, str, ...) \ + gs_write_##reg((struct gs_##str) { __VA_ARGS__ }) + +/** + * DOC: + * + * The Graphics Synthesizer write macros simplifies register writing, + * allowing named fields in statements such as GS_WRITE_CSR( .flush = 1 ). + * + * The following registers have macros: PMODE, SMODE1, SMODE2, SRFSH, SYNCH1, + * SYNCH2, SYNCV, DISPLAY1, DISPLAY2, DISPFB1, DISPFB2, CSR and BUSDIR. + */ +#define GS_WRITE_PMODE(...) GS_WS_REG(pmode, pmode, __VA_ARGS__) +#define GS_WRITE_SMODE1(...) GS_WS_REG(smode1, smode1, __VA_ARGS__) +#define GS_WRITE_SMODE2(...) GS_WS_REG(smode2, smode2, __VA_ARGS__) +#define GS_WRITE_SRFSH(...) GS_WS_REG(srfsh, srfsh, __VA_ARGS__) +#define GS_WRITE_SYNCH1(...) GS_WS_REG(synch1, synch1, __VA_ARGS__) +#define GS_WRITE_SYNCH2(...) GS_WS_REG(synch2, synch2, __VA_ARGS__) +#define GS_WRITE_SYNCV(...) GS_WS_REG(syncv, syncv, __VA_ARGS__) +#define GS_WRITE_DISPLAY1(...) GS_WS_REG(display1, display, __VA_ARGS__) +#define GS_WRITE_DISPLAY2(...) GS_WS_REG(display2, display, __VA_ARGS__) +#define GS_WRITE_DISPFB1(...) GS_WS_REG(dispfb1, dispfb, __VA_ARGS__) +#define GS_WRITE_DISPFB2(...) GS_WS_REG(dispfb2, dispfb, __VA_ARGS__) +#define GS_WRITE_CSR(...) GS_WS_REG(csr, csr, __VA_ARGS__) +#define GS_WRITE_BUSDIR(...) GS_WS_REG(busdir, busdir, __VA_ARGS__) + /** * gs_xorq_imr - exclusive or (XOR) value with the IMR register * @value: value to XOR with the IMR register From patchwork Sun Sep 1 16:20:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125501 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2039113B1 for ; Sun, 1 Sep 2019 16:20:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 05FC9233A2 for ; Sun, 1 Sep 2019 16:20:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728616AbfIAQUb (ORCPT ); Sun, 1 Sep 2019 12:20:31 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44494 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728496AbfIAQUb (ORCPT ); Sun, 1 Sep 2019 12:20:31 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id EF4EB3F660 for ; Sun, 1 Sep 2019 18:20:29 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xJ3QFlcRDSFt for ; Sun, 1 Sep 2019 18:20:29 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 467EB3F58C for ; Sun, 1 Sep 2019 18:20:29 +0200 (CEST) Date: Sun, 1 Sep 2019 18:20:29 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 082/120] MIPS: PS2: GS: IRQ support Message-ID: <09484c957252ee213b72c6173f692f7b28a29109.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/irq.h | 1 + drivers/ps2/Makefile | 1 + drivers/ps2/gs-irq.c | 93 ++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 drivers/ps2/gs-irq.c diff --git a/arch/mips/include/asm/mach-ps2/irq.h b/arch/mips/include/asm/mach-ps2/irq.h index 57b3e539ad92..132ad329de6b 100644 --- a/arch/mips/include/asm/mach-ps2/irq.h +++ b/arch/mips/include/asm/mach-ps2/irq.h @@ -120,6 +120,7 @@ int __init intc_irq_init(void); int __init dmac_irq_init(void); +int gs_irq_init(void); /* * IRQs asserted by the I/O processor (IOP) via the sub-system interface (SIF). diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index 533ab86d6a58..7f108d4ee451 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_PS2_GS) += gs-irq.o obj-$(CONFIG_PS2_GS) += gs-registers.o obj-m += iop-heap.o diff --git a/drivers/ps2/gs-irq.c b/drivers/ps2/gs-irq.c new file mode 100644 index 000000000000..55116a8b5582 --- /dev/null +++ b/drivers/ps2/gs-irq.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer (GS) IRQs + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +static void gs_reverse_mask(struct irq_data *data) +{ + gs_xorq_imr(BIT(8 + data->irq - IRQ_GS)); +} + +static void gs_ack(struct irq_data *data) +{ + gs_writeq_csr(BIT(data->irq - IRQ_GS)); +} + +#define GS_IRQ_TYPE(irq_, name_) \ + { \ + .irq = irq_, \ + .irq_chip = { \ + .name = name_, \ + .irq_unmask = gs_reverse_mask, \ + .irq_mask = gs_reverse_mask, \ + .irq_ack = gs_ack \ + } \ + } + +static struct { + unsigned int irq; + struct irq_chip irq_chip; +} gs_irqs[] = { + GS_IRQ_TYPE(IRQ_GS_SIGNAL, "GS SIGNAL"), + GS_IRQ_TYPE(IRQ_GS_FINISH, "GS FINISH"), + GS_IRQ_TYPE(IRQ_GS_HSYNC, "GS HSYNC"), + GS_IRQ_TYPE(IRQ_GS_VSYNC, "GS VSYNC"), + GS_IRQ_TYPE(IRQ_GS_EDW, "GS EDW"), + GS_IRQ_TYPE(IRQ_GS_EXHSYNC, "GS EXHSYNC"), + GS_IRQ_TYPE(IRQ_GS_EXVSYNC, "GS EXVSYNC"), +}; + +static irqreturn_t gs_cascade(int irq, void *data) +{ + unsigned int pending = gs_readq_csr() & 0x1f; + + if (!pending) + return IRQ_NONE; + + while (pending) { + const unsigned int irq_gs = __fls(pending); + + if (generic_handle_irq(irq_gs + IRQ_GS) < 0) + spurious_interrupt(); + pending &= ~BIT(irq_gs); + } + + return IRQ_HANDLED; +} + +static struct irqaction cascade_gs_irqaction = { + .name = "GS cascade", + .handler = gs_cascade, +}; + +int gs_irq_init(void) +{ + size_t i; + int err; + + gs_writeq_imr(0x7f00); /* Disable GS interrupts */ + gs_writeq_csr(0x00ff); /* Clear GS events */ + + for (i = 0; i < ARRAY_SIZE(gs_irqs); i++) + irq_set_chip_and_handler(gs_irqs[i].irq, + &gs_irqs[i].irq_chip, handle_level_irq); + + err = setup_irq(IRQ_INTC_GS, &cascade_gs_irqaction); + if (err) + pr_err("gs-irq: Failed to setup GS IRQs (err = %d)\n", err); + + return err; +} From patchwork Sun Sep 1 16:21:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125503 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9FE6013B1 for ; Sun, 1 Sep 2019 16:21:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7369F233A2 for ; Sun, 1 Sep 2019 16:21:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728496AbfIAQVF (ORCPT ); Sun, 1 Sep 2019 12:21:05 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44530 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAQVF (ORCPT ); Sun, 1 Sep 2019 12:21:05 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 8563F3F672 for ; Sun, 1 Sep 2019 18:21:01 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bBJgU-D3DJ3j for ; Sun, 1 Sep 2019 18:21:00 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 6EE993F58C for ; Sun, 1 Sep 2019 18:21:00 +0200 (CEST) Date: Sun, 1 Sep 2019 18:21:00 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 083/120] MIPS: PS2: GS: Define Graphics Synthesizer primitive structures Message-ID: <25b6c975d334c0678ab3963d6c76584ed9471c35.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Graphics Synthesizer has 4 MiB of local frame buffer memory that is not directly accessible from the main bus. All drawing operations must be performed with serialized drawing primitives via the Graphics Synthesizer interface (GIF), either by DMA or a vector processor[1]. The GS frame buffer is subdivided into rectangular pages, from left to right, top to bottom. Pages are further subdivided into blocks, with different arrangements for the PSMCT16 and PSMCT32 pixel storage modes. Blocks are further subdivided into columns that are finally subdivided into pixels. The general purpose GS registers are used to set vertex information, drawing environment and transmission between buffers for the drawing primitives. All of them are write-only registers. The following registers are available. Registers with "_1" and "_2" suffixes are designed to operate in one of the two drawing contexts. Register | Description -----------+-------------------------------------------------------- PRIM | Drawing primitive setting RGBAQ | Vertex colour setting ST | Vertex texture coordinate setting (texture coordinates) UV | Vertex texture coordinate setting (texel coordinates) XYZF2 | Vertex coordinate value setting XYZ2 | Vertex coordinate value setting TEX0_1 | Texture information setting TEX0_2 | Texture information setting CLAMP_1 | Texture wrap mode CLAMP_2 | Texture wrap mode FOG | Vertex fog value setting XYZF3 | Vertex coordinate value setting (without drawing kick) XYZ3 | Vertex coordinate value setting (without drawing kick) TEX1_1 | Texture information setting TEX1_2 | Texture information setting TEX2_1 | Texture information setting TEX2_2 | Texture information setting XYOFFSET_1 | Offset value setting XYOFFSET_2 | Offset value setting PRMODECONT | Specification of primitive attribute setting method PRMODE | Drawing primitive attribute setting TEXCLUT | Colour lookup table position setting SCANMSK | Raster address mask setting MIPTBP1_1 | MIPMAP information setting (Level 1 – 3) MIPTBP1_2 | MIPMAP information setting (Level 1 – 3) MIPTBP2_1 | MIPMAP information setting (Level 4 – 6) MIPTBP2_2 | MIPMAP information setting (Level 4 – 6) TEXA | Texture alpha value setting FOGCOL | Distant fog colour setting TEXFLUSH | Texture page buffer disabling SCISSOR_1 | Scissoring area setting SCISSOR_2 | Scissoring area setting ALPHA_1 | Alpha blending setting ALPHA_2 | Alpha blending setting DIMX | Dither matrix setting DTHE | Dither control COLCLAMP | Colour clamp control TEST_1 | Pixel test control TEST_2 | Pixel test control PABE | Alpha blending control in pixel units FBA_1 | Alpha correction value FBA_2 | Alpha correction value FRAME_1 | Frame buffer setting FRAME_2 | Frame buffer setting ZBUF_1 | Z buffer setting ZBUF_2 | Z buffer setting BITBLTBUF | Setting for transmission between buffers TRXPOS | Specification for transmission area in buffers TRXREG | Specification for transmission area in buffers TRXDIR | Activation of transmission between buffers HWREG | Data port for transmission between buffers SIGNAL | SIGNAL event occurrence request FINISH | FINISH event occurrence request LABEL | LABEL event occurrence request -----------+-------------------------------------------------------- References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 158, 161-175. Signed-off-by: Fredrik Noring --- arch/mips/include/uapi/asm/gs.h | 723 ++++++++++++++++++++++++++++++++ 1 file changed, 723 insertions(+) create mode 100644 arch/mips/include/uapi/asm/gs.h diff --git a/arch/mips/include/uapi/asm/gs.h b/arch/mips/include/uapi/asm/gs.h new file mode 100644 index 000000000000..074bb62a4bd0 --- /dev/null +++ b/arch/mips/include/uapi/asm/gs.h @@ -0,0 +1,723 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer (GS) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef _UAPI_MIPS_ASM_GS_H +#define _UAPI_MIPS_ASM_GS_H + +#include + +/** + * DOC: The PlayStation 2 Graphics Synthesizer + * + * The Graphics Synthesizer frame buffer is subdivided into rectangular pages, + * from left to right, top to bottom. Pages are further subdivided into blocks, + * with different arrangements for the PSMCT16 and PSMCT32 pixel storage modes. + * Blocks are further subdivided into columns that are finally subdivided into + * pixels. + * + * The frame buffer width (FBW) is defined as the pixel width divided by 64, + * where 64 is the width of a page for PSMCT16 and PSMCT32. + * + * The texture base pointer (TBP), color base pointer (CBP), source base + * pointer (SBP) and destination base pointer (DBP) are all addressed by block. + * + * As an example, consider the frame buffer resolution 1920x1080@16 that uses + * 1920*1080*2 = 4147200 bytes of the 4 MiB = 4194304 bytes available memory. + * There are 4194304-4147200 = 47104 bytes of free memory. The FBW is 1920/64 + * = 30, which means it is 30 pages wide. However, 1080/GS_PSM_CT32_PAGE_HEIGHT + * = 1080/64 = 16.875, which means that the last row of blocks are unused in + * the last page row. These make up 30*4 = 120 blocks of the 47104/256 = 184 + * blocks available. To make effective use of free memory for this resolution + * in particular, it is essential to compute accurate block addresses. + */ + +#define GS_COLUMNS_PER_BLOCK 4 +#define GS_BLOCKS_PER_PAGE 32 + +#define GS_PAGE_COUNT 512 +#define GS_BLOCK_COUNT (GS_PAGE_COUNT * GS_BLOCKS_PER_PAGE) +#define GS_COLUMN_COUNT (GS_BLOCK_COUNT * GS_COLUMNS_PER_PAGE) + +#define GS_COLUMN_SIZE 64 +#define GS_BLOCK_SIZE (GS_COLUMNS_PER_BLOCK * GS_COLUMN_SIZE) +#define GS_PAGE_SIZE (GS_BLOCKS_PER_PAGE * GS_BLOCK_SIZE) +#define GS_MEMORY_SIZE (GS_PAGE_COUNT * GS_PAGE_SIZE) /* 4 MiB of memory */ + +#define GS_FB_PAGE_WIDTH 64 +#define GS_FB_BASE_DIVISOR 2048 /* FIXME: GS_FB_PAGE_WORDS */ + +/* All pixel storage formats have 1 block column and 4 block rows. */ +#define GS_BLOCK_COLS 1 +#define GS_BLOCK_ROWS 4 + +/* 4 bit (16 color) texture pixel storage format. */ +#define GS_PSMT4_PAGE_COLS 4 +#define GS_PSMT4_PAGE_ROWS 8 +#define GS_PSMT4_COLUMN_WIDTH 32 +#define GS_PSMT4_COLUMN_HEIGHT 4 +#define GS_PSMT4_BLOCK_WIDTH (GS_PSMT4_COLUMN_WIDTH * GS_BLOCK_COLS) +#define GS_PSMT4_BLOCK_HEIGHT (GS_PSMT4_COLUMN_HEIGHT * GS_BLOCK_ROWS) +#define GS_PSMT4_PAGE_WIDTH (GS_PSMT4_BLOCK_WIDTH * GS_PSMT4_PAGE_COLS) +#define GS_PSMT4_PAGE_HEIGHT (GS_PSMT4_BLOCK_HEIGHT * GS_PSMT4_PAGE_ROWS) + +/* 8 bit (256 color) texture pixel storage format. */ +#define GS_PSMT8_PAGE_COLS 8 +#define GS_PSMT8_PAGE_ROWS 4 +#define GS_PSMT8_COLUMN_WIDTH 16 +#define GS_PSMT8_COLUMN_HEIGHT 4 +#define GS_PSMT8_BLOCK_WIDTH (GS_PSMT8_COLUMN_WIDTH * GS_BLOCK_COLS) +#define GS_PSMT8_BLOCK_HEIGHT (GS_PSMT8_COLUMN_HEIGHT * GS_BLOCK_ROWS) +#define GS_PSMT8_PAGE_WIDTH (GS_PSMT8_BLOCK_WIDTH * GS_PSMT8_PAGE_COLS) +#define GS_PSMT8_PAGE_HEIGHT (GS_PSMT8_BLOCK_HEIGHT * GS_PSMT8_PAGE_ROWS) + +/* 16 bit (true color) frame buffer and texture pixel storage format. */ +#define GS_PSM_CT16_PAGE_COLS 4 +#define GS_PSM_CT16_PAGE_ROWS 8 +#define GS_PSM_CT16_COLUMN_WIDTH 8 +#define GS_PSM_CT16_COLUMN_HEIGHT 2 +#define GS_PSM_CT16_BLOCK_WIDTH (GS_PSM_CT16_COLUMN_WIDTH * GS_BLOCK_COLS) +#define GS_PSM_CT16_BLOCK_HEIGHT (GS_PSM_CT16_COLUMN_HEIGHT * GS_BLOCK_ROWS) +#define GS_PSM_CT16_PAGE_WIDTH (GS_PSM_CT16_BLOCK_WIDTH * GS_PSM_CT16_PAGE_COLS) +#define GS_PSM_CT16_PAGE_HEIGHT (GS_PSM_CT16_BLOCK_HEIGHT * GS_PSM_CT16_PAGE_ROWS) + +/* 32 bit (true color) frame buffer and texture pixel storage format. */ +#define GS_PSM_CT32_PAGE_COLS 8 +#define GS_PSM_CT32_PAGE_ROWS 4 +#define GS_PSM_CT32_COLUMN_WIDTH 16 +#define GS_PSM_CT32_COLUMN_HEIGHT 2 +#define GS_PSM_CT32_BLOCK_WIDTH (GS_PSM_CT32_COLUMN_WIDTH * GS_BLOCK_COLS) +#define GS_PSM_CT32_BLOCK_HEIGHT (GS_PSM_CT32_COLUMN_HEIGHT * GS_BLOCK_ROWS) +#define GS_PSM_CT32_PAGE_WIDTH (GS_PSM_CT32_BLOCK_WIDTH * GS_PSM_CT32_PAGE_COLS) +#define GS_PSM_CT32_PAGE_HEIGHT (GS_PSM_CT32_BLOCK_HEIGHT * GS_PSM_CT32_PAGE_ROWS) + +#define GS_ALPHA_ONE 0x80 /* Alpha 0x80 = 1.0 */ + +/** + * struct gs_rgba16 - 16-bit red, green, blue colour and alpha transparency + * @a: 1-bit alpha transparency + * @b: 5-bit blue colour component + * @g: 5-bit green colour component + * @r: 5-bit red colour component + * + * Alpha is treated as 0 when @a is 0, and as %GS_ALPHA_ONE when @a is 1. + */ +struct gs_rgba16 { + __BITFIELD_FIELD(__u16 a : 1, + __BITFIELD_FIELD(__u16 b : 5, + __BITFIELD_FIELD(__u16 g : 5, + __BITFIELD_FIELD(__u16 r : 5, + ;)))) +}; + +/** + * struct gs_rgba32 - 32-bit red, green, blue colour and alpha transparency + * @a: 8-bit alpha transparency, with %GS_ALPHA_ONE representing 1.0 + * @b: 8-bit blue colour component + * @g: 8-bit green colour component + * @r: 8-bit red colour component + */ +struct gs_rgba32 { + __BITFIELD_FIELD(__u32 a : 8, + __BITFIELD_FIELD(__u32 b : 8, + __BITFIELD_FIELD(__u32 g : 8, + __BITFIELD_FIELD(__u32 r : 8, + ;)))) +}; + +enum gs_register_address { + gs_addr_prim = 0x00, gs_addr_rgbaq = 0x01, + gs_addr_st = 0x02, gs_addr_uv = 0x03, + gs_addr_xyzf2 = 0x04, gs_addr_xyz2 = 0x05, + gs_addr_tex0_1 = 0x06, gs_addr_tex0_2 = 0x07, + gs_addr_clamp_1 = 0x08, gs_addr_clamp_2 = 0x09, + gs_addr_fog = 0x0a, gs_addr_xyzf3 = 0x0c, + gs_addr_xyz3 = 0x0d, gs_addr_tex1_1 = 0x14, + gs_addr_tex1_2 = 0x15, gs_addr_tex2_1 = 0x16, + gs_addr_tex2_2 = 0x17, gs_addr_xyoffset_1 = 0x18, + gs_addr_xyoffset_2 = 0x19, gs_addr_prmodecont = 0x1a, + gs_addr_prmode = 0x1b, gs_addr_texclut = 0x1c, + gs_addr_scanmsk = 0x22, gs_addr_miptbp1_1 = 0x34, + gs_addr_miptbp1_2 = 0x35, gs_addr_miptbp2_1 = 0x36, + gs_addr_miptbp2_2 = 0x37, gs_addr_texa = 0x3b, + gs_addr_fogcol = 0x3d, gs_addr_texflush = 0x3f, + gs_addr_scissor_1 = 0x40, gs_addr_scissor_2 = 0x41, + gs_addr_alpha_1 = 0x42, gs_addr_alpha_2 = 0x43, + gs_addr_dimx = 0x44, gs_addr_dthe = 0x45, + gs_addr_colclamp = 0x46, gs_addr_test_1 = 0x47, + gs_addr_test_2 = 0x48, gs_addr_pabe = 0x49, + gs_addr_fba_1 = 0x4a, gs_addr_fba_2 = 0x4b, + gs_addr_frame_1 = 0x4c, gs_addr_frame_2 = 0x4d, + gs_addr_zbuf_1 = 0x4e, gs_addr_zbuf_2 = 0x4f, + gs_addr_bitbltbuf = 0x50, gs_addr_trxpos = 0x51, + gs_addr_trxreg = 0x52, gs_addr_trxdir = 0x53, + gs_addr_hwreg = 0x54, gs_addr_signal = 0x60, + gs_addr_finish = 0x61, gs_addr_label = 0x62, + gs_addr_nop = 0x7f +}; + +enum gs_prim_fix { gs_fragment_unfixed, gs_fragment_fixed }; +enum gs_prim_ctxt { gs_context_1, gs_context_2 }; +enum gs_prim_fst { gs_texturing_stq, gs_texturing_uv }; +enum gs_prim_aa1 { gs_pass_antialiasing_off, gs_pass_antialiasing_on }; +enum gs_prim_abe { gs_blendning_off, gs_blendning_on }; +enum gs_prim_fge { gs_fogging_off, gs_fogging_on }; +enum gs_prim_tme { gs_texturing_off, gs_texturing_on }; +enum gs_prim_iip { gs_flat_shading, gs_gouraud_shading }; +enum gs_prim_type { + gs_point, gs_line, gs_linestrip, gs_triangle, + gs_trianglestrip, gs_trianglefan, gs_sprite +}; + +/** + * struct gs_prim - drawing primitive + * @fix: fragment value control + * @ctxt: context + * @fst: texture coordinate method + * @aa1: pass antialiasing + * @abe: alpha blendning + * @fge: fogging + * @tme: texture mapping + * @iip: shading method + * @prim: type of drawing primitive + * + * The IIP/TME/FGE/ABE/AA1/FST/CTXT/FIX fields are only enabled when AC is 1 + * in the PRMODECONT register. + */ +struct gs_prim { + __BITFIELD_FIELD(__u64 : 53, + __BITFIELD_FIELD(__u64 fix : 1, + __BITFIELD_FIELD(__u64 ctxt : 1, + __BITFIELD_FIELD(__u64 fst : 1, + __BITFIELD_FIELD(__u64 aa1 : 1, + __BITFIELD_FIELD(__u64 abe : 1, + __BITFIELD_FIELD(__u64 fge : 1, + __BITFIELD_FIELD(__u64 tme : 1, + __BITFIELD_FIELD(__u64 iip : 1, + __BITFIELD_FIELD(__u64 prim : 3, + ;)))))))))) +}; + +/** + * struct gs_prmode - attributes of drawing primitives + * @fix: fragment value control + * @ctxt: context + * @fst: texture coordinate method + * @aa1: pass antialiasing + * @abe: alpha blendning + * @fge: fogging + * @tme: texture mapping + * @iip: shading method + * + * The IIP/TME/FGE/ABE/AA1/FST/CTXT/FIX fields are only enabled when AC is 0 + * in the PRMODECONT register. + */ +struct gs_prmode { + __BITFIELD_FIELD(__u64 : 53, + __BITFIELD_FIELD(__u64 fix : 1, + __BITFIELD_FIELD(__u64 ctxt : 1, + __BITFIELD_FIELD(__u64 fst : 1, + __BITFIELD_FIELD(__u64 aa1 : 1, + __BITFIELD_FIELD(__u64 abe : 1, + __BITFIELD_FIELD(__u64 fge : 1, + __BITFIELD_FIELD(__u64 tme : 1, + __BITFIELD_FIELD(__u64 iip : 1, + __BITFIELD_FIELD(__u64 : 3, + ;)))))))))) +}; + +/** + * struct gs_prmodecont - primitive attribute setting method + * @ac: enable PRMODE (= 0) or PRIM (= 1) + */ +struct gs_prmodecont { + __BITFIELD_FIELD(__u64 : 63, + __BITFIELD_FIELD(__u64 ac : 1, + ;)) +}; + +enum gs_psm { + gs_psm_ct32 = 0x00, gs_psm_ct24 = 0x01, gs_psm_ct16 = 0x02, + gs_psm_ct16s = 0x0a, gs_psm_gpu24 = 0x12, gs_psm_t8 = 0x13, + gs_psm_t4 = 0x14, gs_psm_t8h = 0x1b, gs_psm_t4hl = 0x24, + gs_psm_t4hh = 0x2c, gs_psm_z32 = 0x30, gs_psm_z24 = 0x31, + gs_psm_z16 = 0x32, gs_psm_z16s = 0x3a +}; + +/** + * struct gs_bitbltbuf - transmission between buffers + * @dpsm: destination pixel format + * @dbw: destination width/64 + * @dbp: destination base word/64 + * @spsm: source pixel format + * @sbw: source width/64 + * @sbp: source base word/64 + * + * Host -> local: Only destination fields are used. + * + * Local -> host: Only source fields are used. The pixel formats PSMT4, + * PSMT4HL and PSMT4HH cannot be used. + * + * Local -> local: Both source and destination fields are used. The bits + * per pixel for source and destination must be equal. + * + * The rectangular area wraps around when exceeding the buffer width. + * + * Limitations on TRXPOS start x coordinate transmissions (not applicable + * for local -> host): + * + * Multiple of 2: PSMT8, PSMT8H + * Multiple of 4: PSMT4, PSMT4HL, PSMT4HH + * + * Limitations on TRXREG width (not applicable for local -> host): + * + * Multiple of 2: PSMCT32, PSMZ32 + * Multiple of 4: PSMCT16, PSMCT16S, PSMZ16, PSMZ16S + * Multiple of 8: PSMCT24, PSMZ24, PSMT8, PSMT8H, PSMT4, PSMT4HL, PSMT4HH + */ +struct gs_bitbltbuf { + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 dpsm : 6, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 dbw : 6, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 dbp : 14, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 spsm : 6, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 sbw : 6, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 sbp : 14, + ;)))))))))))) +}; + +enum gs_clamp_mode { + gs_clamp_repeat, gs_clamp_clamp, + gs_clamp_region_clamp, gs_clamp_region_repeat +}; + +/** + * struct gs_clamp - texture wrap mode + * @maxv: upper v clamp parameter + * @minv: lower v clamp parameter + * @maxu: upper u clamp parameter + * @minu: lower u clamp parameter + * @wmt: vertical wrap mode + * @wms: horizontal wrap mode + */ +struct gs_clamp { + __BITFIELD_FIELD(__u64 : 20, + __BITFIELD_FIELD(__u64 maxv : 10, + __BITFIELD_FIELD(__u64 minv : 10, + __BITFIELD_FIELD(__u64 maxu : 10, + __BITFIELD_FIELD(__u64 minu : 10, + __BITFIELD_FIELD(__u64 wmt : 2, + __BITFIELD_FIELD(__u64 wms : 2, + ;))))))) +}; + +/** + * struct gs_frame_12 - frame buffer + * @fbmsk: frame buffer drawing mask + * @psm: frame buffer pixel format + * @fbw: frame buffer width/64 + * @fbp: frame buffer base/2048 + */ +struct gs_frame_12 { + __BITFIELD_FIELD(__u64 fbmsk : 32, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 psm : 6, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 fbw : 6, + __BITFIELD_FIELD(__u64 : 7, + __BITFIELD_FIELD(__u64 fbp : 9, + ;))))))) +}; + +/** + * enum gs_scanmsk - raster address mask + * @gs_scanmsk_normal: normal drawing (not masked) + * @gs_scanmsk_even: drawing of pixel with even y coordinate is prohibited + * @gs_scanmsk_odd: drawing of pixel with odd y coordinate is prohibited + */ +enum gs_scanmsk { + gs_scanmsk_normal, + /* Reserved */ + gs_scanmsk_even = 2, + gs_scanmsk_odd +}; + +/** + * struct gs_scanmsk_12 - raster address mask + * @msk: raster address mask + */ +struct gs_scanmsk_12 { + __BITFIELD_FIELD(__u64 : 62, + __BITFIELD_FIELD(__u64 msk : 2, + ;)) +}; + +/** + * struct gs_scissor_12 - scissoring area + * @scay1: lower right y + * @scay0: upper left y + * @scax1: lower right x + * @scax0: upper left x + * + * All SCISSOR coordinates are in the window coordinate system. + */ +struct gs_scissor_12 { + __BITFIELD_FIELD(__u64 : 5, + __BITFIELD_FIELD(__u64 scay1 : 11, + __BITFIELD_FIELD(__u64 : 5, + __BITFIELD_FIELD(__u64 scay0 : 11, + __BITFIELD_FIELD(__u64 : 5, + __BITFIELD_FIELD(__u64 scax1 : 11, + __BITFIELD_FIELD(__u64 : 5, + __BITFIELD_FIELD(__u64 scax0 : 11, + ;)))))))) +}; + +/** + * enum gs_trxpos_dir - transmission direction + * @gs_trxpos_dir_ul_lr: upper left -> lower right + * @gs_trxpos_dir_ll_ur: lower left -> upper right + * @gs_trxpos_dir_ur_ll: upper right -> lower left + * @gs_trxpos_dir_lr_ul: lower right -> upper left + * + * The pixel transmission order is enabled only for local -> local. + */ +enum gs_trxpos_dir { + gs_trxpos_dir_ul_lr, + gs_trxpos_dir_ll_ur, + gs_trxpos_dir_ur_ll, + gs_trxpos_dir_lr_ul, +}; + +/** + * struct gs_trxpos - transmission areass in buffers + * @dir: Pixel transmission order + * @dsay: Destination start y + * @dsax: Destination start x + * @ssay: Source start y + * @ssax: Source start x + * + * Host -> local: Only destination fields are used. DIR is ignored and the + * pixel transmission order is always left to right and top to bottom. + * + * Local -> host: Only source fields are used. DIR is ignored and the pixel + * transmission order is always left to right and top to bottom. + * + * Local -> local: Both source and destination fields are used. The pixel + * transmission order DIR is used. + */ +struct gs_trxpos { + __BITFIELD_FIELD(__u64 : 3, + __BITFIELD_FIELD(__u64 dir : 2, + __BITFIELD_FIELD(__u64 dsay : 11, + __BITFIELD_FIELD(__u64 : 5, + __BITFIELD_FIELD(__u64 dsax : 11, + __BITFIELD_FIELD(__u64 : 5, + __BITFIELD_FIELD(__u64 ssay : 11, + __BITFIELD_FIELD(__u64 : 5, + __BITFIELD_FIELD(__u64 ssax : 11, + ;))))))))) +}; + +/** + * struct gs_trxreg - transmission areas in buffers + * @rrh: transmission area height + * @rrw: transmission area width + * + * The transmission coordinates are modulo 2048 (wrap around). + */ +struct gs_trxreg { + __BITFIELD_FIELD(__u64 : 20, + __BITFIELD_FIELD(__u64 rrh : 12, + __BITFIELD_FIELD(__u64 : 20, + __BITFIELD_FIELD(__u64 rrw : 12, + ;)))) +}; + +enum gs_trxdir_xdir { + gs_trxdir_host_to_local, + gs_trxdir_local_to_host, + gs_trxdir_local_to_local, + gs_trxdir_nil, /* Deactivated transmission */ +}; + +/** + * struct gs_trxdir - activation of transmission between buffers + * @xdir: transmission direction + * + * The TRXDIR register specifies the transmission + * direction and activates the transmission. + */ +struct gs_trxdir { + __BITFIELD_FIELD(__u64 : 62, + __BITFIELD_FIELD(__u64 xdir : 2, + ;)) +}; + +enum gs_alpha_test { gs_alpha_test_off, gs_alpha_test_on }; +enum gs_alpha_method { + gs_alpha_method_fail, gs_alpha_method_pass, gs_alpha_method_less, + gs_alpha_method_lequal, gs_alpha_method_equal, gs_alpha_method_gequal, + gs_alpha_method_greater, gs_alpha_method_notequal +}; +enum gs_alpha_failed { + gs_alpha_failed_keep, gs_alpha_failed_fb_only, + gs_alpha_failed_zb_only, gs_alpha_failed_rgb_only +}; +enum gs_alpha_dst_test { gs_alpha_dst_test_off, gs_alpha_dst_test_on }; +enum gs_alpha_dst_method { gs_alpha_dst_pass0, gs_alpha_dst_pass1 }; +enum gs_depth_test { gs_depth_test_off, gs_depth_test_on }; +enum gs_depth_method { + gs_depth_fail, gs_depth_pass, gs_depth_gequal, gs_depth_greater +}; + +/** + * struct gs_test_12 - pixel test control + * @ztst: depth test method + * @zte: depth test (must be 1) + * @datm: destination alpha test mode + * @date: depth test + * @afail: destination alpha test + * @aref: alpha reference comparison + * @atst: alpha test method + * @ate: alpha test + * + * The ZTE field must at all times be ON (OFF is not allowed). To emulate + * ZTE OFF, set ZTST to PASS. + */ +struct gs_test_12 { + __BITFIELD_FIELD(__u64 : 45, + __BITFIELD_FIELD(__u64 ztst : 2, + __BITFIELD_FIELD(__u64 zte : 1, + __BITFIELD_FIELD(__u64 datm : 1, + __BITFIELD_FIELD(__u64 date : 1, + __BITFIELD_FIELD(__u64 afail : 2, + __BITFIELD_FIELD(__u64 aref : 8, + __BITFIELD_FIELD(__u64 atst : 3, + __BITFIELD_FIELD(__u64 ate : 1, + ;))))))))) +}; + +/** + * struct gs_rgbaq - vertex color + * @q: normalized texture coordinate + * @a: alpha vertex value (0x80 = 1.0) + * @b: blue luminance element of vertex + * @g: green luminance element of vertex + * @r: red luminance element of vertex + * + * The Q field is used both for calculating texture coordinates and deciding + * level of detail (LOD). + */ +struct gs_rgbaq { + __BITFIELD_FIELD(__u64 q : 32, + __BITFIELD_FIELD(__u64 a : 8, + __BITFIELD_FIELD(__u64 b : 8, + __BITFIELD_FIELD(__u64 g : 8, + __BITFIELD_FIELD(__u64 r : 8, + ;))))) +}; + +/** + * struct gs_uv - vertex texture coordinates + * @v: texel coordinate v*16 + * @u: texel coordinate u*16 + */ +struct gs_uv { + __BITFIELD_FIELD(__u64 : 34, + __BITFIELD_FIELD(__u64 v : 14, + __BITFIELD_FIELD(__u64 : 2, + __BITFIELD_FIELD(__u64 u : 14, + ;)))) +}; + +/** + * struct gs_xyz23 - vertex coordinates without a drawing kick + * @z: vertext coordinate z + * @y: vertext coordinate y*16 + * @x: vertext coordinate x*16 + * + * Assigning XYZ2 moves the vertex queue one step forward. Drawing is not + * started with XYZ3 (no Drawing Kick). + * + * X and Y are specified as fixed-point (4-bit scaling factor) in the + * primitive coordinate system. + */ +struct gs_xyz23 { + __BITFIELD_FIELD(__u64 z : 32, + __BITFIELD_FIELD(__u64 y : 16, + __BITFIELD_FIELD(__u64 x : 16, + ;))) +}; + +/** + * struct gs_xyoffset_12 - primitive to window coordinate offsets + * @ofy: offset y*16 + * @ofx: offset x*16 + * + * Coordinate offsets from the primitive coordinate system to the window + * coordinate system. + */ +struct gs_xyoffset_12 { + __BITFIELD_FIELD(__u64 : 16, + __BITFIELD_FIELD(__u64 ofy : 16, + __BITFIELD_FIELD(__u64 : 16, + __BITFIELD_FIELD(__u64 ofx : 16, + ;)))) +}; + +enum gs_tfx { + gs_tfx_modulate, gs_tfx_decal, + gs_tfx_highlight, gs_tfx_highlight2 +}; + +enum gs_tcc { gs_tcc_rgb, gs_tcc_rgba }; +enum gs_csm { gs_csm1, gs_csm2 }; + +/** + * struct gs_tex0 - texture setting + * @cld: CLUT buffer load control + * @csa: CLUT entry offset + * @csm: CLUT storage mode + * @cpsm: CLUT pixel storage format + * @cbp: CLUT buffer base pointer + * @tfx: texture function + * @tcc: texture color component + * @th: texture height (2^h) + * @tw: texture width (2^w) + * @psm: texture storage format + * @tbw: texture buffer width + * @tbp0: texture base pointer + */ +struct gs_tex0 { + __BITFIELD_FIELD(__u64 cld : 3, + __BITFIELD_FIELD(__u64 csa : 5, + __BITFIELD_FIELD(__u64 csm : 1, + __BITFIELD_FIELD(__u64 cpsm : 4, + __BITFIELD_FIELD(__u64 cbp : 14, + __BITFIELD_FIELD(__u64 tfx : 2, + __BITFIELD_FIELD(__u64 tcc : 1, + __BITFIELD_FIELD(__u64 th : 4, + __BITFIELD_FIELD(__u64 tw : 4, + __BITFIELD_FIELD(__u64 psm : 6, + __BITFIELD_FIELD(__u64 tbw : 6, + __BITFIELD_FIELD(__u64 tbp0 : 14, + ;)))))))))))) +}; + +enum gs_lcm { gs_lcm_formula, gs_lcm_fixed }; + +enum gs_lod { + gs_lod_nearest, + gs_lod_linear, + gs_lod_nearest_mipmap_nearest, + gs_lod_nearest_mipmap_linear, + gs_lod_linear_mipmap_nearest, + gs_lod_linear_mipmap_linear +}; + +enum gs_aem { gs_aem_normal, gs_aem_transparent }; + +/** + * struct gs_texa - texture alpha value setting + * @ta1: alpha when A=1 in RGBA16 + * @aem: alpha expanding method + * @ta0: alpha when A=0 in RGBA16 + */ +struct gs_texa { + __BITFIELD_FIELD(__u64 : 24, + __BITFIELD_FIELD(__u64 ta1 : 8, + __BITFIELD_FIELD(__u64 : 16, + __BITFIELD_FIELD(__u64 aem : 1, + __BITFIELD_FIELD(__u64 : 7, + __BITFIELD_FIELD(__u64 ta0 : 8, + ;)))))) +}; + +/** + * struct gs_tex1 - texture setting + * @k: LOD parameter K + * @l: LOD parameter L + * @mtba: MIPMAP base address specification of level 1 or more + * @mmin: reduced texture filter + * @mmag: expanded texture filter + * @mxl: maximum MIP level + * @lcm: LOD calculation method + */ +struct gs_tex1 { + __BITFIELD_FIELD(__u64 k : 11, + __BITFIELD_FIELD(__u64 : 11, + __BITFIELD_FIELD(__u64 l : 2, + __BITFIELD_FIELD(__u64 : 9, + __BITFIELD_FIELD(__u64 mtba : 1, + __BITFIELD_FIELD(__u64 mmin : 3, + __BITFIELD_FIELD(__u64 mmag : 1, + __BITFIELD_FIELD(__u64 mxl : 3, + __BITFIELD_FIELD(__u64 : 1, + __BITFIELD_FIELD(__u64 lcm : 1, + ;)))))))))) +}; + +/** + * struct gs_tex2 - texture setting + * @cld: CLUT buffer load control + * @csa: CLUT entry offset + * @csm: CLUT storage mode + * @cpsm: CLUT pixel storage format + * @cbp: CLUT buffer base pointer + * @psm: Texture storage format + */ +struct gs_tex2 { + __BITFIELD_FIELD(__u64 cld : 3, + __BITFIELD_FIELD(__u64 csa : 5, + __BITFIELD_FIELD(__u64 csm : 1, + __BITFIELD_FIELD(__u64 cpsm : 4, + __BITFIELD_FIELD(__u64 cbp : 14, + __BITFIELD_FIELD(__u64 : 11, + __BITFIELD_FIELD(__u64 psm : 6, + __BITFIELD_FIELD(__u64 : 20, + ;)))))))) +}; + +enum gs_zmsk { gs_zbuf_on, gs_zbuf_off }; + +/** + * struct gs_zbuf - z buffer setting + * @zmsk: z value drawing mask + * @psm: z value storage format (PSMZ32, PSMZ24, PSMZ16 or PSMZ16S) + * @zbp: z buffer base pointer/2048 + */ +struct gs_zbuf { + __BITFIELD_FIELD(__u64 : 31, + __BITFIELD_FIELD(__u64 zmsk : 1, + __BITFIELD_FIELD(__u64 : 4, + __BITFIELD_FIELD(__u64 psm : 4, + __BITFIELD_FIELD(__u64 : 15, + __BITFIELD_FIELD(__u64 zbp : 9, + ;)))))) +}; + +enum gs_dthe_mode { gs_dthe_off, gs_dthe_on }; + +/** + * struct gs_dthe - dither control + * @dthe: dithering off=0 or on=1 + * + * If the pixel storage mode of the frame buffer is PSMCT32 or PSMCT24, + * dithering should be turned off. + */ +struct gs_dthe { + __BITFIELD_FIELD(__u64 : 63, + __BITFIELD_FIELD(__u64 dthe : 1, + ;)) +}; + +#endif /* _UAPI_MIPS_ASM_GS_H */ From patchwork Sun Sep 1 16:21:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125505 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0196414DE for ; Sun, 1 Sep 2019 16:22:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D484422CE9 for ; Sun, 1 Sep 2019 16:22:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728753AbfIAQWA (ORCPT ); Sun, 1 Sep 2019 12:22:00 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:59532 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728672AbfIAQWA (ORCPT ); Sun, 1 Sep 2019 12:22:00 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 103CA3F393 for ; Sun, 1 Sep 2019 18:21:57 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nUM9eo2b1Y51 for ; Sun, 1 Sep 2019 18:21:56 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 32C2F3F73E for ; Sun, 1 Sep 2019 18:21:55 +0200 (CEST) Date: Sun, 1 Sep 2019 18:21:55 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 084/120] MIPS: PS2: GIF: Define Graphics Synthesizer interface structures Message-ID: <277cabae8f0e5ff45a952fea64dbdf1213d52af0.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Graphics Synthesizer interface (GIF) formats data based on the GIF tags at the start of display list packets, and then transfer formatted data to the GS as drawing commands[1]. The GIF has three kinds of general data transfer paths: - PATH1: data from vector processor unit 1 (VPU1) memory; - PATH2: data via the VPU1 interface packet expansion engine (VIF1) FIFO; - PATH3: data directly from the main bus to the Graphics Synthesizer. The GIF tag is a 16-byte fixed length object that specifies the size and structure of subsequent data. Up to 16 register descriptors can be specified in one GIF tag, specifying to which registers of the GS the input data following the GIF tag should be output and the packing format mode: - in PACKED mode, the data of each quadword is interpreted and packed according to the register descriptor in the GIF tag, and is output to the address specified in the same way by the register descriptor; - in REGLIST mode, the data following the GIF tag is considered to be data strings of 2x64 bits and output as is without packing by setting the register descriptor value as the output destination address; - in IMAGE mode, the data following the GIF tag is considered to be data strings of 2x64 bits and output to the host-local transfer register HWREG of the GS, used when transferring image data such as textures. The privileged registers of the GS are directly mapped in the address space of the main bus, and are not accessible via the GIF regardless of the state of the general data transfer path. The GIF monitors access to the privileged registers. It is nontrivial to transfer data from GS local memory by reversing the direction with the privileged BUSDIR register. References: [1] "EE User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 147-160. Signed-off-by: Fredrik Noring --- I think a /dev/gs device for the Graphics Synthesizer could be very useful, which is why the GIF header file is put in the uapi directory, but no such device driver exists at the moment so perhaps the header file could be kernel private until then? --- arch/mips/include/uapi/asm/gif.h | 164 +++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 arch/mips/include/uapi/asm/gif.h diff --git a/arch/mips/include/uapi/asm/gif.h b/arch/mips/include/uapi/asm/gif.h new file mode 100644 index 000000000000..a952ed879de4 --- /dev/null +++ b/arch/mips/include/uapi/asm/gif.h @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer interface (GIF) + * + * Copyright (C) 2018 Fredrik Noring + */ + +/** + * DOC: Graphics Synthesizer interface (GIF) structures + * + * The Graphics Synthesizer interface (GIF) formats data based on the GIF tags + * at the start of display list packets, and then transfer formatted data to + * the GS as drawing commands. + * + * The GIF has three kinds of general data transfer paths: + * + * - PATH1: data from vector processor unit 1 (VPU1) memory; + * - PATH2: data via the VPU1 interface packet expansion engine (VIF1) FIFO; + * - PATH3: data directly from the main bus to the Graphics Synthesizer. + * + * The GIF tag is a 16-byte fixed length object that specifies the size and + * structure of subsequent data. Up to 16 register descriptors can be specified + * in one GIF tag, specifying to which registers of the GS the input data + * following the GIF tag should be output and the packing format mode. + * + * The privileged registers of the GS are directly mapped to the address space + * of the main bus, and are not accessible via the GIF regardless of the state + * of the general data transfer path. The GIF monitors access to the privileged + * registers. + */ + +#ifndef _UAPI_MIPS_ASM_GIF_H +#define _UAPI_MIPS_ASM_GIF_H + +#include + +#include "gs.h" + +#define GIF_TAG_SIZE 16 /* 128 bits */ +#define gif_quadword_count(x) (((x) + GIF_TAG_SIZE-1) >> 4) + +/* + * When transferring data via PATH1 and PATH3 in parallel, do not apply the + * A+D packing format to the data on PATH3. This may cause the GS to hang. + */ +enum gif_tag_reg { + gif_reg_prim, gif_reg_rgbaq, gif_reg_st, gif_reg_uv, + gif_reg_xyzf2, gif_reg_xyz2, gif_reg_tex0_1, gif_reg_tex0_2, + gif_reg_clamp_1, gif_reg_clamp_2, gif_reg_fog, /* Reserved */ + gif_reg_xyzf3 = 0xc, gif_reg_xyz3, gif_reg_ad, gif_reg_nop +}; + +/** + * enum gif_tag_flg - GIF tag data packing format mode + * @gif_packed_mode: in PACKED mode, each quadword is interpreted and packed + * according to the register descriptor in the GIF tag, and is output to + * the address specified in the same way by the register descriptor + * @gif_reglist_mode: in REGLIST mode, the data following the GIF tag is + * considered to be data strings of 2x64 bits and output as is without + * packing by setting the register descriptor value as the output + * destination address + * @gif_image_mode: in IMAGE mode, the data following the GIF tag is considered + * to be data strings of 2x64 bits and output to the host-local transfer + * register HWREG of the GS, used when transferring image data such as + * textures + * @gif_disabled_mode: disable (same operation as the IMAGE mode) + */ +enum gif_tag_flg { + gif_packed_mode, + gif_reglist_mode, + gif_image_mode, + gif_disabled_mode +}; + +#define GIF_TAG_NLOOP_MAX 0x7fff /* The NLOOP field is 15 bits */ + +/* + * The REGS, NREG, PRIM and PRE fields of the GIF tag are ignored in IMAGE mode. + */ +struct gif_tag { + __BITFIELD_FIELD(__u64 reg15 : 4, + __BITFIELD_FIELD(__u64 reg14 : 4, + __BITFIELD_FIELD(__u64 reg13 : 4, + __BITFIELD_FIELD(__u64 reg12 : 4, + __BITFIELD_FIELD(__u64 reg11 : 4, + __BITFIELD_FIELD(__u64 reg10 : 4, + __BITFIELD_FIELD(__u64 reg9 : 4, + __BITFIELD_FIELD(__u64 reg8 : 4, + __BITFIELD_FIELD(__u64 reg7 : 4, + __BITFIELD_FIELD(__u64 reg6 : 4, + __BITFIELD_FIELD(__u64 reg5 : 4, + __BITFIELD_FIELD(__u64 reg4 : 4, + __BITFIELD_FIELD(__u64 reg3 : 4, + __BITFIELD_FIELD(__u64 reg2 : 4, + __BITFIELD_FIELD(__u64 reg1 : 4, + __BITFIELD_FIELD(__u64 reg0 : 4, /* First register descriptor */ + __BITFIELD_FIELD(__u64 nreg : 4, /* 0 means 16 registers */ + __BITFIELD_FIELD(__u64 flg : 2, /* Data format mode */ + __BITFIELD_FIELD(__u64 prim : 11, /* PRIM register */ + __BITFIELD_FIELD(__u64 pre : 1, /* Enable PRIM field */ + __BITFIELD_FIELD(__u64 : 30, + __BITFIELD_FIELD(__u64 eop : 1, /* End of packet */ + __BITFIELD_FIELD(__u64 nloop : 15, + ;))))))))))))))))))))))) +} __attribute__((aligned(GIF_TAG_SIZE))); + +union gif_reg { + struct gs_bitbltbuf bitbltbuf; + struct gs_clamp clamp_1; + struct gs_clamp clamp_2; + struct gs_dthe dthe; + struct gs_frame_12 frame_1; + struct gs_frame_12 frame_2; + struct gs_prim prim; + struct gs_prmode prmode; + struct gs_prmodecont prmodecont; + struct gs_rgbaq rgbaq; + struct gs_scanmsk_12 scanmsk; + struct gs_scissor_12 scissor_1; + struct gs_scissor_12 scissor_2; + struct gs_test_12 test_1; + struct gs_test_12 test_2; + struct gs_texa texa; + struct gs_tex0 tex0; + struct gs_tex1 tex1; + struct gs_tex2 tex2; + struct gs_trxdir trxdir; + struct gs_trxpos trxpos; + struct gs_trxreg trxreg; + struct gs_uv uv; + struct gs_xyz23 xyz2; + struct gs_xyz23 xyz3; + struct gs_xyoffset_12 xyoffset_1; + struct gs_xyoffset_12 xyoffset_2; + struct gs_zbuf zbuf; +}; + +struct gif_packed_ad { + union gif_reg data; /* Register data */ + __BITFIELD_FIELD(__u64 : 56, + __BITFIELD_FIELD(__u64 addr : 8, /* Register address */ + ;)) +}; + +struct gif_data_reg { + union gif_reg lo; + union gif_reg hi; +}; + +union gif_data { + struct gif_tag tag; + union { + struct gif_packed_ad ad; + } packed; + struct gif_data_reg reg; + struct gs_rgba32 rgba32[4]; + __u8 image[16]; /* All pixel formats pack data without padding */ + __u64 doubleword[2]; + __u32 word[4]; + __u16 halfword[8]; + __u8 byte[16]; +} __attribute__((aligned(GIF_TAG_SIZE))); + +#endif /* _UAPI_MIPS_ASM_GIF_H */ From patchwork Sun Sep 1 16:22:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125507 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5283317E0 for ; Sun, 1 Sep 2019 16:22:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3B4E6233A2 for ; Sun, 1 Sep 2019 16:22:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728763AbfIAQWX (ORCPT ); Sun, 1 Sep 2019 12:22:23 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:59582 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728672AbfIAQWW (ORCPT ); Sun, 1 Sep 2019 12:22:22 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 6C0DC3F752 for ; Sun, 1 Sep 2019 18:22:20 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ga6TsNp0kzp7 for ; Sun, 1 Sep 2019 18:22:16 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id EE5853F393 for ; Sun, 1 Sep 2019 18:22:15 +0200 (CEST) Date: Sun, 1 Sep 2019 18:22:15 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 085/120] MIPS: PS2: GIF: Graphics Synthesizer interface support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gif.h | 77 +++++++++++++++++++ drivers/ps2/Makefile | 1 + drivers/ps2/gif.c | 106 +++++++++++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/gif.h create mode 100644 drivers/ps2/gif.c diff --git a/arch/mips/include/asm/mach-ps2/gif.h b/arch/mips/include/asm/mach-ps2/gif.h new file mode 100644 index 000000000000..2a3965bd5544 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/gif.h @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer interface (GIF) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_GIF_H +#define __ASM_MACH_PS2_GIF_H + +#include + +#include + +#define GIF_CTRL 0x10003000 /* (W) GIF control */ +#define GIF_MODE 0x10003010 /* (W) GIF mode */ +#define GIF_STAT 0x10003020 /* (R) GIF status */ + +/* + * These GIF registers are accessible only when stopped by the + * &gif_ctrl.pse flag. + */ + +#define GIF_TAG0 0x10003040 /* (R) GIF tag 31:0 */ +#define GIF_TAG1 0x10003050 /* (R) GIF tag 63:32 */ +#define GIF_TAG2 0x10003060 /* (R) GIF tag 95:54 */ +#define GIF_TAG3 0x10003070 /* (R) GIF tag 127:96 */ +#define GIF_CNT 0x10003080 /* (R) GIF transfer status counter */ +#define GIF_P3CNT 0x10003090 /* (R) PATH3 transfer status counter */ +#define GIF_P3TAG 0x100030a0 /* (R) PATH3 GIF tag value */ + +/** + * struct gif_ctrl - GIF control register + * @rst: GIF reset + * @pse: temporary transfer stop + * + * Writing 1 to PSE temporarily stops GIF transfers and makes it possible + * to read GIF registers for debugging. Writing 0 to PSE resumes transfers. + */ +struct gif_ctrl { + u32 rst : 1; + u32 : 2; + u32 pse : 1; + u32 : 28; +}; + +/** + * gif_writel_ctrl - write word to the GIF_CTRL register + * @value - 32-bit word to write + */ +void gif_writel_ctrl(u32 value); + +/** + * gif_write_ctrl - write structure to the GIF_CTRL register + * @value - structure to write + */ +void gif_write_ctrl(struct gif_ctrl value); + +/** + * gif_reset- reset the GIF + * + * The reset includes a delay of 100 us. + */ +void gif_reset(void); + +/** + * gif_wait - is the GIF ready to transfer data? + * + * FIXME: Move to ps2fb.c + * + * Return: %true if ready to transfer data, otherwise %false + */ +bool gif_wait(void); + +void gif_write(union gif_data *base_package, size_t package_count); + +#endif /* __ASM_MACH_PS2_GIF_H */ diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index 7f108d4ee451..9671bbe40294 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_PS2_GS) += gif.o obj-$(CONFIG_PS2_GS) += gs-irq.o obj-$(CONFIG_PS2_GS) += gs-registers.o diff --git a/drivers/ps2/gif.c b/drivers/ps2/gif.c new file mode 100644 index 000000000000..b7707047e470 --- /dev/null +++ b/drivers/ps2/gif.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer interface (GIF) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +void gif_writel_ctrl(u32 value) +{ + outl(value, GIF_CTRL); +} +EXPORT_SYMBOL_GPL(gif_writel_ctrl); + +void gif_write_ctrl(struct gif_ctrl value) +{ + u32 v; + memcpy(&v, &value, sizeof(v)); + gif_writel_ctrl(v); +} +EXPORT_SYMBOL_GPL(gif_write_ctrl); + +void gif_reset(void) +{ + gif_write_ctrl((struct gif_ctrl) { .rst = 1 }); + + udelay(100); /* 100 us */ +} +EXPORT_SYMBOL_GPL(gif_reset); + +bool gif_busy(void) +{ + return (inl(DMAC_GIF_CHCR) & DMAC_CHCR_BUSY) != 0; +} +EXPORT_SYMBOL_GPL(gif_busy); + +bool gif_wait(void) +{ + size_t countout = 1000000; + + while (gif_busy() && countout > 0) + countout--; + + return countout > 0; +} +EXPORT_SYMBOL_GPL(gif_wait); + +void gif_write(union gif_data *base_package, size_t package_count) +{ + const size_t size = package_count * sizeof(*base_package); + const dma_addr_t madr = virt_to_phys(base_package); + + if (!package_count) + return; + + dma_cache_wback((unsigned long)base_package, size); + + /* Wait for previous transmissions to finish. */ + while (gif_busy()) + ; + + outl(madr, DMAC_GIF_MADR); + outl(package_count, DMAC_GIF_QWC); + outl(DMAC_CHCR_SENDN, DMAC_GIF_CHCR); +} +EXPORT_SYMBOL_GPL(gif_write); + +static int __init gif_init(void) +{ + return 0; +} + +static void __exit gif_exit(void) +{ +} + +module_init(gif_init); +module_exit(gif_exit); + +MODULE_DESCRIPTION("PlayStation 2 Graphics Synthesizer interface (GIF)"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:22:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125509 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E5C213B1 for ; Sun, 1 Sep 2019 16:22:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5B56320828 for ; Sun, 1 Sep 2019 16:22:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728764AbfIAQWq (ORCPT ); Sun, 1 Sep 2019 12:22:46 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:60656 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728672AbfIAQWq (ORCPT ); Sun, 1 Sep 2019 12:22:46 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 50C253FC34 for ; Sun, 1 Sep 2019 18:22:44 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FEEnMLHN4IoS for ; Sun, 1 Sep 2019 18:22:43 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 678283F62D for ; Sun, 1 Sep 2019 18:22:43 +0200 (CEST) Date: Sun, 1 Sep 2019 18:22:43 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 086/120] MIPS: PS2: GS: Graphics Synthesizer device init and video clock Message-ID: <9d51214ecd1ad41577f01f323cf14f7b917ffc5f.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Several combinations of video clock register values appear to generate equivalent frequencies. For the standard ones, the combinations used by Sony are preferred and tabulated. For all others, a search is performed. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs.h | 47 +++++++ arch/mips/ps2/Kconfig | 16 +++ drivers/ps2/Makefile | 1 + drivers/ps2/gs.c | 195 ++++++++++++++++++++++++++++ 4 files changed, 259 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/gs.h create mode 100644 arch/mips/ps2/Kconfig create mode 100644 drivers/ps2/gs.c diff --git a/arch/mips/include/asm/mach-ps2/gs.h b/arch/mips/include/asm/mach-ps2/gs.h new file mode 100644 index 000000000000..9cb1b909ae9b --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/gs.h @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer (GS) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#ifndef __ASM_MACH_PS2_GS_H +#define __ASM_MACH_PS2_GS_H + +#include + +#include + +#define GS_REG_BASE 0x12000000 + +/** + * struct gs_synch_gen - Graphics Synthesizer SMODE1 register video clock fields + * @rc: PLL reference divider + * @lc: PLL loop divider + * @t1248: PLL output divider + * @spml: FIXME + * + * These fields determine the Graphics Synthesizer video clock + * + * VCK = (13500000 * @lc) / ((@t1248 + 1) * @spml * @rc). + * + * See also &struct gs_smode1. + */ +struct gs_synch_gen { + u32 rc : 3; + u32 lc : 7; + u32 t1248 : 2; + u32 spml : 4; +}; + +u32 gs_video_clock(const u32 t1248, const u32 lc, const u32 rc); + +u32 gs_video_clock_for_smode1(const struct gs_smode1 smode1); + +struct gs_synch_gen gs_synch_gen_for_vck(const u32 vck); + +u32 gs_rfsh_from_synch_gen(const struct gs_synch_gen sg); + +struct device *gs_device_driver(void); /* FIXME: Is this method appropriate? */ + +#endif /* __ASM_MACH_PS2_GS_H */ diff --git a/arch/mips/ps2/Kconfig b/arch/mips/ps2/Kconfig new file mode 100644 index 000000000000..f782d61cfaac --- /dev/null +++ b/arch/mips/ps2/Kconfig @@ -0,0 +1,16 @@ +config PS2_GS + tristate "PlayStation 2 Graphics Synthesizer" + depends on SONY_PS2 + default y + help + Say yes to enable the PlayStation 2 Graphics Synthesizer. The GS + draws primitives such as triangles and sprites to its 4 MiB local + frame buffer. It can handle shading, texture mapping, + z-buffering, alpha blending, edge antialiasing and fogging. + + PAL, NTSC and VESA video modes are supported. Interlace and + noninterlaced can be switched. The resolution is variable from + 256x224 to 1920x1080. + + This driver can also be built as a module. If so, the module + will be called gs. diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index 9671bbe40294..28fb55803199 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_PS2_GS) += gif.o +obj-$(CONFIG_PS2_GS) += gs.o obj-$(CONFIG_PS2_GS) += gs-irq.o obj-$(CONFIG_PS2_GS) += gs-registers.o diff --git a/drivers/ps2/gs.c b/drivers/ps2/gs.c new file mode 100644 index 000000000000..00bb36304ee6 --- /dev/null +++ b/drivers/ps2/gs.c @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer (GS) + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +static struct device *gs_dev; + +/** + * gs_video_clock - video clock (VCK) frequency given SMODE1 bit fields + * @t1248 - &gs_smode1.t1248 PLL output divider + * @lc - &gs_smode1.lc PLL loop divider + * @rc - &gs_smode1.rc PLL reference divider + * + * Return: video clock (VCK) + */ +u32 gs_video_clock(const u32 t1248, const u32 lc, const u32 rc) +{ + return (13500000 * lc) / ((t1248 + 1) * rc); +} +EXPORT_SYMBOL_GPL(gs_video_clock); + +/** + * gs_video_clock_for_smode1 - video clock (VCK) frequency given SMODE1 + * register value + * @smode1: SMODE1 register value + * + * Return: video clock (VCK) + */ +u32 gs_video_clock_for_smode1(const struct gs_smode1 smode1) +{ + return gs_video_clock(smode1.t1248, smode1.lc, smode1.rc); +} +EXPORT_SYMBOL_GPL(gs_video_clock_for_smode1); + +static u32 div_round_ps(u32 a, u32 b) +{ + return DIV_ROUND_CLOSEST_ULL(a * 1000000000000ll, b); +} + +static u32 vck_to_pix_clock(const u32 vck, const u32 spml) +{ + return div_round_ps(spml, vck); +} + +/** + * gs_synch_gen_for_vck - determine video synchronization register fields for + * a given video clock + * @vck: video clock to compute video synchronization register fields for + * + * Some combinations of registers appear to generate equivalent video clock + * frequencies. For the standard ones, the combinations used by Sony are + * preferred and tabulated. For all others, a search is performed. + * + * Return: video synchronization register fields RC, LC, T1248 and SPML + **/ +struct gs_synch_gen gs_synch_gen_for_vck(const u32 vck) +{ + static const struct gs_synch_gen preferred[] = { + { .spml = 2, .t1248 = 1, .lc = 15, .rc = 2 }, /* 50.625 MHz */ + { .spml = 2, .t1248 = 1, .lc = 32, .rc = 4 }, /* 54.000 MHz */ + { .spml = 4, .t1248 = 1, .lc = 32, .rc = 4 }, /* 54.000 MHz */ + { .spml = 2, .t1248 = 1, .lc = 28, .rc = 3 }, /* 63.000 MHz */ + { .spml = 1, .t1248 = 1, .lc = 22, .rc = 2 }, /* 74.250 MHz */ + { .spml = 1, .t1248 = 1, .lc = 35, .rc = 3 }, /* 78.750 MHz */ + { .spml = 2, .t1248 = 1, .lc = 71, .rc = 6 }, /* 79.875 MHz */ + { .spml = 2, .t1248 = 1, .lc = 44, .rc = 3 }, /* 99.000 MHz */ + { .spml = 1, .t1248 = 0, .lc = 8, .rc = 1 }, /* 108.000 MHz */ + { .spml = 2, .t1248 = 0, .lc = 58, .rc = 6 }, /* 130.500 MHz */ + { .spml = 1, .t1248 = 0, .lc = 10, .rc = 1 }, /* 135.000 MHz */ + { .spml = 1, .t1248 = 1, .lc = 22, .rc = 1 } /* 148.500 MHz */ + }; + + struct gs_synch_gen sg = { }; + u32 spml, t1248, lc, rc; + int best = -1; + int diff, i; + + for (i = 0; i < ARRAY_SIZE(preferred); i++) { + spml = preferred[i].spml; + t1248 = preferred[i].t1248; + lc = preferred[i].lc; + rc = preferred[i].rc; + + diff = abs(vck - vck_to_pix_clock( + gs_video_clock(t1248, lc, rc), spml)); + + if (best == -1 || diff < best) { + best = diff; + sg = (struct gs_synch_gen) { + .rc = rc, + .lc = lc, + .t1248 = t1248, + .spml = spml + }; + } + } + + for (spml = 1; spml < 5; spml++) + for (t1248 = 0; t1248 < 2; t1248++) + for (lc = 1; lc < 128; lc++) + for (rc = 1; rc < 7; rc++) { + diff = abs(vck - vck_to_pix_clock( + gs_video_clock(t1248, lc, rc), spml)); + + if (best == -1 || diff < best) { + best = diff; + sg = (struct gs_synch_gen) { + .rc = rc, + .lc = lc, + .t1248 = t1248, + .spml = spml + }; + } + } + + return sg; +} +EXPORT_SYMBOL_GPL(gs_synch_gen_for_vck); + +/** + * gs_rfsh_from_synch_gen - DRAM refresh for the given synchronization registers + * + * Return: DRAM refresh register value + */ +u32 gs_rfsh_from_synch_gen(const struct gs_synch_gen sg) +{ + const u32 pck = gs_video_clock(sg.t1248, sg.lc, sg.rc) / sg.spml; + + return pck < 20000000 ? 8 : + pck < 70000000 ? 4 : 2; +} +EXPORT_SYMBOL_GPL(gs_rfsh_from_synch_gen); + +struct device *gs_device_driver(void) +{ + return gs_dev; +} +EXPORT_SYMBOL_GPL(gs_device_driver); + +static int gs_probe(struct platform_device *pdev) +{ + gs_dev = &pdev->dev; + + gs_irq_init(); + + gif_reset(); + + return 0; +} + +static int gs_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_driver gs_driver = { + .probe = gs_probe, + .remove = gs_remove, + .driver = { + .name = "gs", + }, +}; + +static int __init gs_init(void) +{ + return platform_driver_register(&gs_driver); +} + +static void __exit gs_exit(void) +{ + platform_driver_unregister(&gs_driver); +} + +module_init(gs_init); +module_exit(gs_exit); + +MODULE_DESCRIPTION("PlayStation 2 Graphics Synthesizer device driver"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:23:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125511 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1F9C113B1 for ; Sun, 1 Sep 2019 16:23:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F2DCA20818 for ; Sun, 1 Sep 2019 16:23:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728775AbfIAQXE (ORCPT ); Sun, 1 Sep 2019 12:23:04 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:59672 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728672AbfIAQXE (ORCPT ); Sun, 1 Sep 2019 12:23:04 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 66EC83F752 for ; Sun, 1 Sep 2019 18:23:02 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id odAujYT3b6KQ for ; Sun, 1 Sep 2019 18:23:01 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id A88653F393 for ; Sun, 1 Sep 2019 18:23:01 +0200 (CEST) Date: Sun, 1 Sep 2019 18:23:01 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 087/120] MIPS: PS2: GS: Compute block count and indices Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The GS frame buffer is subdivided into rectangular pages, from left to right, top to bottom. Pages are further subdivided into blocks, with different arrangements for the PSMCT16 and PSMCT32 pixel storage modes. Blocks are further subdivided into columns that are finally subdivided into pixels[1]. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 161-175. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs.h | 8 +++ drivers/ps2/gs.c | 94 +++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/gs.h b/arch/mips/include/asm/mach-ps2/gs.h index 9cb1b909ae9b..5429f52a4518 100644 --- a/arch/mips/include/asm/mach-ps2/gs.h +++ b/arch/mips/include/asm/mach-ps2/gs.h @@ -38,6 +38,14 @@ u32 gs_video_clock(const u32 t1248, const u32 lc, const u32 rc); u32 gs_video_clock_for_smode1(const struct gs_smode1 smode1); +u32 gs_psm_ct16_block_count(const u32 fbw, const u32 fbh); + +u32 gs_psm_ct32_block_count(const u32 fbw, const u32 fbh); + +u32 gs_psm_ct32_block_address(const u32 fbw, const u32 block_index); + +u32 gs_psm_ct16_block_address(const u32 fbw, const u32 block_index); + struct gs_synch_gen gs_synch_gen_for_vck(const u32 vck); u32 gs_rfsh_from_synch_gen(const struct gs_synch_gen sg); diff --git a/drivers/ps2/gs.c b/drivers/ps2/gs.c index 00bb36304ee6..a3cd1a6adfb7 100644 --- a/drivers/ps2/gs.c +++ b/drivers/ps2/gs.c @@ -48,6 +48,100 @@ u32 gs_video_clock_for_smode1(const struct gs_smode1 smode1) } EXPORT_SYMBOL_GPL(gs_video_clock_for_smode1); +/** + * gs_psm_ct16_block_count - number of blocks for 16-bit pixel storage + * @fbw: buffer width/64 + * @fbh: buffer height + * + * Return: number of blocks for 16-bit pixel storage of given width and height + */ +u32 gs_psm_ct16_block_count(const u32 fbw, const u32 fbh) +{ + const u32 block_cols = fbw * GS_PSM_CT16_PAGE_COLS; + const u32 block_rows = (fbh + GS_PSM_CT16_BLOCK_HEIGHT - 1) / + GS_PSM_CT16_BLOCK_HEIGHT; + + return block_cols * block_rows; +} +EXPORT_SYMBOL_GPL(gs_psm_ct16_block_count); + +/** + * gs_psm_ct32_block_count - number of blocks for 32-bit pixel storage + * @fbw: buffer width/64 + * @fbh: buffer height + * + * Return: number of blocks for 32-bit pixel storage of given width and height + */ +u32 gs_psm_ct32_block_count(const u32 fbw, const u32 fbh) +{ + const u32 block_cols = fbw * GS_PSM_CT32_PAGE_COLS; + const u32 block_rows = (fbh + GS_PSM_CT32_BLOCK_HEIGHT - 1) / + GS_PSM_CT32_BLOCK_HEIGHT; + + return block_cols * block_rows; +} +EXPORT_SYMBOL_GPL(gs_psm_ct32_block_count); + +/** + * gs_psm_ct16_block_address - 16-bit block address given a block index + * @fbw: buffer width/64 + * @block_index: block index starting at the top left corner + * + * Return: block address for a given block index + */ +u32 gs_psm_ct16_block_address(const u32 fbw, const u32 block_index) +{ + static const u32 block[GS_PSM_CT16_PAGE_ROWS][GS_PSM_CT16_PAGE_COLS] = { + { 0, 2, 8, 10 }, + { 1, 3, 9, 11 }, + { 4, 6, 12, 14 }, + { 5, 7, 13, 15 }, + { 16, 18, 24, 26 }, + { 17, 19, 25, 27 }, + { 20, 22, 28, 30 }, + { 21, 23, 29, 31 } + }; + + const u32 fw = GS_PSM_CT16_PAGE_COLS * fbw; + const u32 fc = block_index % fw; + const u32 fr = block_index / fw; + const u32 bc = fc % GS_PSM_CT16_PAGE_COLS; + const u32 br = fr % GS_PSM_CT16_PAGE_ROWS; + const u32 pc = fc / GS_PSM_CT16_PAGE_COLS; + const u32 pr = fr / GS_PSM_CT16_PAGE_ROWS; + + return GS_BLOCKS_PER_PAGE * (fbw * pr + pc) + block[br][bc]; +} +EXPORT_SYMBOL_GPL(gs_psm_ct16_block_address); + +/** + * gs_psm_ct32_block_address - 32-bit block address given a block index + * @fbw: buffer width/64 + * @block_index: block index starting at the top left corner + * + * Return: block address for a given block index + */ +u32 gs_psm_ct32_block_address(const u32 fbw, const u32 block_index) +{ + static const u32 block[GS_PSM_CT32_PAGE_ROWS][GS_PSM_CT32_PAGE_COLS] = { + { 0, 1, 4, 5, 16, 17, 20, 21 }, + { 2, 3, 6, 7, 18, 19, 22, 23 }, + { 8, 9, 12, 13, 24, 25, 28, 29 }, + { 10, 11, 14, 15, 26, 27, 30, 31 } + }; + + const u32 fw = GS_PSM_CT32_PAGE_COLS * fbw; + const u32 fc = block_index % fw; + const u32 fr = block_index / fw; + const u32 bc = fc % GS_PSM_CT32_PAGE_COLS; + const u32 br = fr % GS_PSM_CT32_PAGE_ROWS; + const u32 pc = fc / GS_PSM_CT32_PAGE_COLS; + const u32 pr = fr / GS_PSM_CT32_PAGE_ROWS; + + return GS_BLOCKS_PER_PAGE * (fbw * pr + pc) + block[br][bc]; +} +EXPORT_SYMBOL_GPL(gs_psm_ct32_block_address); + static u32 div_round_ps(u32 a, u32 b) { return DIV_ROUND_CLOSEST_ULL(a * 1000000000000ll, b); From patchwork Sun Sep 1 16:23:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125513 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8833613B1 for ; Sun, 1 Sep 2019 16:23:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 65B2F20828 for ; Sun, 1 Sep 2019 16:23:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728848AbfIAQXW (ORCPT ); Sun, 1 Sep 2019 12:23:22 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:60682 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728672AbfIAQXW (ORCPT ); Sun, 1 Sep 2019 12:23:22 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 549B13FC34 for ; Sun, 1 Sep 2019 18:23:20 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8Qct7PyYzeiR for ; Sun, 1 Sep 2019 18:23:19 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 9DFF83F62D for ; Sun, 1 Sep 2019 18:23:19 +0200 (CEST) Date: Sun, 1 Sep 2019 18:23:19 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 088/120] MIPS: PS2: GS: Primitive and texel coordinate transformations Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The frame buffer coordinate system is the pixel drawing space, with integer coordinates. The primitive coordinate system is the drawing space used for vertices, with 4-bit fractional parts. The texel coordinate system is used for textures, with 4-bit fractional parts, centered on the position where the fractional parts are 0.5[1]. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 23-24, 28. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/gs.h b/arch/mips/include/asm/mach-ps2/gs.h index 5429f52a4518..935d03007680 100644 --- a/arch/mips/include/asm/mach-ps2/gs.h +++ b/arch/mips/include/asm/mach-ps2/gs.h @@ -46,6 +46,28 @@ u32 gs_psm_ct32_block_address(const u32 fbw, const u32 block_index); u32 gs_psm_ct16_block_address(const u32 fbw, const u32 block_index); +/** + * gs_fbcs_to_pcs - frame buffer coordinate to primitive coordinate + * @c: frame buffer coordinate + * + * Return: primitive coordinate + */ +static inline int gs_fbcs_to_pcs(const int c) +{ + return c * 16; /* The 4 least significant bits are fractional. */ +} + +/** + * gs_pxcs_to_tcs - pixel coordinate to texel coordinate + * @c: pixel coordinate + * + * Return: texel coordinate + */ +static inline int gs_pxcs_to_tcs(const int c) +{ + return c * 16 + 8; /* The 4 least significant bits are fractional. */ +} + struct gs_synch_gen gs_synch_gen_for_vck(const u32 vck); u32 gs_rfsh_from_synch_gen(const struct gs_synch_gen sg); From patchwork Sun Sep 1 16:23:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125515 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B5EFD14DE for ; Sun, 1 Sep 2019 16:23:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9DE2D20828 for ; Sun, 1 Sep 2019 16:23:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728863AbfIAQX5 (ORCPT ); Sun, 1 Sep 2019 12:23:57 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:60738 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728672AbfIAQX5 (ORCPT ); Sun, 1 Sep 2019 12:23:57 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 8D47A3FC34 for ; Sun, 1 Sep 2019 18:23:55 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Wih7qAspd2mw for ; Sun, 1 Sep 2019 18:23:54 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id D44643F62D for ; Sun, 1 Sep 2019 18:23:54 +0200 (CEST) Date: Sun, 1 Sep 2019 18:23:53 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 089/120] MIPS: PS2: GS: Approximate video region with ROM region Message-ID: <84a15a9832f0066d0de410c2613087a30ff99d73.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org PlayStation 2 hardware indicates regions in multiple ways. There are regions for the ROM, discs, CSS, video mode and Magic Gate. Currently only the ROM region is implemented. Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/gs.h | 4 ++++ drivers/ps2/gs.c | 30 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/arch/mips/include/asm/mach-ps2/gs.h b/arch/mips/include/asm/mach-ps2/gs.h index 935d03007680..e719ca0531ba 100644 --- a/arch/mips/include/asm/mach-ps2/gs.h +++ b/arch/mips/include/asm/mach-ps2/gs.h @@ -34,6 +34,10 @@ struct gs_synch_gen { u32 spml : 4; }; +bool gs_region_pal(void); + +bool gs_region_ntsc(void); + u32 gs_video_clock(const u32 t1248, const u32 lc, const u32 rc); u32 gs_video_clock_for_smode1(const struct gs_smode1 smode1); diff --git a/drivers/ps2/gs.c b/drivers/ps2/gs.c index a3cd1a6adfb7..c380dfa358b5 100644 --- a/drivers/ps2/gs.c +++ b/drivers/ps2/gs.c @@ -21,6 +21,36 @@ static struct device *gs_dev; +/** + * gs_region_pal - is the machine for a PAL video mode region? + * + * See also gs_region_ntsc(). The system region is determined by rom_version(), + * which is an approximation because the ROM region does not always correspdond + * to the video region. + * + * Return: %true if PAL video mode is appropriate for the region, else %false + */ +bool gs_region_pal(void) +{ + return rom_version().region == 'E'; +} +EXPORT_SYMBOL_GPL(gs_region_pal); + +/** + * gs_region_ntsc - is the machine for an NTSC video mode region? + * + * See also gs_region_pal(). The system region is determined by rom_version(), + * which is an approximation because the ROM region does not always correspdond + * to the video region. + * + * Return: %true if NTSC video mode is appropriate for the region, else %false + */ +bool gs_region_ntsc(void) +{ + return !gs_region_pal(); +} +EXPORT_SYMBOL_GPL(gs_region_ntsc); + /** * gs_video_clock - video clock (VCK) frequency given SMODE1 bit fields * @t1248 - &gs_smode1.t1248 PLL output divider From patchwork Sun Sep 1 16:24:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125517 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A18C013B1 for ; Sun, 1 Sep 2019 16:24:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 883D8233A2 for ; Sun, 1 Sep 2019 16:24:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728672AbfIAQYY (ORCPT ); Sun, 1 Sep 2019 12:24:24 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:60748 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728900AbfIAQYY (ORCPT ); Sun, 1 Sep 2019 12:24:24 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 551483FC34 for ; Sun, 1 Sep 2019 18:24:22 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9BpobDNYmO1z for ; Sun, 1 Sep 2019 18:24:21 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 9A9753F62D for ; Sun, 1 Sep 2019 18:24:21 +0200 (CEST) Date: Sun, 1 Sep 2019 18:24:21 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 090/120] macro: Extend COUNT_ARGS() from 12 to 32 arguments Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org This is useful to define sysfs bit-fields, such as this one in a forthcoming change: SYSFS_RW_REG(smode1, smode1, SYSFS_DECNUM_FIELD(rc), SYSFS_DECNUM_FIELD(lc), SYSFS_DECNUM_FIELD(t1248), SYSFS_DECNUM_FIELD(slck), SYSFS_SYMBOL_FIELD(cmod, vesa, ntsc, pal), SYSFS_DECNUM_FIELD(ex), SYSFS_DECNUM_FIELD(prst), SYSFS_DECNUM_FIELD(sint), SYSFS_DECNUM_FIELD(xpck), SYSFS_DECNUM_FIELD(pck2), SYSFS_DECNUM_FIELD(spml), SYSFS_SYMBOL_FIELD(gcont, rgbyc, ycrcb), SYSFS_DECNUM_FIELD(phs), SYSFS_DECNUM_FIELD(pvs), SYSFS_DECNUM_FIELD(pehs), SYSFS_DECNUM_FIELD(pevs), SYSFS_DECNUM_FIELD(clksel), SYSFS_DECNUM_FIELD(nvck), SYSFS_DECNUM_FIELD(slck2), SYSFS_DECNUM_FIELD(vcksel), SYSFS_DECNUM_FIELD(vhp)); Signed-off-by: Fredrik Noring --- include/linux/kernel.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 4fa360a13c1e..a9d57f6ed1d3 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -954,9 +954,15 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } #define swap(a, b) \ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) -/* This counts to 12. Any more, it will return 13th argument. */ -#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n -#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +/* This counts to 32. Any more, it will return the 33rd argument. */ +#define __COUNT_ARGS( \ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, \ + _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _n, X...) _n +#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, \ + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, \ + 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) #define __CONCAT(a, b) a ## b #define CONCATENATE(a, b) __CONCAT(a, b) From patchwork Sun Sep 1 16:25:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125519 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1CC6613B1 for ; Sun, 1 Sep 2019 16:25:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E4E50233A2 for ; Sun, 1 Sep 2019 16:25:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728878AbfIAQZ0 (ORCPT ); Sun, 1 Sep 2019 12:25:26 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:60848 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728877AbfIAQZ0 (ORCPT ); Sun, 1 Sep 2019 12:25:26 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 940743FC34; Sun, 1 Sep 2019 18:25:17 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AlyCZdn1sUj4; Sun, 1 Sep 2019 18:25:16 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 71A9F3F62D; Sun, 1 Sep 2019 18:25:16 +0200 (CEST) Date: Sun, 1 Sep 2019 18:25:16 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 091/120] MIPS: PS2: GS: Show privileged registers with sysfs Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Reading arbitrary numerical and symbolical privileged GS register bit fields is supported. For example, the PMODE register can be inspected with: # cat /sys/devices/platform/gs/registers/pmode en1 1 en2 0 crtmd 1 mmod circuit1 amod circuit1 slbg circuit2 alp 0 The implementation uses a fair amount of macro expansions. This greatly simplifies register definitions, which in the case of PMODE is: SYSFS_RW_REG(pmode, pmode, SYSFS_DECNUM_FIELD(en1), SYSFS_DECNUM_FIELD(en2), SYSFS_DECNUM_FIELD(crtmd), SYSFS_SYMBOL_FIELD(mmod, circuit1, alp), SYSFS_SYMBOL_FIELD(amod, circuit1, circuit2), SYSFS_SYMBOL_FIELD(slbg, circuit2, bgcolor), SYSFS_DECNUM_FIELD(alp)); It relies on the following enum and struct definitions: enum gs_pmode_mmod { gs_mmod_circuit1, gs_mmod_alp }; enum gs_pmode_amod { gs_amod_circuit1, gs_amod_circuit2 }; enum gs_pmode_slbg { gs_slbg_circuit2, gs_slbg_bgcolor }; struct gs_pmode { u64 en1 : 1; /* Enable read circuit 1 */ u64 en2 : 1; /* Enable read circuit 2 */ u64 crtmd : 3; /* CRT output switching (always 001) */ u64 mmod : 1; /* Alpha blending value */ u64 amod : 1; /* OUT1 alpha output */ u64 slbg : 1; /* Alpha blending method */ u64 alp : 8; /* Fixed alpha (0xff = 1.0) */ u64 zero : 1; /* Must be zero */ u64 : 47; }; Signed-off-by: Fredrik Noring --- drivers/ps2/Makefile | 1 + drivers/ps2/gs-sysfs.c | 457 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 458 insertions(+) create mode 100644 drivers/ps2/gs-sysfs.c diff --git a/drivers/ps2/Makefile b/drivers/ps2/Makefile index 28fb55803199..86ba1d3908dd 100644 --- a/drivers/ps2/Makefile +++ b/drivers/ps2/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PS2_GS) += gif.o obj-$(CONFIG_PS2_GS) += gs.o obj-$(CONFIG_PS2_GS) += gs-irq.o obj-$(CONFIG_PS2_GS) += gs-registers.o +obj-$(CONFIG_PS2_GS) += gs-sysfs.o obj-m += iop-heap.o obj-m += iop-irq.o diff --git a/drivers/ps2/gs-sysfs.c b/drivers/ps2/gs-sysfs.c new file mode 100644 index 000000000000..2429de3e0094 --- /dev/null +++ b/drivers/ps2/gs-sysfs.c @@ -0,0 +1,457 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 Graphics Synthesizer (GS) sysfs driver + * + * Copyright (C) 2019 Fredrik Noring + * + * Reading arbitrary numerical and symbolical privileged GS register + * bit fields is supported. For example, the PMODE register can be + * inspected with: + * + * # cat /sys/devices/platform/gs/registers/pmode + * en1 1 + * en2 0 + * crtmd 1 + * mmod circuit1 + * amod circuit1 + * slbg circuit2 + * alp 0 + * + * The implementation uses a fair amount of macro expansions. This greatly + * simplifies register definitions, which in the case of PMODE is: + * + * SYSFS_RW_REG(pmode, pmode, + * SYSFS_DECNUM_FIELD(en1), + * SYSFS_DECNUM_FIELD(en2), + * SYSFS_DECNUM_FIELD(crtmd), + * SYSFS_SYMBOL_FIELD(mmod, circuit1, alp), + * SYSFS_SYMBOL_FIELD(amod, circuit1, circuit2), + * SYSFS_SYMBOL_FIELD(slbg, circuit2, bgcolor), + * SYSFS_DECNUM_FIELD(alp)); + * + * It relies on the following enum and struct definitions: + * + * enum gs_pmode_mmod { gs_mmod_circuit1, gs_mmod_alp }; + * enum gs_pmode_amod { gs_amod_circuit1, gs_amod_circuit2 }; + * enum gs_pmode_slbg { gs_slbg_circuit2, gs_slbg_bgcolor }; + * struct gs_pmode { + * u64 en1 : 1; // Enable read circuit 1 + * u64 en2 : 1; // Enable read circuit 2 + * u64 crtmd : 3; // CRT output switching (always 001) + * u64 mmod : 1; // Alpha blending value + * u64 amod : 1; // OUT1 alpha output + * u64 slbg : 1; // Alpha blending method + * u64 alp : 8; // Fixed alpha (0xff = 1.0) + * u64 zero : 1; // Must be zero + * u64 : 47; + * }; + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +static struct kobject *registers_kobj; + +#define SYSFS_STATEMENT1(prefix_, macro_) \ + prefix_##macro_; + +#define SYSFS_STATEMENT2(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT1(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT3(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT2(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT4(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT3(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT5(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT4(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT6(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT5(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT7(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT6(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT8(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT7(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT9(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT8(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT10(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT9(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT11(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT10(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT12(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT11(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT13(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT12(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT14(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT13(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT15(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT14(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT16(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT15(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT17(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT16(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT18(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT17(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT19(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT18(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT20(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT19(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT21(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT20(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT22(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT21(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT23(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT22(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT24(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT23(prefix_, __VA_ARGS__) + +#define SYSFS_STATEMENT25(prefix_, macro_, ...) \ + prefix_##macro_; \ + SYSFS_STATEMENT24(prefix_, __VA_ARGS__) + +#define SHOW_SYSFS_DECNUM_FIELD(field_, ...) \ + do { \ + if (valid) \ + n += scnprintf(&buf[n], PAGE_SIZE - n, \ + #field_ " %u\n", value.field_); \ + else \ + n += scnprintf(&buf[n], PAGE_SIZE - n, \ + #field_ "\n"); \ + } while (false) + +#define SHOW_SYSFS_HEXNUM_FIELD(field_, ...) \ + do { \ + if (valid) \ + n += scnprintf(&buf[n], PAGE_SIZE - n, \ + #field_ " 0x%x\n", value.field_); \ + else \ + n += scnprintf(&buf[n], PAGE_SIZE - n, \ + #field_ "\n"); \ + } while (false) + +#define SHOW_SYSFS_SYMBOL_STRING_ENTRY(field_, prefix_, value_) \ + value.field_ == prefix_##_##value_ ? " " #value_ : + +#define SHOW_SYSFS_SYMBOL_STRING1(field_, prefix_, value_) \ + SHOW_SYSFS_SYMBOL_STRING_ENTRY(field_, prefix_, value_) "-" + +#define SHOW_SYSFS_SYMBOL_STRING2(field_, prefix_, value_, ...) \ + SHOW_SYSFS_SYMBOL_STRING_ENTRY(field_, prefix_, value_) \ + SHOW_SYSFS_SYMBOL_STRING1(field_, prefix_, __VA_ARGS__) + +#define SHOW_SYSFS_SYMBOL_STRING3(field_, prefix_, value_, ...) \ + SHOW_SYSFS_SYMBOL_STRING_ENTRY(field_, prefix_, value_) \ + SHOW_SYSFS_SYMBOL_STRING2(field_, prefix_, __VA_ARGS__) + +#define SHOW_SYSFS_SYMBOL_STRING4(field_, prefix_, value_, ...) \ + SHOW_SYSFS_SYMBOL_STRING_ENTRY(field_, prefix_, value_) \ + SHOW_SYSFS_SYMBOL_STRING3(field_, prefix_, __VA_ARGS__) + +#define SHOW_SYSFS_SYMBOL_STRING5(field_, prefix_, value_, ...) \ + SHOW_SYSFS_SYMBOL_STRING_ENTRY(field_, prefix_, value_) \ + SHOW_SYSFS_SYMBOL_STRING4(field_, prefix_, __VA_ARGS__) + +#define SHOW_SYSFS_SYMBOL_STRING(field_, prefix_, ...) \ + !valid ? "" : \ + CONCATENATE(SHOW_SYSFS_SYMBOL_STRING, \ + COUNT_ARGS(__VA_ARGS__))(field_, prefix_, __VA_ARGS__) + +#define SHOW_SYSFS_SYMBOL_FIELD(field_, ...) \ + n += scnprintf(&buf[n], PAGE_SIZE - n, #field_ "%s\n", \ + SHOW_SYSFS_SYMBOL_STRING(field_, gs_##field_, __VA_ARGS__)) + +#define SHOW_SYSFS_REGISTER(reg, str, ...) \ + static ssize_t show_##reg(struct device *device, \ + struct device_attribute *attr, char *buf) \ + { \ + const bool valid = gs_valid_##reg(); \ + const struct gs_##str value = valid ? \ + gs_read_##reg() : (struct gs_##str) { }; \ + size_t n = 0; \ + __VA_ARGS__; \ + return n; \ + } + +#define SYSFS_SHOW(reg, str, ...) \ + SHOW_SYSFS_REGISTER(reg, str, \ + CONCATENATE(SYSFS_STATEMENT, \ + COUNT_ARGS(__VA_ARGS__))(SHOW_, __VA_ARGS__)) + +#define SYSFS_RO_REG(reg, str, ...) \ + SYSFS_SHOW(reg, str, __VA_ARGS__) \ + static DEVICE_ATTR(reg, S_IRUGO, show_##reg, NULL) + +#define SYSFS_RW_REG(reg, str, ...) \ + SYSFS_SHOW(reg, str, __VA_ARGS__) \ + static DEVICE_ATTR(reg, S_IRUGO, show_##reg, NULL) + +SYSFS_RW_REG(pmode, pmode, + SYSFS_DECNUM_FIELD(en1), + SYSFS_DECNUM_FIELD(en2), + SYSFS_DECNUM_FIELD(crtmd), + SYSFS_SYMBOL_FIELD(mmod, circuit1, alp), + SYSFS_SYMBOL_FIELD(amod, circuit1, circuit2), + SYSFS_SYMBOL_FIELD(slbg, circuit2, bgcolor), + SYSFS_DECNUM_FIELD(alp)); + +SYSFS_RW_REG(smode1, smode1, + SYSFS_DECNUM_FIELD(rc), + SYSFS_DECNUM_FIELD(lc), + SYSFS_DECNUM_FIELD(t1248), + SYSFS_DECNUM_FIELD(slck), + SYSFS_SYMBOL_FIELD(cmod, vesa, ntsc, pal), + SYSFS_DECNUM_FIELD(ex), + SYSFS_DECNUM_FIELD(prst), + SYSFS_DECNUM_FIELD(sint), + SYSFS_DECNUM_FIELD(xpck), + SYSFS_DECNUM_FIELD(pck2), + SYSFS_DECNUM_FIELD(spml), + SYSFS_SYMBOL_FIELD(gcont, rgbyc, ycrcb), + SYSFS_DECNUM_FIELD(phs), + SYSFS_DECNUM_FIELD(pvs), + SYSFS_DECNUM_FIELD(pehs), + SYSFS_DECNUM_FIELD(pevs), + SYSFS_DECNUM_FIELD(clksel), + SYSFS_DECNUM_FIELD(nvck), + SYSFS_DECNUM_FIELD(slck2), + SYSFS_DECNUM_FIELD(vcksel), + SYSFS_DECNUM_FIELD(vhp)); + +SYSFS_RW_REG(smode2, smode2, + SYSFS_SYMBOL_FIELD(intm, progressive, interlace), + SYSFS_SYMBOL_FIELD(ffmd, field, frame), + SYSFS_SYMBOL_FIELD(dpms, on, standby, suspend, off)); + +SYSFS_RW_REG(srfsh, srfsh, + SYSFS_DECNUM_FIELD(rfsh)); + +SYSFS_RW_REG(synch1, synch1, + SYSFS_DECNUM_FIELD(hfp), + SYSFS_DECNUM_FIELD(hbp), + SYSFS_DECNUM_FIELD(hseq), + SYSFS_DECNUM_FIELD(hsvs), + SYSFS_DECNUM_FIELD(hs)); + +SYSFS_RW_REG(synch2, synch2, + SYSFS_DECNUM_FIELD(hf), + SYSFS_DECNUM_FIELD(hb)); + +SYSFS_RW_REG(syncv, syncv, + SYSFS_DECNUM_FIELD(vfp), + SYSFS_DECNUM_FIELD(vfpe), + SYSFS_DECNUM_FIELD(vbp), + SYSFS_DECNUM_FIELD(vbpe), + SYSFS_DECNUM_FIELD(vdp), + SYSFS_DECNUM_FIELD(vs)); + +SYSFS_RW_REG(dispfb1, dispfb, + SYSFS_DECNUM_FIELD(fbp), + SYSFS_DECNUM_FIELD(fbw), + SYSFS_SYMBOL_FIELD(psm, ct32, ct24, ct16, ct16s, gpu24), + SYSFS_DECNUM_FIELD(dbx), + SYSFS_DECNUM_FIELD(dby)); + +SYSFS_RW_REG(display1, display, + SYSFS_DECNUM_FIELD(dx), + SYSFS_DECNUM_FIELD(dy), + SYSFS_DECNUM_FIELD(magh), + SYSFS_DECNUM_FIELD(magv), + SYSFS_DECNUM_FIELD(dw), + SYSFS_DECNUM_FIELD(dh)); + +SYSFS_RW_REG(dispfb2, dispfb, + SYSFS_DECNUM_FIELD(fbp), + SYSFS_DECNUM_FIELD(fbw), + SYSFS_SYMBOL_FIELD(psm, ct32, ct24, ct16, ct16s), + SYSFS_DECNUM_FIELD(dbx), + SYSFS_DECNUM_FIELD(dby)); + +SYSFS_RW_REG(display2, display, + SYSFS_DECNUM_FIELD(dx), + SYSFS_DECNUM_FIELD(dy), + SYSFS_DECNUM_FIELD(magh), + SYSFS_DECNUM_FIELD(magv), + SYSFS_DECNUM_FIELD(dw), + SYSFS_DECNUM_FIELD(dh)); + +SYSFS_RW_REG(extbuf, extbuf, + SYSFS_DECNUM_FIELD(exbp), + SYSFS_DECNUM_FIELD(exbw), + SYSFS_SYMBOL_FIELD(fbin, out1, out2), + SYSFS_SYMBOL_FIELD(wffmd, field, frame), + SYSFS_SYMBOL_FIELD(emoda, alpha, y, yhalf, zero), + SYSFS_SYMBOL_FIELD(emodc, rgb, y, ycbcr, alpha), + SYSFS_DECNUM_FIELD(wdx), + SYSFS_DECNUM_FIELD(wdy)); + +SYSFS_RW_REG(extdata, extdata, + SYSFS_DECNUM_FIELD(sx), + SYSFS_DECNUM_FIELD(sy), + SYSFS_DECNUM_FIELD(smph), + SYSFS_DECNUM_FIELD(smpv), + SYSFS_DECNUM_FIELD(ww), + SYSFS_DECNUM_FIELD(wh)); + +SYSFS_RW_REG(extwrite, extwrite, + SYSFS_SYMBOL_FIELD(write, complete_current, start_next)); + +SYSFS_RW_REG(bgcolor, bgcolor, + SYSFS_DECNUM_FIELD(r), + SYSFS_DECNUM_FIELD(g), + SYSFS_DECNUM_FIELD(b)); + +SYSFS_RO_REG(csr, csr, + SYSFS_DECNUM_FIELD(signal), + SYSFS_DECNUM_FIELD(finish), + SYSFS_DECNUM_FIELD(hsint), + SYSFS_DECNUM_FIELD(vsint), + SYSFS_DECNUM_FIELD(edwint), + SYSFS_DECNUM_FIELD(flush), + SYSFS_DECNUM_FIELD(reset), + SYSFS_DECNUM_FIELD(nfield), + SYSFS_SYMBOL_FIELD(field, even, odd), + SYSFS_SYMBOL_FIELD(fifo, neither, empty, almost_full), + SYSFS_HEXNUM_FIELD(rev), + SYSFS_HEXNUM_FIELD(id)); + +SYSFS_RO_REG(imr, imr, + SYSFS_DECNUM_FIELD(sigmsk), + SYSFS_DECNUM_FIELD(finishmsk), + SYSFS_DECNUM_FIELD(hsmsk), + SYSFS_DECNUM_FIELD(vsmsk), + SYSFS_DECNUM_FIELD(edwmsk), + SYSFS_DECNUM_FIELD(ones)); + +SYSFS_RO_REG(busdir, busdir, + SYSFS_SYMBOL_FIELD(dir, host_to_local, local_to_host)); + +SYSFS_RW_REG(siglblid, siglblid, + SYSFS_DECNUM_FIELD(sigid), + SYSFS_DECNUM_FIELD(lblid)); + +static struct attribute *gs_registers_attributes[] = { + &dev_attr_pmode.attr, + &dev_attr_smode1.attr, + &dev_attr_smode2.attr, + &dev_attr_srfsh.attr, + &dev_attr_synch1.attr, + &dev_attr_synch2.attr, + &dev_attr_syncv.attr, + &dev_attr_dispfb1.attr, + &dev_attr_display1.attr, + &dev_attr_dispfb2.attr, + &dev_attr_display2.attr, + &dev_attr_extbuf.attr, + &dev_attr_extdata.attr, + &dev_attr_extwrite.attr, + &dev_attr_bgcolor.attr, + &dev_attr_csr.attr, /* FIXME: Too lowlevel for sysfs? */ + &dev_attr_imr.attr, /* FIXME: Too lowlevel for sysfs? */ + &dev_attr_busdir.attr, /* FIXME: Too lowlevel for sysfs? */ + &dev_attr_siglblid.attr, /* FIXME: Too lowlevel for sysfs? */ + NULL +}; + +static struct attribute_group gs_registers_attribute_group = { + .attrs = gs_registers_attributes +}; + +static int __init gs_sysfs_init(void) +{ + struct device *gs_dev = gs_device(); /* FIXME: Is this method appropriate? */ + int err; + + if (!gs_dev) { + pr_err("gs-sysfs: Failed to retrieve gs device\n"); + err = -ENXIO; + goto gs_dev_err; + } + + registers_kobj = kobject_create_and_add("registers", &gs_dev->kobj); + if (!registers_kobj) { + pr_err("gs-sysfs: Failed to create and add register kernel object\n"); + err = -ENOMEM; + goto kobj_err; + } + + err = sysfs_create_group(registers_kobj, &gs_registers_attribute_group); + if (err) { + pr_err("gs-sysfs: Failed to create register sysfs group\n"); + goto group_err; + } + + return 0; + +group_err: + kobject_del(registers_kobj); + +kobj_err: +gs_dev_err: + return err; +} + +static void __exit gs_sysfs_exit(void) +{ + kobject_del(registers_kobj); +} + +module_init(gs_sysfs_init); +module_exit(gs_sysfs_exit); + +MODULE_DESCRIPTION("PlayStation 2 Graphics Synthesizer sysfs driver"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:25:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125521 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 11E1614DE for ; Sun, 1 Sep 2019 16:25:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E57C1233A2 for ; Sun, 1 Sep 2019 16:25:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728883AbfIAQZ2 (ORCPT ); Sun, 1 Sep 2019 12:25:28 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:44868 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728877AbfIAQZ2 (ORCPT ); Sun, 1 Sep 2019 12:25:28 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 3F72C3F660; Sun, 1 Sep 2019 18:25:26 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EgNUseOu8H_3; Sun, 1 Sep 2019 18:25:25 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 820163F58C; Sun, 1 Sep 2019 18:25:25 +0200 (CEST) Date: Sun, 1 Sep 2019 18:25:25 +0200 From: Fredrik Noring To: Paul Burton , linux-mips@vger.kernel.org Cc: "Maciej W. Rozycki" , =?utf-8?q?J=C3=BCrgen?= Urban Subject: [PATCH 092/120] MIPS: PS2: GS: Store privileged registers with sysfs Message-ID: <0742ac0d622df50b672d8743146a947cac73d2e4.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org One or several bit fields can be written simultaneously. For example, the PMODE slbg field can be changed with: # echo "slbg bgcolor" >/sys/devices/platform/gs/registers/pmode Written values are integers or enum symbols, depending on the field. Signed-off-by: Fredrik Noring --- drivers/ps2/gs-sysfs.c | 145 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 5 deletions(-) diff --git a/drivers/ps2/gs-sysfs.c b/drivers/ps2/gs-sysfs.c index 2429de3e0094..3c749375aee0 100644 --- a/drivers/ps2/gs-sysfs.c +++ b/drivers/ps2/gs-sysfs.c @@ -4,9 +4,9 @@ * * Copyright (C) 2019 Fredrik Noring * - * Reading arbitrary numerical and symbolical privileged GS register - * bit fields is supported. For example, the PMODE register can be - * inspected with: + * Reading and writing arbitrary numerical and symbolical privileged + * GS register bit fields is supported. For example, the PMODE register + * can be inspected with: * * # cat /sys/devices/platform/gs/registers/pmode * en1 1 @@ -17,6 +17,11 @@ * slbg circuit2 * alp 0 * + * One or several bit fields can be written simultaneously. For example, + * the PMODE slbg field can be changed with: + * + * # echo "slbg bgcolor" >/sys/devices/platform/gs/registers/pmode + * * The implementation uses a fair amount of macro expansions. This greatly * simplifies register definitions, which in the case of PMODE is: * @@ -64,6 +69,76 @@ static struct kobject *registers_kobj; +static size_t line_size(const char *s) +{ + const size_t n = strchrnul(s, '\n') - s; + + return s[n] == '\n' ? n + 1 : n; +} + +static const char *trim_line_space(const char *s) +{ + while (isspace(*s) && *s != '\n') + s++; + + return s; +} + +static bool symbol_match(const char **s, const char *symbol) +{ + const size_t length = strlen(symbol); + const char *t = *s; + + t = trim_line_space(t); + if (strncmp(t, symbol, length) != 0) + return false; + t += length; + t = trim_line_space(t); + + *s = t; + + return true; +} + +static bool number_match(const char **s, u64 *value) +{ + const char *t = *s; + char *e; + + t = trim_line_space(t); + *value = simple_strtoull(t, &e, 0); + if (t == e) + return false; + t = e; + t = trim_line_space(t); + + *s = t; + + return true; +} + +static bool end_of_field(const char *s) +{ + return *s == '\n' || *s == '\0'; +} + +static bool symbol_field(const char *s, const char *field, const char *value) +{ + return symbol_match(&s, field) && + symbol_match(&s, value) && + end_of_field(s); +} + +static bool number_field(const char *s, const char *field, u64 *value) +{ + return symbol_match(&s, field) && + number_match(&s, value) && + end_of_field(s); +} + +#define for_each_line(s, n) \ + for (n = 0; (s)[n] != '\0'; n += line_size(&(s)[n])) + #define SYSFS_STATEMENT1(prefix_, macro_) \ prefix_##macro_; @@ -231,13 +306,73 @@ static struct kobject *registers_kobj; CONCATENATE(SYSFS_STATEMENT, \ COUNT_ARGS(__VA_ARGS__))(SHOW_, __VA_ARGS__)) +#define STORE_SYSFS_DECNUM_FIELD(field_) \ + do { \ + u64 value_; \ + if (number_field(&buf[n], #field_, &value_)) \ + value.field_ = value_; \ + } while (false) + +#define STORE_SYSFS_HEXNUM_FIELD(field_) \ + STORE_SYSFS_DECNUM_FIELD(field_) + +#define STORE_SYSFS_SYMBOL_FIELD_ENTRY(field_, prefix_, value_) \ + do { \ + if (symbol_field(&buf[n], #field_, #value_)) \ + value.field_ = prefix_##_##value_; \ + } while (false) + +#define STORE_SYSFS_SYMBOL_FIELD1(field_, prefix_, value_) \ + STORE_SYSFS_SYMBOL_FIELD_ENTRY(field_, prefix_, value_) + +#define STORE_SYSFS_SYMBOL_FIELD2(field_, prefix_, value_, ...) \ + STORE_SYSFS_SYMBOL_FIELD_ENTRY(field_, prefix_, value_); \ + STORE_SYSFS_SYMBOL_FIELD1(field_, prefix_, __VA_ARGS__) + +#define STORE_SYSFS_SYMBOL_FIELD3(field_, prefix_, value_, ...) \ + STORE_SYSFS_SYMBOL_FIELD_ENTRY(field_, prefix_, value_); \ + STORE_SYSFS_SYMBOL_FIELD2(field_, prefix_, __VA_ARGS__) + +#define STORE_SYSFS_SYMBOL_FIELD4(field_, prefix_, value_, ...) \ + STORE_SYSFS_SYMBOL_FIELD_ENTRY(field_, prefix_, value_); \ + STORE_SYSFS_SYMBOL_FIELD3(field_, prefix_, __VA_ARGS__) + +#define STORE_SYSFS_SYMBOL_FIELD5(field_, prefix_, value_, ...) \ + STORE_SYSFS_SYMBOL_FIELD_ENTRY(field_, prefix_, value_); \ + STORE_SYSFS_SYMBOL_FIELD4(field_, prefix_, __VA_ARGS__) + +#define STORE_SYSFS_SYMBOL_FIELD(field_, ...) \ + CONCATENATE(STORE_SYSFS_SYMBOL_FIELD, \ + COUNT_ARGS(__VA_ARGS__))(field_, gs_##field_, __VA_ARGS__) + +#define STORE_SYSFS_REGISTER(reg, str, ...) \ + static ssize_t store_##reg(struct device *device, \ + struct device_attribute *attr, const char *buf, size_t size) \ + { \ + const bool valid = gs_valid_##reg(); \ + struct gs_##str value = valid ? \ + gs_read_##reg() : (struct gs_##str) { }; \ + size_t n; \ + for_each_line(buf, n) { \ + __VA_ARGS__; \ + } \ + gs_write_##reg(value); \ + return size; \ + } + +#define SYSFS_STORE(reg, str, ...) \ + STORE_SYSFS_REGISTER(reg, str, \ + CONCATENATE(SYSFS_STATEMENT, \ + COUNT_ARGS(__VA_ARGS__))(STORE_, __VA_ARGS__)) + #define SYSFS_RO_REG(reg, str, ...) \ SYSFS_SHOW(reg, str, __VA_ARGS__) \ static DEVICE_ATTR(reg, S_IRUGO, show_##reg, NULL) #define SYSFS_RW_REG(reg, str, ...) \ SYSFS_SHOW(reg, str, __VA_ARGS__) \ - static DEVICE_ATTR(reg, S_IRUGO, show_##reg, NULL) + SYSFS_STORE(reg, str, __VA_ARGS__) \ + static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, show_##reg, store_##reg) SYSFS_RW_REG(pmode, pmode, SYSFS_DECNUM_FIELD(en1), @@ -412,7 +547,7 @@ static struct attribute_group gs_registers_attribute_group = { static int __init gs_sysfs_init(void) { - struct device *gs_dev = gs_device(); /* FIXME: Is this method appropriate? */ + struct device *gs_dev = gs_device_driver(); /* FIXME: Is this method appropriate? */ int err; if (!gs_dev) { From patchwork Sun Sep 1 16:25:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125523 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7338E14DE for ; Sun, 1 Sep 2019 16:25:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5068F233A2 for ; Sun, 1 Sep 2019 16:25:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728886AbfIAQZh (ORCPT ); Sun, 1 Sep 2019 12:25:37 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:59868 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728877AbfIAQZh (ORCPT ); Sun, 1 Sep 2019 12:25:37 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 708EE3F752 for ; Sun, 1 Sep 2019 18:25:35 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5gb38kM-JAFE for ; Sun, 1 Sep 2019 18:25:34 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id C9EC23F393 for ; Sun, 1 Sep 2019 18:25:34 +0200 (CEST) Date: Sun, 1 Sep 2019 18:25:34 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 093/120] fbdev: Add fb_warn_once() variant that only prints a warning once Message-ID: <5dd47e9805a123aa9bea3c8c3cadfab24e25c29d.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org fb_warn_once() is a variant of fb_warn(), to print a warning only once. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- include/linux/fb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fb.h b/include/linux/fb.h index 303771264644..19f5118e34ea 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -818,6 +818,8 @@ extern int fb_find_mode(struct fb_var_screeninfo *var, pr_notice("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__) #define fb_warn(fb_info, fmt, ...) \ pr_warn("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__) +#define fb_warn_once(fb_info, fmt, ...) \ + pr_warn_once("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__) #define fb_info(fb_info, fmt, ...) \ pr_info("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__) #define fb_dbg(fb_info, fmt, ...) \ From patchwork Sun Sep 1 16:26:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125525 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5BEF513B1 for ; Sun, 1 Sep 2019 16:26:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 309CC233A2 for ; Sun, 1 Sep 2019 16:26:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728888AbfIAQ0S (ORCPT ); Sun, 1 Sep 2019 12:26:18 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:60918 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728779AbfIAQ0R (ORCPT ); Sun, 1 Sep 2019 12:26:17 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id B8AE9402D7 for ; Sun, 1 Sep 2019 18:26:13 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xraPv2jdkMOf for ; Sun, 1 Sep 2019 18:26:12 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 82EBA3FC34 for ; Sun, 1 Sep 2019 18:26:12 +0200 (CEST) Date: Sun, 1 Sep 2019 18:26:12 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 094/120] MIPS: PS2: FB: Frame buffer driver for the PlayStation 2 Message-ID: <4927c42fb3401c42c4c5a077f272331ac79d80b1.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The main limitation is the lack of mmap, since the Graphics Synthesizer has local frame buffer memory that is not directly accessible from the main bus. The GS has 4 MiB of local memory. The console drawing primitives are synchronous to allow printk at any time. This is highly useful for debugging but it is not the fastest possible implementation. The console is nevertheless very fast and makes use of several hardware accelerated features of the Graphics Synthesizer. The maximum practical resolution is 1920x1080p at 16 bits per pixel that requires 4147200 bytes of local memory, leaving 47104 bytes for a tiled font, which at 8x8 pixels and a minimum 4 bits indexed texture palette is at most 1464 characters. The indexed palette makes switching colours easy. &struct fb_tile_ops is accelerated with GS texture sprites that are fast (GS local copy) for the kernel via simple DMA GS commands via the GIF. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/Kconfig | 12 + drivers/video/fbdev/Makefile | 1 + drivers/video/fbdev/ps2fb.c | 533 +++++++++++++++++++++++++++++++++ include/linux/console_struct.h | 2 + include/uapi/linux/fb.h | 1 + 5 files changed, 549 insertions(+) create mode 100644 drivers/video/fbdev/ps2fb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 6b2de93bd302..cc93cbd67b01 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1999,6 +1999,18 @@ config FB_IBM_GXT4500 doesn't use Geometry Engine GT1000. This driver also supports AGP Fire GL2/3/4 cards on x86. +# FIXME FB_SYS_* +config FB_PS2 + tristate "Frame buffer driver for Sony Playstation 2" + depends on FB && SONY_PS2 + select PS2_GS + select FB_TILEBLITTING + default y + help + Frame buffer driver for the Sony Playstation 2 Graphics Synthesizer. + Memory mapping is not supported since the frame buffer is local to + the GS. + config FB_PS3 tristate "PS3 GPU framebuffer driver" depends on FB && PS3_PS3AV diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 7dc4861a93e6..1e55fa8ca4af 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -105,6 +105,7 @@ obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o +obj-$(CONFIG_FB_PS2) += ps2fb.o obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o obj-$(CONFIG_FB_UDL) += udlfb.o diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c new file mode 100644 index 000000000000..7bfbc3c2aa4d --- /dev/null +++ b/drivers/video/fbdev/ps2fb.c @@ -0,0 +1,533 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 frame buffer driver + * + * Copyright (C) 2019 Fredrik Noring + */ + +/** + * DOC: The PlayStation 2 frame buffer console + * + * The frame buffer supports a tiled frame buffer console. The main limitation + * is the lack of memory mapping (mmap), since the Graphics Synthesizer has + * local frame buffer memory that is not directly accessible from the main bus. + * The GS has 4 MiB of local memory. + * + * The console drawing primitives are synchronous to allow printk at any time. + * This is highly useful for debugging but it is not the fastest possible + * implementation. The console is nevertheless very fast and makes use of + * several hardware accelerated features of the Graphics Synthesizer. + * + * The maximum practical resolution is 1920x1080p at 16 bits per pixel that + * requires 4147200 bytes of local memory, leaving 47104 bytes for a tiled + * font, which at 8x8 pixels and a minimum 4 bits indexed texture palette is + * at most 1464 characters. The indexed palette makes switching colours easy. + * &struct fb_tile_ops is accelerated with GS texture sprites that are fast + * (GS local copy) for the kernel via simple DMA GS commands via the GIF. + * + * The local memory is organised as follows: first comes the display buffer, + * then one block of a palette, and finally the font installed as a texture. + * + * All frame buffer transmissions are done by DMA via GIF PATH3. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#define DEVICE_NAME "ps2fb" + +#define PALETTE_BLOCK_COUNT 1 /* One block is used for the indexed colors */ + +/* Module parameters */ +static char *mode_option; + +union package { + union gif_data gif; + struct dma_tag dma; +}; + +/** + * struct tile_texture - texture representing a tile + * @tbp: texture base pointer + * @u: texel u coordinate (x coordinate) + * @v: texel v coordinate (y coordinate) + */ +struct tile_texture { + u32 tbp; + u32 u; + u32 v; +}; + +/** + * struct console_buffer - console buffer + * @block_count: number of frame buffer blocks + * @bg: background color index + * @fg: foreground color index + * @tile: tile dimensions + * @tile.width: width in pixels + * @tile.height: height in pixels + * @tile.width2: least width in pixels, power of 2 + * @tile.height2: least height in pixels, power of 2 + * @tile.block: tiles are stored as textures in the PSMT4 pixel storage format + * with both cols and rows as powers of 2 + * @tile.block.cols: tile columns per GS block + * @tile.block.rows: tile rows per GS block + */ +struct console_buffer { + u32 block_count; + + u32 bg; + u32 fg; + + struct cb_tile { + u32 width; + u32 height; + + u32 width2; + u32 height2; + + struct { + u32 cols; + u32 rows; + } block; + } tile; +}; + +/** + * struct ps2fb_par - driver specific structure + * @lock: spin lock to be taken for all structure operations + * @cb: console buffer definition + * @package: tags and datafor the GIF + * @package.capacity: maximum number of GIF packages in 16-byte unit + * @package.buffer: DMA buffer for GIF packages + */ +struct ps2fb_par { + spinlock_t lock; + + struct console_buffer cb; + + struct { + size_t capacity; + union package *buffer; + } package; +}; + +/** + * texture_least_power_of_2 - round up to a power of 2, not less than 8 + * @n: integer to round up + * + * Return: least integer that is a power of 2 and not less than @n or 8 + */ +static u32 texture_least_power_of_2(u32 n) +{ + return max(1 << get_count_order(n), 8); +} + +/** + * cb_tile - create a console buffer tile object + * @width: width of tile in pixels + * @height: height of tile in pixels + * + * Return: a console buffer tile object with the given width and height + */ +static struct cb_tile cb_tile(u32 width, u32 height) +{ + const u32 width2 = texture_least_power_of_2(width); + const u32 height2 = texture_least_power_of_2(height); + + return (struct cb_tile) { + .width = width, + .height = height, + + .width2 = width2, + .height2 = height2, + + .block = { + .cols = GS_PSMT4_BLOCK_WIDTH / width2, + .rows = GS_PSMT4_BLOCK_HEIGHT / height2, + }, + }; +} + +/** + * display_buffer_size - display buffer size for a given video resolution + * + * This calculation is a lower bound estimate. A precise calculation would have + * to take memory pages, blocks and column arrangements into account. To choose + * the appropriate standard video mode such details can be disregarded, though. + * + * Return: the size in bytes of the display buffer + */ +static u32 display_buffer_size(const u32 xres_virtual, const u32 yres_virtual, + const u32 bits_per_pixel) +{ + return (xres_virtual * yres_virtual * bits_per_pixel) / 8; +} + +/** + * ps2fb_cb_get_tilemax - maximum number of tiles + * @info: frame buffer info object + * + * Return: the maximum number of tiles + */ +static int ps2fb_cb_get_tilemax(struct fb_info *info) +{ + const struct ps2fb_par *par = info->par; + const u32 block_tile_count = + par->cb.tile.block.cols * + par->cb.tile.block.rows; + const s32 blocks_available = + GS_BLOCK_COUNT - par->cb.block_count - PALETTE_BLOCK_COUNT; + + return blocks_available > 0 ? blocks_available * block_tile_count : 0; +} + +/** + * bits_per_pixel_fits - does the given resolution fit the given buffer size? + * @xres_virtual: virtual x resolution in pixels + * @yres_virtual: virtual y resolution in pixels + * @bits_per_pixel: number of bits per pixel + * @buffer_size: size in bytes of display buffer + * + * The size calculation is approximate, but accurate enough for the standard + * video modes. + * + * Return: %true if the resolution fits the given buffer size, otherwise %false + */ +static bool bits_per_pixel_fits(const u32 xres_virtual, const u32 yres_virtual, + const int bits_per_pixel, const size_t buffer_size) +{ + return display_buffer_size(xres_virtual, yres_virtual, + bits_per_pixel) <= buffer_size; +} + +/** + * default_bits_per_pixel - choose either 16 or 32 bits per pixel + * @xres_virtual: virtual x resolution in pixels + * @yres_virtual: virtual y resolution in pixels + * @buffer_size: size in bytes of display buffer + * + * 32 bits per pixel is returned unless this does not fit the given buffer size. + * + * The size calculation is approximate, but accurate enough for the standard + * video modes. + * + * Return: 16 or 32 bits per pixel + */ +static int default_bits_per_pixel( + const u32 xres_virtual, const u32 yres_virtual, + const size_t buffer_size) +{ + return bits_per_pixel_fits(xres_virtual, yres_virtual, + 32, buffer_size) ? 32 : 16; +} + +/** + * filled_var_videomode - is the screen info video mode filled in? + * @var: screen info object to check + * + * Return: %true if the video mode is filled in, otherwise %false + */ +static bool filled_var_videomode(const struct fb_var_screeninfo *var) +{ + return var->xres > 0 && var->hsync_len > 0 && + var->yres > 0 && var->vsync_len > 0 && var->pixclock > 0; +} + +static int ps2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + /* Check whether video mode defaults are needed. */ + if (!filled_var_videomode(var)) { + const struct fb_videomode *vm = + fb_find_best_mode(var, &info->modelist); + + if (!vm) + return -EINVAL; + + fb_videomode_to_var(var, vm); + } + + /* GS video register resolution is limited to 2048. */ + if (var->xres < 1 || 2048 < var->xres || + var->yres < 1 || 2048 < var->yres) + return -EINVAL; + + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + var->xoffset = 0; + var->yoffset = 0; + + /* Check bits per pixel. */ + if (!var->bits_per_pixel) + var->bits_per_pixel = default_bits_per_pixel( + var->xres_virtual, var->yres_virtual, info->fix.smem_len); + else if (var->bits_per_pixel != 16 && + var->bits_per_pixel != 32) + return -EINVAL; + if (!bits_per_pixel_fits(var->xres_virtual, var->yres_virtual, + var->bits_per_pixel, info->fix.smem_len)) + var->bits_per_pixel = default_bits_per_pixel( + var->xres_virtual, var->yres_virtual, info->fix.smem_len); + if (!bits_per_pixel_fits(var->xres_virtual, var->yres_virtual, + var->bits_per_pixel, info->fix.smem_len)) + return -ENOMEM; + if (var->bits_per_pixel == 16) { + var->red = (struct fb_bitfield){ .offset = 0, .length = 5 }; + var->green = (struct fb_bitfield){ .offset = 5, .length = 5 }; + var->blue = (struct fb_bitfield){ .offset = 10, .length = 5 }; + var->transp = (struct fb_bitfield){ .offset = 15, .length = 1 }; + } else if (var->bits_per_pixel == 32) { + var->red = (struct fb_bitfield){ .offset = 0, .length = 8 }; + var->green = (struct fb_bitfield){ .offset = 8, .length = 8 }; + var->blue = (struct fb_bitfield){ .offset = 16, .length = 8 }; + var->transp = (struct fb_bitfield){ .offset = 24, .length = 8 }; + } else + return -EINVAL; /* Unsupported bits per pixel. */ + + /* Screen rotations are not supported. */ + if (var->rotate) + return -EINVAL; + + return 0; +} + +static int ps2fb_cb_check_var( + struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + unsigned long flags; + int err; + + spin_lock_irqsave(&par->lock, flags); + err = ps2fb_check_var(var, info); + spin_unlock_irqrestore(&par->lock, flags); + + if (!err && info->tileops) + if (info->tileops->fb_get_tilemax(info) < 256) + err = -ENOMEM; + + return err; +} + +static u32 block_dimensions(u32 dim, u32 alignment) +{ + u32 mask = 0; + u32 d; + + for (d = 1; d <= dim; d++) + if (d % alignment == 0) + mask |= 1 << (d - 1); + + return mask; +} + +static int init_console_buffer(struct platform_device *pdev, + struct fb_info *info) +{ + static struct fb_ops fbops = { + .owner = THIS_MODULE, + .fb_check_var = ps2fb_cb_check_var, + }; + + static struct fb_tile_ops tileops = { + .fb_get_tilemax = ps2fb_cb_get_tilemax + }; + + struct ps2fb_par *par = info->par; + + fb_info(info, "Graphics Synthesizer console frame buffer device\n"); + + info->screen_size = 0; + info->screen_base = NULL; /* mmap is unsupported by hardware */ + + info->fix.smem_start = 0; /* GS frame buffer is local memory */ + info->fix.smem_len = GS_MEMORY_SIZE; + + info->fbops = &fbops; + info->flags = FBINFO_DEFAULT | + FBINFO_READS_FAST; + + info->flags |= FBINFO_MISC_TILEBLITTING; + info->tileops = &tileops; + + /* + * BITBLTBUF for pixel format CT32 requires divisibility by 2, + * and CT16 requires divisibility by 4. So 4 is a safe choice. + */ + info->pixmap.blit_x = block_dimensions(GS_PSMT4_BLOCK_WIDTH, 4); + info->pixmap.blit_y = block_dimensions(GS_PSMT4_BLOCK_HEIGHT, 1); + + /* 8x8 default font tile size for fb_get_tilemax */ + par->cb.tile = cb_tile(8, 8); + + return 0; +} + +static int ps2fb_probe(struct platform_device *pdev) +{ + struct ps2fb_par *par; + struct fb_info *info; + int err; + + info = framebuffer_alloc(sizeof(*par), &pdev->dev); + if (info == NULL) { + dev_err(&pdev->dev, "framebuffer_alloc failed\n"); + err = -ENOMEM; + goto err_framebuffer_alloc; + } + + par = info->par; + + spin_lock_init(&par->lock); + + par->package.buffer = (union package *)__get_free_page(GFP_DMA); + if (!par->package.buffer) { + dev_err(&pdev->dev, "Failed to allocate package buffer\n"); + err = -ENOMEM; + goto err_package_buffer; + } + par->package.capacity = PAGE_SIZE / sizeof(union package); + + strlcpy(info->fix.id, "PS2 GS", ARRAY_SIZE(info->fix.id)); + info->fix.accel = FB_ACCEL_PLAYSTATION_2; + + err = init_console_buffer(pdev, info); + if (err < 0) + goto err_init_buffer; + + info->mode = &par->mode; + + if (register_framebuffer(info) < 0) { + fb_err(info, "register_framebuffer failed\n"); + err = -EINVAL; + goto err_register_framebuffer; + } + + platform_set_drvdata(pdev, info); + + return 0; + +err_register_framebuffer: +err_init_buffer: + free_page((unsigned long)par->package.buffer); +err_package_buffer: + framebuffer_release(info); +err_framebuffer_alloc: + return err; +} + +static int ps2fb_remove(struct platform_device *pdev) +{ + struct fb_info *info = platform_get_drvdata(pdev); + struct ps2fb_par *par = info->par; + int err = 0; + + if (info != NULL) { + unregister_framebuffer(info); + fb_dealloc_cmap(&info->cmap); + + framebuffer_release(info); + } + + if (!gif_wait()) { + fb_err(info, "Failed to complete GIF DMA transfer\n"); + err = -EBUSY; + } + free_page((unsigned long)par->package.buffer); + + return err; +} + +static struct platform_driver ps2fb_driver = { + .probe = ps2fb_probe, + .remove = ps2fb_remove, + .driver = { + .name = DEVICE_NAME, + }, +}; + +static struct platform_device *ps2fb_device; + +static int __init ps2fb_init(void) +{ + int err; + +#ifndef MODULE + char *options = NULL; + char *this_opt; + + if (fb_get_options(DEVICE_NAME, &options)) + return -ENODEV; + if (!options || !*options) + goto no_options; + + while ((this_opt = strsep(&options, ",")) != NULL) { + if (!*this_opt) + continue; + + if (!strncmp(this_opt, "mode_option:", 12)) + mode_option = &this_opt[12]; + else if ('0' <= this_opt[0] && this_opt[0] <= '9') + mode_option = this_opt; + else + pr_warn(DEVICE_NAME ": Unrecognized option \"%s\"\n", + this_opt); + } + +no_options: +#endif /* !MODULE */ + + /* Default to a suitable PAL or NTSC broadcast mode. */ + if (!mode_option) + mode_option = gs_region_pal() ? "576x460i@50" : "576x384i@60"; + + ps2fb_device = platform_device_alloc("ps2fb", 0); + if (!ps2fb_device) + return -ENOMEM; + + err = platform_device_add(ps2fb_device); + if (err < 0) { + platform_device_put(ps2fb_device); + return err; + } + + return platform_driver_register(&ps2fb_driver); +} + +static void __exit ps2fb_exit(void) +{ + platform_driver_unregister(&ps2fb_driver); + platform_device_unregister(ps2fb_device); +} + +module_init(ps2fb_init); +module_exit(ps2fb_exit); + +module_param(mode_option, charp, 0); +MODULE_PARM_DESC(mode_option, + "Specify initial video mode as \"x[-][@]\""); + +MODULE_DESCRIPTION("PlayStation 2 frame buffer driver"); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index 24d4c16e3ae0..cb562672cc3a 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h @@ -13,9 +13,11 @@ #ifndef _LINUX_CONSOLE_STRUCT_H #define _LINUX_CONSOLE_STRUCT_H +#include #include #include #include +#include struct uni_pagedir; struct uni_screen; diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h index b6aac7ee1f67..38d88eebf651 100644 --- a/include/uapi/linux/fb.h +++ b/include/uapi/linux/fb.h @@ -149,6 +149,7 @@ #define FB_ACCEL_SUPERSAVAGE 0x8c /* S3 Supersavage */ #define FB_ACCEL_PROSAVAGE_DDR 0x8d /* S3 ProSavage DDR */ #define FB_ACCEL_PROSAVAGE_DDRK 0x8e /* S3 ProSavage DDR-K */ +#define FB_ACCEL_PLAYSTATION_2 0x8f /* PlayStation 2 */ #define FB_ACCEL_PUV3_UNIGFX 0xa0 /* PKUnity-v3 Unigfx */ From patchwork Sun Sep 1 16:30:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125527 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7840014DE for ; Sun, 1 Sep 2019 16:30:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 401CA21874 for ; Sun, 1 Sep 2019 16:30:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728830AbfIAQap (ORCPT ); Sun, 1 Sep 2019 12:30:45 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60304 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQao (ORCPT ); Sun, 1 Sep 2019 12:30:44 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id DF2C43F752 for ; Sun, 1 Sep 2019 18:30:40 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oCUJYps_ptr0 for ; Sun, 1 Sep 2019 18:30:39 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id E76783F393 for ; Sun, 1 Sep 2019 18:30:39 +0200 (CEST) Date: Sun, 1 Sep 2019 18:30:39 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 095/120] MIPS: PS2: FB: fb_set_par() standard-definition television support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Most of the computations for the video synchronisation registers are based on trial an error, as their bit fields are undocumented. A small set of standard video modes are supplied with the Graphics Synthesizer user manual[1], and for these modes the corresponding register values are known. This frame buffer driver allows arbitrary top, bottom, left and right video display margin (border) adjustments, hence registers are computed instead of tabulated. This is useful to for example precisely center the image for a given analogue video display. The SDTV modes are designed to work with S-video, SCART and component video cables, in addition to the PS2 HDMI adapter based on the Macro Silicon MS9282 chip. The MAGV and MAGH fields for vertical and horizontal magnification in the DISPLAY registers could be used to support lower resolution video modes, for example 320x200 that was popular with many 8-bit and 16-bit computers, but that is left for a future extension. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 84. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 328 ++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 7bfbc3c2aa4d..3fb31719459c 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -133,6 +133,97 @@ struct ps2fb_par { } package; }; +/** + * struct gs_sync_param - Graphics Synthesizer registers for video modes + * @smode1: SMODE1 register + * @smode2: SMODE2 register + * @srfsh: SRFSH register + * @synch1: SYNCH1 register + * @synch2: SYNCH2 register + * @syncv: SYNCV register + * @display: DISPLAY1 or DISPLAY2 register + * + * These are the essential Graphics Synthesizer video synchronisation register + * parameters. + */ +struct gs_sync_param { + struct gs_smode1 smode1; + struct gs_smode2 smode2; + struct gs_srfsh srfsh; + struct gs_synch1 synch1; + struct gs_synch2 synch2; + struct gs_syncv syncv; + struct gs_display display; +}; + +/** + * var_to_fbw - frame buffer width for a given virtual x resolution + * @var: screen info object to compute FBW for + * + * Return: frame buffer width (FBW) in 64-pixel unit + */ +static u32 var_to_fbw(const struct fb_var_screeninfo *var) +{ + /* + * Round up to nearest GS_FB_PAGE_WIDTH (64 px) since there are + * valid resolutions such as 720 px that do not divide 64 properly. + */ + return (var->xres_virtual + GS_FB_PAGE_WIDTH - 1) / GS_FB_PAGE_WIDTH; +} + +/** + * var_to_psm - frame buffer pixel storage mode for a given bits per pixel + * @var: screen info object to compute PSM for + * @info: frame buffer info object + * + * Return: frame buffer pixel storage mode + */ +static enum gs_psm var_to_psm(const struct fb_var_screeninfo *var, + const struct fb_info *info) +{ + if (var->bits_per_pixel == 1) + return gs_psm_ct16; + if (var->bits_per_pixel == 16) + return gs_psm_ct16; + if (var->bits_per_pixel == 32) + return gs_psm_ct32; + + fb_warn_once(info, "%s: Unsupported bits per pixel %u\n", + __func__, var->bits_per_pixel); + return gs_psm_ct32; +} + +/** + * var_to_block_count - number of frame buffer blocks for a given video mode + * @var: screen info object to compute the number of blocks for + * + * The Graphics Synthesizer frame buffer is subdivided into rectangular pages, + * from left to right, top to bottom. Pages are further subdivided into blocks, + * with different arrangements for PSMCT16 and PSMCT32. Blocks are further + * subdivided into columns, which are finally subdivided into pixels. + * + * The video display buffer, textures and palettes share the same frame buffer. + * This function can be used to compute the first free block after the video + * display buffer. + * + * Return: number of blocks, or zero for unsupported pixel storage modes + */ +static u32 var_to_block_count(const struct fb_info *info) +{ + const struct fb_var_screeninfo *var = &info->var; + const enum gs_psm psm = var_to_psm(var, info); + const u32 fbw = var_to_fbw(var); + + if (psm == gs_psm_ct16) + return gs_psm_ct16_block_count(fbw, var->yres_virtual); + if (psm == gs_psm_ct32) + return gs_psm_ct32_block_count(fbw, var->yres_virtual); + + fb_warn_once(info, "%s: Unsupported pixel storage mode %u\n", + __func__, psm); + return 0; +} + /** * texture_least_power_of_2 - round up to a power of 2, not less than 8 * @n: integer to round up @@ -330,6 +421,242 @@ static int ps2fb_cb_check_var( return err; } +/** + * refresh_for_var - display refresh frequency for a given screen info + * @var: screen info object to compute the display frequency for + * + * Return: display refresh frequency in hertz + */ +static u32 refresh_for_var(const struct fb_var_screeninfo *var) +{ + const u32 htotal = var->hsync_len + + var->left_margin + var->xres + var->right_margin; + const u32 vtotal = var->vsync_len + + var->upper_margin + var->yres + var->lower_margin; + const u32 ptotal = htotal * vtotal; + + return DIV_ROUND_CLOSEST_ULL(DIV_ROUND_CLOSEST_ULL( + 1000000000000ull * ((var->vmode & FB_VMODE_INTERLACED) ? 2 : 1), + var->pixclock), ptotal); +} + +/** + * vm_to_cmod - determine the CMOD field for the SMODE1 register + * @vm: video mode object to compute CMOD for + * + * Result: PAL, NTSC or VESA + */ +static enum gs_smode1_cmod vm_to_cmod(const struct fb_videomode *vm) +{ + const u32 htotal = vm->hsync_len + + vm->left_margin + vm->xres + vm->right_margin; + const u32 vtotal = vm->vsync_len + + vm->upper_margin + vm->yres + vm->lower_margin; + const u32 ptotal = htotal * vtotal; + const u32 refresh = DIV_ROUND_CLOSEST_ULL(DIV_ROUND_CLOSEST_ULL( + 1000000000000ull * ((vm->vmode & FB_VMODE_INTERLACED) ? 2 : 1), + vm->pixclock), ptotal); + + if (vm->sync & FB_SYNC_BROADCAST) + return refresh < 55 ? gs_cmod_pal : + refresh < 65 ? gs_cmod_ntsc : + gs_cmod_vesa; + + return gs_cmod_vesa; +} + +/** + * vm_to_sp_sdtv - standard-definition television video synch parameters + * @vm: video mode object to compute synchronisation parameters for + * + * The numeric register field constants come from fixed SDTV video modes made + * by Sony. The main complication is that these values are the basis to compute + * arbitrary top, bottom, left and right display margin (border) settings for + * both PAL and NTSC. This is useful to for example precisely center the image + * for a given analogue video display. + * + * The SDTV modes are designed to work with S-video, SCART and component video + * cables, in addition to the PS2 HDMI adapter based on the Macro Silicon + * MS9282 chip. + * + * The MAGV and MAGH fields for vertical and horizontal magnification in the + * DISPLAY registers could be used to support lower resolution video modes, + * for example 320x200 that was popular with many 8-bit and 16-bit computers, + * but that is left for a future extension. + * + * Return: Graphics Synthesizer SDTV video mode synchronisation parameters + */ +static struct gs_sync_param vm_to_sp_sdtv(const struct fb_videomode *vm) +{ + const u32 cmod = vm_to_cmod(vm); + const u32 intm = (vm->vmode & FB_VMODE_INTERLACED) ? 1 : 0; + const u32 vs = cmod == gs_cmod_pal ? 5 : 6; + const u32 hb = cmod == gs_cmod_pal ? 1680 : 1652; + const u32 hf = 2892 - hb; + const u32 hs = 254; + const u32 hbp = cmod == gs_cmod_pal ? 262 : 222; + const u32 hfp = cmod == gs_cmod_pal ? 48 : 64; + const u32 vdp = cmod == gs_cmod_pal ? 576 : 480; + const u32 vbpe = vs; + const u32 vbp = cmod == gs_cmod_pal ? 33 : 26; + const u32 vfpe = vs; + const u32 vfp = (vm->vmode & FB_VMODE_INTERLACED) ? 1 : + cmod == gs_cmod_pal ? 4 : 2; + const u32 tw = hb + hf; + const u32 th = vdp; + const u32 dw = min_t(u32, vm->xres * 4, tw); + const u32 dh = min_t(u32, vm->yres * (intm ? 1 : 2), th); + const u32 dx = hs + hbp + (tw - dw)/2 - 1; + const u32 dy = (vs + vbp + vbpe + (th - dh)/2) / (intm ? 1 : 2) - 1; + + return (struct gs_sync_param) { + .smode1 = { + .vhp = 0, .vcksel = 1, .slck2 = 1, .nvck = 1, + .clksel = 1, .pevs = 0, .pehs = 0, .pvs = 0, + .phs = 0, .gcont = 0, .spml = 4, .pck2 = 0, + .xpck = 0, .sint = 1, .prst = 0, .ex = 0, + .cmod = cmod, .slck = 0, .t1248 = 1, + .lc = 32, .rc = 4 + }, + .smode2 = { + .intm = intm + }, + .srfsh = { + .rfsh = 8 + }, + .synch1 = { + .hs = hs, + .hsvs = cmod == gs_cmod_pal ? 1474 : 1462, + .hseq = cmod == gs_cmod_pal ? 127 : 124, + .hbp = hbp, + .hfp = hfp + }, + .synch2 = { + .hb = hb, + .hf = hf + }, + .syncv = { + .vs = vs, + .vdp = vdp, + .vbpe = vbpe, + .vbp = vbp, + .vfpe = vfpe, + .vfp = vfp + }, + .display = { + .dh = vm->yres - 1, + .dw = vm->xres * 4 - 1, + .magv = 0, + .magh = 3, + .dy = dy, + .dx = dx + } + }; +} + +static struct gs_sync_param vm_to_sp_for_synch_gen( + const struct fb_videomode *vm, const struct gs_synch_gen sg) +{ + struct gs_sync_param sp = vm_to_sp_sdtv(vm); + + sp.smode1.gcont = gs_gcont_ycrcb; + sp.smode1.sint = 1; + sp.smode1.prst = 0; + + return sp; +} + +static struct gs_sync_param vm_to_sp(const struct fb_videomode *vm) +{ + return vm_to_sp_for_synch_gen(vm, gs_synch_gen_for_vck(vm->pixclock)); +} + +static int ps2fb_set_par(struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + const struct fb_var_screeninfo *var = &info->var; + const struct fb_videomode *mm = fb_match_mode(var, &info->modelist); + const struct fb_videomode vm = (struct fb_videomode) { + .refresh = refresh_for_var(var), + .xres = var->xres, + .yres = var->yres, + .pixclock = var->pixclock, + .left_margin = var->left_margin, + .right_margin = var->right_margin, + .upper_margin = var->upper_margin, + .lower_margin = var->lower_margin, + .hsync_len = var->hsync_len, + .vsync_len = var->vsync_len, + .sync = var->sync, + .vmode = var->vmode, + .flag = mm != NULL ? mm->flag : 0 + }; + const struct gs_sync_param sp = vm_to_sp(&vm); + struct gs_smode1 smode1 = sp.smode1; + + par->mode = vm; + + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_TRUECOLOR; + info->fix.xpanstep = 0; + info->fix.ypanstep = 0; + info->fix.ywrapstep = 1; + info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; + + gs_write_smode1(smode1); + gs_write_smode2(sp.smode2); + gs_write_srfsh(sp.srfsh); + gs_write_synch1(sp.synch1); + gs_write_synch2(sp.synch2); + gs_write_syncv(sp.syncv); + gs_write_display1(sp.display); + + GS_WRITE_DISPFB1( + .fbw = var_to_fbw(var), + .psm = var_to_psm(var, info), + .dbx = var->xoffset, + .dby = var->yoffset, + ); + + GS_WRITE_PMODE( + .en1 = 1, + .crtmd = 1 + ); + + smode1.prst = 1; + gs_write_smode1(smode1); + + udelay(2500); + + smode1.sint = 0; + smode1.prst = 0; + gs_write_smode1(smode1); + + return 0; +} + +static int ps2fb_cb_set_par(struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + unsigned long flags; + int err; + + spin_lock_irqsave(&par->lock, flags); + + err = ps2fb_set_par(info); + if (!err) + par->cb.block_count = var_to_block_count(info); + + spin_unlock_irqrestore(&par->lock, flags); + + if (!err && info->tileops) + fb_info(info, "%d tiles maximum for %ux%u font\n", + info->tileops->fb_get_tilemax(info), + par->cb.tile.width, par->cb.tile.height); + + return err; +} + static u32 block_dimensions(u32 dim, u32 alignment) { u32 mask = 0; @@ -347,6 +674,7 @@ static int init_console_buffer(struct platform_device *pdev, { static struct fb_ops fbops = { .owner = THIS_MODULE, + .fb_set_par = ps2fb_cb_set_par, .fb_check_var = ps2fb_cb_check_var, }; From patchwork Sun Sep 1 16:30:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125529 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 92D8614E5 for ; Sun, 1 Sep 2019 16:30:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7B18B233A2 for ; Sun, 1 Sep 2019 16:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728916AbfIAQaz (ORCPT ); Sun, 1 Sep 2019 12:30:55 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33056 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQaz (ORCPT ); Sun, 1 Sep 2019 12:30:55 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id E2FAB3FC34 for ; Sun, 1 Sep 2019 18:30:52 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id j1U68j0XK59c for ; Sun, 1 Sep 2019 18:30:52 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 313853FA2D for ; Sun, 1 Sep 2019 18:30:52 +0200 (CEST) Date: Sun, 1 Sep 2019 18:30:51 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 096/120] MIPS: PS2: FB: fb_set_par() high-definition television support Message-ID: <95af9f78f8336db3170ae66218af33e3ccfaea50.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Some of the numeric register field constants come from fixed DTV video modes made by Sony[1]. The main complication is that these values are the basis to compute arbitrary top, bottom, left and right display margin (border) settings. This is useful to for example precisely center the image for a given analogue video display. The HDTV modes are designed to work with component video cables and the PS2 HDMI adapter based on the Macro Silicon MS9282 chip. The MAGV and MAGH fields for vertical and horizontal magnification in the DISPLAY registers could be used to emulate SDTV resolution video modes such as 320x200 that was popular with many 8-bit and 16-bit computers, but that is left for a future extension. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 84. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 86 ++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 3fb31719459c..f9061ccc5755 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -554,10 +554,94 @@ static struct gs_sync_param vm_to_sp_sdtv(const struct fb_videomode *vm) }; } +/** + * vm_to_sp_hdtv - high-definition television video synch parameters + * @vm: video mode object to compute synchronisation parameters for + * @sg: Graphics Synthesizer SMODE1 register video clock fields + * + * Some of the numeric register field constants come from fixed DTV video + * modes made by Sony. The main complication is that these values are the + * basis to compute arbitrary top, bottom, left and right display margin + * (border) settings. This is useful to for example precisely center the + * image for a given analogue video display. + * + * The HDTV modes are designed to work with component video cables and the + * PS2 HDMI adapter based on the Macro Silicon MS9282 chip. + * + * The MAGV and MAGH fields for vertical and horizontal magnification in the + * DISPLAY registers could be used to emulate SDTV resolution video modes such + * as 320x200 that was popular with many 8-bit and 16-bit computers, but that + * is left for a future extension. + * + * Return: Graphics Synthesizer HDTV video mode synchronisation parameters + */ +static struct gs_sync_param vm_to_sp_hdtv( + const struct fb_videomode *vm, const struct gs_synch_gen sg) +{ + const u32 spml = sg.spml; + const u32 t1248 = sg.t1248; + const u32 lc = sg.lc; + const u32 rc = sg.rc; + const u32 vc = vm->yres <= 576 ? 1 : 0; + const u32 hadj = spml / 2; + const u32 vhp = (vm->vmode & FB_VMODE_INTERLACED) ? 0 : 1; + const u32 hb = vm->xres * spml * 3 / 5; + + return (struct gs_sync_param) { + .smode1 = { + .vhp = vhp, .vcksel = vc, .slck2 = 1, .nvck = 1, + .clksel = 1, .pevs = 0, .pehs = 0, .pvs = 0, + .phs = 0, .gcont = 0, .spml = spml, .pck2 = 0, + .xpck = 0, .sint = 1, .prst = 0, .ex = 0, + .cmod = 0, .slck = 0, .t1248 = t1248, + .lc = lc, .rc = rc + }, + .smode2 = { + .intm = (vm->vmode & FB_VMODE_INTERLACED) ? 1 : 0 + }, + .srfsh = { + .rfsh = gs_rfsh_from_synch_gen(sg) + }, + .synch1 = { + .hs = vm->hsync_len * spml, + .hsvs = (vm->left_margin + vm->xres + + vm->right_margin - vm->hsync_len) * spml / 2, + .hseq = vm->hsync_len * spml, + .hbp = vm->left_margin * spml - hadj, + .hfp = vm->right_margin * spml + hadj + }, + .synch2 = { + .hb = hb, + .hf = vm->xres * spml - hb + }, + .syncv = { + .vs = vm->vsync_len, + .vdp = vm->yres, + .vbpe = 0, + .vbp = vm->upper_margin, + .vfpe = 0, + .vfp = vm->lower_margin + }, + .display = { + .dh = vm->yres - 1, + .dw = vm->xres * spml - 1, + .magv = 0, + .magh = spml - 1, + .dy = vm->vsync_len + vm->upper_margin - 1, + .dx = (vm->hsync_len + vm->left_margin) * spml - 1 - hadj + } + }; +} + static struct gs_sync_param vm_to_sp_for_synch_gen( const struct fb_videomode *vm, const struct gs_synch_gen sg) { - struct gs_sync_param sp = vm_to_sp_sdtv(vm); + const bool bc = vm->sync & FB_SYNC_BROADCAST; + const bool il = vm->vmode & FB_VMODE_INTERLACED; + struct gs_sync_param sp = + vm->yres <= 288 && bc ? vm_to_sp_sdtv(vm) : + vm->yres <= 576 && il && bc ? vm_to_sp_sdtv(vm) : + vm_to_sp_hdtv(vm, sg); sp.smode1.gcont = gs_gcont_ycrcb; sp.smode1.sint = 1; From patchwork Sun Sep 1 16:31:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125531 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 03F9914DE for ; Sun, 1 Sep 2019 16:31:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DC7E823711 for ; Sun, 1 Sep 2019 16:31:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728934AbfIAQbH (ORCPT ); Sun, 1 Sep 2019 12:31:07 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:45262 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQbH (ORCPT ); Sun, 1 Sep 2019 12:31:07 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 39C263F63C for ; Sun, 1 Sep 2019 18:31:05 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FuTZB4b0X92A for ; Sun, 1 Sep 2019 18:31:04 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 8A9723F58C for ; Sun, 1 Sep 2019 18:31:04 +0200 (CEST) Date: Sun, 1 Sep 2019 18:31:04 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 097/120] MIPS: PS2: FB: fb_set_par() VESA computer display mode support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Some of the numeric register field constants come from fixed VESA video modes made by Sony[1]. The main complication is that these values are the basis to compute arbitrary top, bottom, left and right display margin (border) settings. This is useful to for example precisely center the image for a given analogue video display. The VESA modes are designed to work with the synch-on-green (SOG) VGA cable that Sony distributed with the Linux kit for the PlayStation 2. Modern computer displays typically do not support synch-on-green, so an adapter is most likely necessary for these modes. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 84. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 78 ++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index f9061ccc5755..dd8b468ab72b 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -633,6 +633,81 @@ static struct gs_sync_param vm_to_sp_hdtv( }; } +/** + * vm_to_sp_vesa - VESA computer display mode synch parameters + * @vm: video mode object to compute synchronisation parameters for + * @sg: Graphics Synthesizer SMODE1 register video clock fields + * + * Some of the numeric register field constants come from fixed VESA video + * modes made by Sony. The main complication is that these values are the + * basis to compute arbitrary top, bottom, left and right display margin + * (border) settings. This is useful to for example precisely center the + * image for a given analogue video display. + * + * The VESA modes are designed to work with the synch-on-green (SOG) VGA cable + * that Sony distributed with the Linux kit for the PlayStation 2. Modern + * computer displays typically do not support synch-on-green, so an adapter + * is most likely necessary for these modes. + * + * Return: Graphics Synthesizer VESA display mode synchronisation parameters + */ +static struct gs_sync_param vm_to_sp_vesa( + const struct fb_videomode *vm, const struct gs_synch_gen sg) +{ + const u32 spml = sg.spml; + const u32 t1248 = sg.t1248; + const u32 lc = sg.lc; + const u32 rc = sg.rc; + const u32 hadj = spml / 2; + const u32 vhp = (vm->vmode & FB_VMODE_INTERLACED) ? 0 : 1; + const u32 hb = vm->xres * spml * 3 / 5; + + return (struct gs_sync_param) { + .smode1 = { + .vhp = vhp, .vcksel = 0, .slck2 = 1, .nvck = 1, + .clksel = 1, .pevs = 0, .pehs = 0, .pvs = 0, + .phs = 0, .gcont = 0, .spml = spml, .pck2 = 0, + .xpck = 0, .sint = 1, .prst = 0, .ex = 0, + .cmod = 0, .slck = 0, .t1248 = t1248, + .lc = lc, .rc = rc + }, + .smode2 = { + .intm = (vm->vmode & FB_VMODE_INTERLACED) ? 1 : 0 + }, + .srfsh = { + .rfsh = gs_rfsh_from_synch_gen(sg) + }, + .synch1 = { + .hs = vm->hsync_len * spml, + .hsvs = (vm->left_margin + vm->xres + + vm->right_margin - vm->hsync_len) * spml / 2, + .hseq = vm->hsync_len * spml, + .hbp = vm->left_margin * spml - hadj, + .hfp = vm->right_margin * spml + hadj + }, + .synch2 = { + .hb = hb, + .hf = vm->xres * spml - hb + }, + .syncv = { + .vs = vm->vsync_len, + .vdp = vm->yres, + .vbpe = 0, + .vbp = vm->upper_margin, + .vfpe = 0, + .vfp = vm->lower_margin + }, + .display = { + .dh = vm->yres - 1, + .dw = vm->xres * spml - 1, + .magv = 0, + .magh = spml - 1, + .dy = vm->vsync_len + vm->upper_margin - 1, + .dx = (vm->hsync_len + vm->left_margin) * spml - 1 - hadj + } + }; +} + static struct gs_sync_param vm_to_sp_for_synch_gen( const struct fb_videomode *vm, const struct gs_synch_gen sg) { @@ -641,7 +716,8 @@ static struct gs_sync_param vm_to_sp_for_synch_gen( struct gs_sync_param sp = vm->yres <= 288 && bc ? vm_to_sp_sdtv(vm) : vm->yres <= 576 && il && bc ? vm_to_sp_sdtv(vm) : - vm_to_sp_hdtv(vm, sg); + bc ? vm_to_sp_hdtv(vm, sg) : + vm_to_sp_vesa(vm, sg); sp.smode1.gcont = gs_gcont_ycrcb; sp.smode1.sint = 1; From patchwork Sun Sep 1 16:31:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125533 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 758E814E5 for ; Sun, 1 Sep 2019 16:31:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5351021874 for ; Sun, 1 Sep 2019 16:31:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728930AbfIAQba (ORCPT ); Sun, 1 Sep 2019 12:31:30 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60382 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQba (ORCPT ); Sun, 1 Sep 2019 12:31:30 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 444E53F752 for ; Sun, 1 Sep 2019 18:31:29 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DtdsWtezF5Wa for ; Sun, 1 Sep 2019 18:31:28 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 74E453F393 for ; Sun, 1 Sep 2019 18:31:28 +0200 (CEST) Date: Sun, 1 Sep 2019 18:31:28 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 098/120] MIPS: PS2: FB: Preconfigure standard PAL, NTSC and VESA display modes Message-ID: <6b0617e9a1f60312b3a22c24549011b434ac413b.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org These display mode configurations are a combination of modes made by Sony[1] and modes from the PlayStation 3 frame buffer driver (ps3fb.c). The VESA modes are designed to work with the synch-on-green (SOG) VGA cable that Sony distributed with the Linux kit for the PlayStation 2. Modern computer displays typically do not support synch-on-green, so an adapter is most likely necessary for these modes. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 84. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 110 ++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index dd8b468ab72b..a28263474665 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -156,6 +156,91 @@ struct gs_sync_param { struct gs_display display; }; +static const struct fb_videomode standard_modes[] = { + /* PAL */ + { "256p", 50, 640, 256, 74074, 100, 61, 34, 22, 63, 2, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "288p", 50, 720, 288, 74074, 70, 11, 19, 3, 63, 3, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "512i", 50, 640, 512, 74074, 100, 61, 67, 41, 63, 5, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED, FB_MODE_IS_STANDARD }, + { "576i", 50, 720, 576, 74074, 70, 11, 39, 5, 63, 5, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED, FB_MODE_IS_STANDARD }, + { "576p", 50, 720, 576, 37037, 70, 11, 39, 5, 63, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "720p", 50, 1280, 720, 13468, 220, 400, 19, 6, 80, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "1080i", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED, FB_MODE_IS_STANDARD }, + { "1080p", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + + /* PAL with borders to ensure that the whole screen is visible */ + { "460i", 50, 576, 460, 74074, 142, 83, 97, 63, 63, 5, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED }, + { "460p", 50, 576, 460, 37037, 142, 83, 97, 63, 63, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED }, + { "644p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED }, + { "964i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED }, + { "964p", 50, 1688, 964, 6734, 264, 600, 94, 62, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED }, + + /* NTSC */ + { "224p", 60, 640, 224, 74074, 95, 60, 22, 14, 63, 3, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "240p", 60, 720, 240, 74074, 58, 17, 15, 5, 63, 3, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "448i", 60, 640, 448, 74074, 95, 60, 44, 27, 63, 6, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED, FB_MODE_IS_STANDARD }, + { "480i", 60, 720, 480, 74074, 58, 17, 30, 9, 63, 6, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED, FB_MODE_IS_STANDARD }, + { "480p", 60, 720, 480, 37037, 58, 17, 30, 9, 63, 6, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "720p", 60, 1280, 720, 13481, 220, 70, 19, 6, 80, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + { "1080i", 60, 1920, 1080, 13481, 148, 44, 36, 4, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED, FB_MODE_IS_STANDARD }, + { "1080p", 60, 1920, 1080, 6741, 148, 44, 36, 4, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED, FB_MODE_IS_STANDARD }, + + /* NTSC with borders to ensure that the whole screen is visible */ + { "384i", 60, 576, 384, 74074, 130, 89, 78, 57, 63, 6, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED }, + { "384p", 60, 576, 384, 37037, 130, 89, 78, 57, 63, 6, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED }, + { "644p", 60, 1124, 644, 13481, 298, 148, 57, 44, 80, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED }, + { "964i", 60, 1688, 964, 13481, 264, 160, 94, 62, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED }, + { "964p", 60, 1688, 964, 6741, 264, 160, 94, 62, 88, 5, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED }, + + /* VESA */ + { "vesa-1a", 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "vesa-1c", 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "vesa-2b", 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "vesa-2d", 75, 800, 600, 20202, 160, 16, 21, 1, 80, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "vesa-3b", 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6, + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "vesa-3d", 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "vesa-4a", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "vesa-4b", 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA } +}; + /** * var_to_fbw - frame buffer width for a given virtual x resolution * @var: screen info object to compute FBW for @@ -829,6 +914,17 @@ static u32 block_dimensions(u32 dim, u32 alignment) return mask; } +static void fill_modes(struct device *dev, struct list_head *head) +{ + int i; + + INIT_LIST_HEAD(head); + + for (i = 0; i < ARRAY_SIZE(standard_modes); i++) + if (fb_add_videomode(&standard_modes[i], head) < 0) + dev_err(dev, "fb_add_videomode failed\n"); +} + static int init_console_buffer(struct platform_device *pdev, struct fb_info *info) { @@ -897,6 +993,8 @@ static int ps2fb_probe(struct platform_device *pdev) } par->package.capacity = PAGE_SIZE / sizeof(union package); + fill_modes(&pdev->dev, &info->modelist); + strlcpy(info->fix.id, "PS2 GS", ARRAY_SIZE(info->fix.id)); info->fix.accel = FB_ACCEL_PLAYSTATION_2; @@ -904,6 +1002,17 @@ static int ps2fb_probe(struct platform_device *pdev) if (err < 0) goto err_init_buffer; + fb_info(info, "Mode option is \"%s\"\n", mode_option); + + info->var = (struct fb_var_screeninfo) { }; + if (!fb_find_mode(&info->var, info, mode_option, + standard_modes, ARRAY_SIZE(standard_modes), NULL, 32)) { + fb_err(info, "Failed to find video mode \"%s\"\n", + mode_option); + err = -EINVAL; + goto err_find_mode; + } + info->mode = &par->mode; if (register_framebuffer(info) < 0) { @@ -917,6 +1026,7 @@ static int ps2fb_probe(struct platform_device *pdev) return 0; err_register_framebuffer: +err_find_mode: err_init_buffer: free_page((unsigned long)par->package.buffer); err_package_buffer: From patchwork Sun Sep 1 16:31:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125535 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3424414E5 for ; Sun, 1 Sep 2019 16:31:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1115C21874 for ; Sun, 1 Sep 2019 16:31:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728938AbfIAQbz (ORCPT ); Sun, 1 Sep 2019 12:31:55 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33154 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQbz (ORCPT ); Sun, 1 Sep 2019 12:31:55 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 733683FC34 for ; Sun, 1 Sep 2019 18:31:53 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id G2dZd_2aeDBL for ; Sun, 1 Sep 2019 18:31:52 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id A9BD03FA2D for ; Sun, 1 Sep 2019 18:31:52 +0200 (CEST) Date: Sun, 1 Sep 2019 18:31:52 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 099/120] MIPS: PS2: FB: Reset the Graphics Synthesizer drawing environment Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Various parameters are used to draw Graphics Synthesizer primitives, for example texture information and drawing attributes set by the PRIM register[1]. These parameters are called the drawing environment. The environment remains in effect for multiple primitives until it is reset. Some environment registers such as XYOFFSET_1 and XYOFFSET_2 represent the same function and can be chosen with the CTXT primitive attribute. This driver is currently only using the first drawing environment. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 47-49. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 198 +++++++++++++++++++++++++++++++++++- 1 file changed, 197 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index a28263474665..90ddcbe27d43 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -59,6 +59,11 @@ #define PALETTE_BLOCK_COUNT 1 /* One block is used for the indexed colors */ +#define GIF_PACKAGE_TAG(package) ((package)++)->gif.tag = (struct gif_tag) +#define GIF_PACKAGE_REG(package) ((package)++)->gif.reg = (struct gif_data_reg) +#define GIF_PACKAGE_AD(package) ((package)++)->gif.packed.ad = (struct gif_packed_ad) +#define DMA_PACKAGE_TAG(package) ((package)++)->dma = (struct dma_tag) + /* Module parameters */ static char *mode_option; @@ -361,6 +366,194 @@ static u32 display_buffer_size(const u32 xres_virtual, const u32 yres_virtual, return (xres_virtual * yres_virtual * bits_per_pixel) / 8; } +/** + * struct environment - Graphics Synthesizer drawing environment context + * @xres: x resolution in pixels + * @yres: y resolution in pixels + * @fbw: frame buffer width in 64-pixel unit + * @psm: pixel storage mode + * @fbp: frame buffer base pointer in 2048-pixel unit + */ +struct environment { + u32 xres; + u32 yres; + u32 fbw; + enum gs_psm psm; + u32 fbp; +}; + +/** + * var_to_env - Graphics Synthesizer drawing environment for a given video mode + * @var: screen info object + * @info: frame buffer info object + * + * Return: Graphics Synthesizer drawing environment parameters + */ +static struct environment var_to_env(const struct fb_var_screeninfo *var, + const struct fb_info *info) +{ + return (struct environment) { + .xres = var->xres, + .yres = var->yres, + .fbw = var_to_fbw(var), + .psm = var_to_psm(var, info) + }; +} + +/** + * package_environment - package drawing environment tags and data for the GIF + * @package: DMA buffer to put packages in + * @env: drawing environment to package + * + * Various parameters are used to draw Graphics Synthesizer primitives, for + * example texture information and drawing attributes set by the PRIM register. + * These parameters are called the drawing environment. The environment remains + * in effect for multiple primitives until it is reset. + * + * Some environment registers such as XYOFFSET_1 and XYOFFSET_2 represent the + * same function and can be chosen with the CTXT primitive attribute. + * + * The following registers are available: + * + * ============ ============================================================= + * XYOFFSET_1/2 offset value of vertex coordinates + * PRMODECONT PRIM attributes enabled/disabled + * TEX0_1/2 attributes of texture buffer and texture mapping + * TEX1_1/2 attributes of texture mapping + * TEX2_1/2 colour lookup table entry + * CLAMP_1/2 wrap mode of texture mapping + * TEXCLUT colour lookup table setting + * SCANMSK drawing control with y coordinate of pixel + * MIPTBP1_1/2 base pointer for MIPMAP on each level + * MIPTBP2_1/2 base pointer for MIPMAP on each level + * TEXA reference value when expanding alpha value of TEX16 and TEX24 + * FOGCOL fogging distant color + * SCISSOR_1/2 scissoring area + * ALPHA_1/2 alpha-blending attributes + * DIMX dither matrix + * DTHE dithering enabled/disabled + * COLCLAMP color clamp/mask + * TEST_1/2 pixel operation + * PABE alpha-blending in pixel units enabled/disabled + * FBA_1/2 alpha correction value + * FRAME_1/2 frame buffer setting + * ZBUF_1/2 z buffer setting + * ============ ============================================================= + * + * Return: number of generated GIF packages in 16-byte unit + */ +static size_t package_environment(union package *package, + const struct environment env) +{ + union package * const base_package = package; + + GIF_PACKAGE_TAG(package) { + .flg = gif_packed_mode, + .reg0 = gif_reg_ad, + .nreg = 1, + .nloop = 11 + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_frame_1, + .data.frame_1 = { + .fbw = env.fbw, + .fbp = env.fbp, + .psm = env.psm + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_xyoffset_1, + .data.xyoffset_1 = { + .ofx = 0, + .ofy = 0, + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_scissor_1, + .data.scissor_1 = { + .scax0 = 0, .scax1 = env.xres, + .scay0 = 0, .scay1 = env.yres + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_scanmsk, + .data.scanmsk = { + .msk = gs_scanmsk_normal + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_prmode, + .data.prmode = { } /* Reset PRMODE to a known value */ + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_prmodecont, + .data.prmodecont = { + .ac = 1 + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_test_1, + .data.test_1 = { + .zte = gs_depth_test_on, /* Must always be ON */ + .ztst = gs_depth_pass /* Emulate OFF */ + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_texa, + .data.texa = { + .ta0 = GS_ALPHA_ONE, + .aem = gs_aem_normal, + .ta1 = GS_ALPHA_ONE + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_tex1_1, + .data.tex1 = { + .lcm = gs_lcm_fixed, + .mmag = gs_lod_nearest, + .mmin = gs_lod_nearest, + .k = 0 + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_zbuf_1, + .data.zbuf = { + .zmsk = gs_zbuf_off + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_dthe, + .data.dthe = { + .dthe = gs_dthe_off + } + }; + + return package - base_package; +} + +/** + * write_cb_environment - write console buffer GS drawing environment to the GIF + * @info: frame buffer info object + * + * Write various parameters used to draw Graphics Synthesizer primitives, for + * example texture information and drawing attributes set by the PRIM register. + * The environment remains in effect for multiple primitives until it is reset. + */ +void write_cb_environment(struct fb_info *info) +{ + if (gif_wait()) { + struct ps2fb_par *par = info->par; + union package * const base_package = par->package.buffer; + union package *package = base_package; + + package += package_environment(package, + var_to_env(&info->var, info)); + + gif_write(&base_package->gif, package - base_package); + } else + fb_err(info, "Failed to write GS environment, GIF is busy\n"); +} + /** * ps2fb_cb_get_tilemax - maximum number of tiles * @info: frame buffer info object @@ -889,9 +1082,12 @@ static int ps2fb_cb_set_par(struct fb_info *info) spin_lock_irqsave(&par->lock, flags); err = ps2fb_set_par(info); - if (!err) + if (!err) { par->cb.block_count = var_to_block_count(info); + write_cb_environment(info); + } + spin_unlock_irqrestore(&par->lock, flags); if (!err && info->tileops) From patchwork Sun Sep 1 16:32:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125537 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 27285112C for ; Sun, 1 Sep 2019 16:32:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0EE1C21874 for ; Sun, 1 Sep 2019 16:32:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728621AbfIAQcH (ORCPT ); Sun, 1 Sep 2019 12:32:07 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:45322 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQcH (ORCPT ); Sun, 1 Sep 2019 12:32:07 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 0CF7E3F660 for ; Sun, 1 Sep 2019 18:32:06 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gNEEkdc4lpn4 for ; Sun, 1 Sep 2019 18:32:05 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 59CC53F63C for ; Sun, 1 Sep 2019 18:32:05 +0200 (CEST) Date: Sun, 1 Sep 2019 18:32:05 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 100/120] MIPS: PS2: FB: Clear the display buffer when changing video modes Message-ID: <00c26ac4e0edb65593fc7f3fce1f0cfbf3eac303.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org This avoids displaying leftover graphics that appear as garbage from a previous mode. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 90ddcbe27d43..e5e603db7671 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -572,6 +572,49 @@ static int ps2fb_cb_get_tilemax(struct fb_info *info) return blocks_available > 0 ? blocks_available * block_tile_count : 0; } +/** + * clear_screen - clear the displayed buffer screen + * @info: frame buffer info object + */ +static void clear_screen(struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + union package * const base_package = par->package.buffer; + union package *package = base_package; + + if (!gif_wait()) { + fb_err(info, "Failed to clear the screen, GIF is busy\n"); + return; + } + + GIF_PACKAGE_TAG(package) { + .flg = gif_reglist_mode, + .reg0 = gif_reg_prim, + .reg1 = gif_reg_rgbaq, + .reg2 = gif_reg_xyz2, + .reg3 = gif_reg_xyz2, + .nreg = 4, + .nloop = 1, + .eop = 1 + }; + GIF_PACKAGE_REG(package) { + .lo.prim = { .prim = gs_sprite }, + .hi.rgbaq = { .a = GS_ALPHA_ONE } + }; + GIF_PACKAGE_REG(package) { + .lo.xyz2 = { + .x = gs_fbcs_to_pcs(0), + .y = gs_fbcs_to_pcs(0) + }, + .hi.xyz2 = { + .x = gs_fbcs_to_pcs(info->var.xres_virtual), + .y = gs_fbcs_to_pcs(info->var.yres_virtual) + } + }; + + gif_write(&base_package->gif, package - base_package); +} + /** * bits_per_pixel_fits - does the given resolution fit the given buffer size? * @xres_virtual: virtual x resolution in pixels @@ -1086,6 +1129,8 @@ static int ps2fb_cb_set_par(struct fb_info *info) par->cb.block_count = var_to_block_count(info); write_cb_environment(info); + + clear_screen(info); } spin_unlock_irqrestore(&par->lock, flags); From patchwork Sun Sep 1 16:32:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125539 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 325CA112C for ; Sun, 1 Sep 2019 16:32:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1B221233A2 for ; Sun, 1 Sep 2019 16:32:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728949AbfIAQcT (ORCPT ); Sun, 1 Sep 2019 12:32:19 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:45352 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQcS (ORCPT ); Sun, 1 Sep 2019 12:32:18 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id ECC143F660 for ; Sun, 1 Sep 2019 18:32:16 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RKwokFvBOkQ1 for ; Sun, 1 Sep 2019 18:32:16 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 4511A3F63C for ; Sun, 1 Sep 2019 18:32:16 +0200 (CEST) Date: Sun, 1 Sep 2019 18:32:16 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 101/120] MIPS: PS2: FB: fb_setcolreg() 256 colour pseudo palette support Message-ID: <4cbbf1502c5057a573b8b74b6916eff5c3fe5d33.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Graphics Synthesizer display buffer is either 16-bit or 32-bit true colour. The font will be represented by 4-bit palette indexed texture tiles in a forthcoming change. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index e5e603db7671..c852341ec19a 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -57,6 +57,7 @@ #define DEVICE_NAME "ps2fb" +#define PALETTE_SIZE 256 #define PALETTE_BLOCK_COUNT 1 /* One block is used for the indexed colors */ #define GIF_PACKAGE_TAG(package) ((package)++)->gif.tag = (struct gif_tag) @@ -122,6 +123,8 @@ struct console_buffer { /** * struct ps2fb_par - driver specific structure * @lock: spin lock to be taken for all structure operations + * @mode: frame buffer video mode + * @pseudo_palette: pseudo palette, used for texture colouring * @cb: console buffer definition * @package: tags and datafor the GIF * @package.capacity: maximum number of GIF packages in 16-byte unit @@ -130,6 +133,9 @@ struct console_buffer { struct ps2fb_par { spinlock_t lock; + struct fb_videomode mode; + struct gs_rgba32 pseudo_palette[PALETTE_SIZE]; + struct console_buffer cb; struct { @@ -572,6 +578,44 @@ static int ps2fb_cb_get_tilemax(struct fb_info *info) return blocks_available > 0 ? blocks_available * block_tile_count : 0; } +/** + * invalidate_palette - set invalid palette indices to force update + * @par: driver specific object + * + * The background and foreground palette indices will mismatch in the next + * tile file, and thereby force a palette update. + */ +static void invalidate_palette(struct ps2fb_par *par) +{ + par->cb.bg = ~0; + par->cb.fg = ~0; +} + +static int ps2fb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info) +{ + const struct gs_rgba32 color = { + .r = red >> 8, + .g = green >> 8, + .b = blue >> 8, + .a = transp >> 8 + }; + struct ps2fb_par *par = info->par; + unsigned long flags; + + if (regno >= PALETTE_SIZE) + return -EINVAL; + + spin_lock_irqsave(&par->lock, flags); + + par->pseudo_palette[regno] = color; + invalidate_palette(par); + + spin_unlock_irqrestore(&par->lock, flags); + + return 0; +} + /** * clear_screen - clear the displayed buffer screen * @info: frame buffer info object @@ -1076,6 +1120,7 @@ static int ps2fb_set_par(struct fb_info *info) struct gs_smode1 smode1 = sp.smode1; par->mode = vm; + invalidate_palette(par); info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_TRUECOLOR; @@ -1171,6 +1216,7 @@ static int init_console_buffer(struct platform_device *pdev, { static struct fb_ops fbops = { .owner = THIS_MODULE, + .fb_setcolreg = ps2fb_setcolreg, .fb_set_par = ps2fb_cb_set_par, .fb_check_var = ps2fb_cb_check_var, }; @@ -1203,6 +1249,8 @@ static int init_console_buffer(struct platform_device *pdev, info->pixmap.blit_x = block_dimensions(GS_PSMT4_BLOCK_WIDTH, 4); info->pixmap.blit_y = block_dimensions(GS_PSMT4_BLOCK_HEIGHT, 1); + info->pseudo_palette = par->pseudo_palette; + /* 8x8 default font tile size for fb_get_tilemax */ par->cb.tile = cb_tile(8, 8); @@ -1256,6 +1304,13 @@ static int ps2fb_probe(struct platform_device *pdev) info->mode = &par->mode; + if (fb_alloc_cmap(&info->cmap, PALETTE_SIZE, 0) < 0) { + fb_err(info, "fb_alloc_cmap failed\n"); + err = -ENOMEM; + goto err_alloc_cmap; + } + fb_set_cmap(&info->cmap, info); + if (register_framebuffer(info) < 0) { fb_err(info, "register_framebuffer failed\n"); err = -EINVAL; @@ -1267,6 +1322,8 @@ static int ps2fb_probe(struct platform_device *pdev) return 0; err_register_framebuffer: + fb_dealloc_cmap(&info->cmap); +err_alloc_cmap: err_find_mode: err_init_buffer: free_page((unsigned long)par->package.buffer); From patchwork Sun Sep 1 16:32:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125541 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B80F114E5 for ; Sun, 1 Sep 2019 16:32:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8B75C233A2 for ; Sun, 1 Sep 2019 16:32:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726727AbfIAQcc (ORCPT ); Sun, 1 Sep 2019 12:32:32 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60498 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAQcc (ORCPT ); Sun, 1 Sep 2019 12:32:32 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 72C063F7B1 for ; Sun, 1 Sep 2019 18:32:29 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zqwrPKqWqulQ for ; Sun, 1 Sep 2019 18:32:28 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 922723F393 for ; Sun, 1 Sep 2019 18:32:28 +0200 (CEST) Date: Sun, 1 Sep 2019 18:32:28 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 102/120] MIPS: PS2: FB: fb_settile() with font stored as palette indexed textures Message-ID: <90396cdc31e09ab24654c428b2b25ceeeb3445d0.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Storing the font map locally in Graphics Synthesizer memory is very efficient when drawing. A 4-bit palette indexed texture is used so that both the background and foreground colours can be updated without reinstalling the font map. Before using converted data from host-to-local or local-to-local transmissions as texture or colour lookup tables for the first time, the texture buffer must be disabled with the TEXFLUSH register. The register write waits for the completion of the current drawing process, and then disables the texture data read to the texture page buffer. Any data can be written to it. A drawing process succeeding the write to the register is started after the texture page buffer is disabled[1]. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., pp. 43, 51, 55, 63, 77, 131. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 285 ++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index c852341ec19a..2f7477dc69c1 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -320,6 +320,47 @@ static u32 var_to_block_count(const struct fb_info *info) return 0; } +/** + * block_address_for_index - frame buffer block address for given block index + * @block_index: index of block to compute the address of + * @info: frame buffer info object + * + * Return: block address, or zero for unsupported pixel storage modes + */ +static u32 block_address_for_index(const u32 block_index, + const struct fb_info *info) +{ + const struct fb_var_screeninfo *var = &info->var; + const enum gs_psm psm = var_to_psm(var, info); + const u32 fbw = var_to_fbw(var); + + if (psm == gs_psm_ct16) + return gs_psm_ct16_block_address(fbw, block_index); + if (psm == gs_psm_ct32) + return gs_psm_ct32_block_address(fbw, block_index); + + fb_warn_once(info, "%s: Unsupported pixel storage format %u\n", + __func__, psm); + return 0; +} + +/** + * texture_address_for_index - frame buffer texture address for given index + * @block_index: index of block to compute the address of + * @info: frame buffer info object + * + * Return: texture address, or zero for unsupported pixel storage modes + */ +static u32 texture_address_for_index(const u32 block_index, + const struct fb_info *info) +{ + const struct ps2fb_par *par = info->par; + + return block_address_for_index( + par->cb.block_count + PALETTE_BLOCK_COUNT + block_index, + info); +} + /** * texture_least_power_of_2 - round up to a power of 2, not less than 8 * @n: integer to round up @@ -357,6 +398,34 @@ static struct cb_tile cb_tile(u32 width, u32 height) }; } +/** + * texture_for_tile - texture base pointer and texel coordinates for tile index + * @tile_index: index of tile to compute the texture for + * @info: frame buffer info object + * + * Returns texture base pointer and texel coordinates + */ +static struct tile_texture texture_for_tile(const u32 tile_index, + const struct fb_info *info) +{ + const struct ps2fb_par *par = info->par; + + const u32 texture_tile_count = + par->cb.tile.block.cols * par->cb.tile.block.rows; + const u32 block_tile = tile_index / texture_tile_count; + const u32 texture_tile = tile_index % texture_tile_count; + const u32 block_address = texture_address_for_index(block_tile, info); + + const u32 row = texture_tile / par->cb.tile.block.cols; + const u32 col = texture_tile % par->cb.tile.block.cols; + + return (struct tile_texture) { + .tbp = block_address, + .u = col * par->cb.tile.width2, + .v = row * par->cb.tile.height2 + }; +} + /** * display_buffer_size - display buffer size for a given video resolution * @@ -560,6 +629,221 @@ void write_cb_environment(struct fb_info *info) fb_err(info, "Failed to write GS environment, GIF is busy\n"); } +/** + * pixel - background or foreground pixel palette index for given coordinates + * @image: image to sample pixel from + * @x: x coordinate, relative to the top left corner + * @y: y coordinate, relative to the top left corner + * @info: frame buffer info object + * + * The background palette index is given for coordinates outside of the image. + * + * Return: background or foreground palette index + */ +static u32 pixel(const struct fb_image * const image, + const int x, const int y, struct fb_info *info) +{ + if (x < 0 || x >= image->width || + y < 0 || y >= image->height) + return image->bg_color; + + if (image->depth == 1) + return (image->data[y*((image->width + 7) >> 3) + (x >> 3)] & + (0x80 >> (x & 0x7))) ? + image->fg_color : image->bg_color; + + fb_warn_once(info, "%s: Unsupported image depth %u\n", + __func__, image->depth); + return 0; +} + +/** + * ps2fb_cb_texflush - flush texture buffer after palette or texture updates + * @info: frame buffer info object + * + * Before using converted data from host-to-local or local-to-local + * transmissions as texture or colour lookup tables for the first time, the + * texture buffer must be disabled with the TEXFLUSH register. + * + * The register write waits for the completion of the current drawing process, + * and then disables the texture data read to the texture page buffer. Any + * data can be written to it. A drawing process succeeding the write to the + * register is started after the texture page buffer is disabled. + */ +static void ps2fb_cb_texflush(struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + union package * const base_package = par->package.buffer; + union package *package = base_package; + unsigned long flags; + + if (info->state != FBINFO_STATE_RUNNING) + return; + + spin_lock_irqsave(&par->lock, flags); + + if (!gif_wait()) + goto timeout; + + GIF_PACKAGE_TAG(package) { + .flg = gif_packed_mode, + .reg0 = gif_reg_ad, + .nreg = 1, + .nloop = 1 + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_texflush + }; + + gif_write(&base_package->gif, package - base_package); + +timeout: + spin_unlock_irqrestore(&par->lock, flags); +} + +/** + * package_psmt4_texture - package PSMT4 texture tags and data for the GIF + * @package: DMA buffer to put packages in + * @image: image to copy + * @info: frame buffer info object + * + * Return: number of generated GIF packages in 16-byte unit + */ +static size_t package_psmt4_texture(union package *package, + const struct fb_image *image, struct fb_info *info) +{ + union package * const base_package = package; + const u32 width2 = texture_least_power_of_2(image->width); + const u32 height2 = texture_least_power_of_2(image->height); + const u32 texels_per_quadword = 32; /* PSMT4 are 4 bit texels */ + const u32 nloop = (width2 * height2 + texels_per_quadword - 1) / + texels_per_quadword; + u32 x, y; + + GIF_PACKAGE_TAG(package) { + .flg = gif_image_mode, + .nloop = nloop, + .eop = 1 + }; + + for (y = 0; y < height2; y++) + for (x = 0; x < width2; x += 2) { + const int p0 = pixel(image, x + 0, y, info); + const int p1 = pixel(image, x + 1, y, info); + const int i = 4*y + x/2; + + package[i/16].gif.image[i%16] = + (p1 ? 0x10 : 0) | (p0 ? 0x01 : 0); + } + + package += nloop; + + return package - base_package; +} + +/** + * write_cb_tile - write console buffer tile to the GIF + * @tile_index: index of the tile, starting from zero for the first glyph + * @image: the image of the tile to write + * @info: frame buffer info object + */ +static void write_cb_tile(const int tile_index, + const struct fb_image *image, struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + const struct tile_texture tt = texture_for_tile(tile_index, info); + union package * const base_package = par->package.buffer; + union package *package = base_package; + + if (!gif_wait()) + return; + + GIF_PACKAGE_TAG(package) { + .flg = gif_packed_mode, + .reg0 = gif_reg_ad, + .nreg = 1, + .nloop = 4 + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_bitbltbuf, + .data.bitbltbuf = { + .dpsm = gs_psm_t4, + .dbw = GS_PSMT4_BLOCK_WIDTH / 64, + .dbp = tt.tbp + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxpos, + .data.trxpos = { + .dsax = tt.u, + .dsay = tt.v + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxreg, + .data.trxreg = { + .rrw = texture_least_power_of_2(image->width), + .rrh = texture_least_power_of_2(image->height) + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxdir, + .data.trxdir = { .xdir = gs_trxdir_host_to_local } + }; + + package += package_psmt4_texture(package, image, info); + + gif_write(&base_package->gif, package - base_package); +} + +/** + * ps2fb_cb_settile - set console buffer font tiles + * @info: frame buffer info object + * @map: font map use as tiles +*/ +static void ps2fb_cb_settile(struct fb_info *info, struct fb_tilemap *map) +{ + const u32 glyph_size = ALIGN(map->width, 8) * map->height / 8; + struct ps2fb_par *par = info->par; + const u8 *font = map->data; + int i; + + if (!font) + return; /* FIXME: Why is fb_settile called with a NULL font? */ + + if (info->state != FBINFO_STATE_RUNNING) + return; + + if (map->width > GS_PSMT4_BLOCK_WIDTH || + map->height > GS_PSMT4_BLOCK_HEIGHT || + map->depth != 1) { + fb_err(info, "Unsupported font parameters: " + "width %d height %d depth %d length %d\n", + map->width, map->height, map->depth, map->length); + return; + } + + par->cb.tile = cb_tile(map->width, map->height); + + for (i = 0; i < map->length; i++) { + const struct fb_image image = { + .width = map->width, + .height = map->height, + .fg_color = 1, + .bg_color = 0, + .depth = 1, + .data = &font[i * glyph_size], + }; + unsigned long flags; + + spin_lock_irqsave(&par->lock, flags); + write_cb_tile(i, &image, info); + spin_unlock_irqrestore(&par->lock, flags); + } + + ps2fb_cb_texflush(info); +} + /** * ps2fb_cb_get_tilemax - maximum number of tiles * @info: frame buffer info object @@ -1222,6 +1506,7 @@ static int init_console_buffer(struct platform_device *pdev, }; static struct fb_tile_ops tileops = { + .fb_settile = ps2fb_cb_settile, .fb_get_tilemax = ps2fb_cb_get_tilemax }; From patchwork Sun Sep 1 16:32:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125543 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 71E1714E5 for ; Sun, 1 Sep 2019 16:32:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 502B8233A2 for ; Sun, 1 Sep 2019 16:32:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728943AbfIAQcv (ORCPT ); Sun, 1 Sep 2019 12:32:51 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:45418 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAQcv (ORCPT ); Sun, 1 Sep 2019 12:32:51 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id A0A523F65F for ; Sun, 1 Sep 2019 18:32:48 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id r_GcrGYSR0c3 for ; Sun, 1 Sep 2019 18:32:47 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id E4EBF3F63C for ; Sun, 1 Sep 2019 18:32:47 +0200 (CEST) Date: Sun, 1 Sep 2019 18:32:47 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 103/120] MIPS: PS2: FB: Hardware accelerated fb_tilecopy() support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org In local-to-local BITBLTBUF transmissions, the following restrictions to the TRXREG register width field apply depending on the pixel storage mode[1]: - multiple of 2: PSMCT32, PSMZ32 - multiple of 4: PSMCT16, PSMCT16S, PSMZ16, PSMZ16S - multiple of 8: PSMCT24, PSMZ24, PSMT8, PSMT8H, PSMT4, PSMT4HL, PSMT4HH References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 76. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 148 ++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 2f7477dc69c1..2123686af013 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -426,6 +426,33 @@ static struct tile_texture texture_for_tile(const u32 tile_index, }; } +/** + * valid_bitbltbuf_width - is the BITBLTBUF width valid? + * @width: width in pixels to check + * @psm: pixel storage mode + * + * In local-to-local BITBLTBUF transmissions, the following restrictions + * to the TRXREG register width field apply depending on the pixel storage + * mode[1]: + * + * - multiple of 2: PSMCT32, PSMZ32 + * - multiple of 4: PSMCT16, PSMCT16S, PSMZ16, PSMZ16S + * - multiple of 8: PSMCT24, PSMZ24, PSMT8, PSMT8H, PSMT4, PSMT4HL, PSMT4HH + * + * Return: %true if the given width is valid, otherwise %false + */ +static bool valid_bitbltbuf_width(int width, enum gs_psm psm) +{ + if (width < 1) + return false; + if (psm == gs_psm_ct32 && (width & 1) != 0) + return false; + if (psm == gs_psm_ct16 && (width & 3) != 0) + return false; + + return true; +} + /** * display_buffer_size - display buffer size for a given video resolution * @@ -629,6 +656,103 @@ void write_cb_environment(struct fb_info *info) fb_err(info, "Failed to write GS environment, GIF is busy\n"); } +/** + * package_copyarea - package copy area tags and data for the GIF + * @package: DMA buffer to put packages in + * @area: area to copy + * @info: frame buffer info object + * + * Return: number of generated GIF packages in 16-byte unit + */ +static size_t package_copyarea(union package *package, + const struct fb_copyarea *area, const struct fb_info *info) +{ + const struct fb_var_screeninfo *var = &info->var; + union package * const base_package = package; + const int psm = var_to_psm(var, info); + const int fbw = var_to_fbw(var); + + GIF_PACKAGE_TAG(package) { + .flg = gif_packed_mode, + .reg0 = gif_reg_ad, + .nreg = 1, + .nloop = 4 + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_bitbltbuf, + .data.bitbltbuf = { + .spsm = psm, .sbw = fbw, + .dpsm = psm, .dbw = fbw + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxpos, + .data.trxpos = { + .ssax = area->sx, .ssay = area->sy, + .dsax = area->dx, .dsay = area->dy, + .dir = area->dy < area->sy || + (area->dy == area->sy && area->dx < area->sx) ? + gs_trxpos_dir_ul_lr : gs_trxpos_dir_lr_ul + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxreg, + .data.trxreg = { + .rrw = area->width, + .rrh = area->height + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxdir, + .data.trxdir = { .xdir = gs_trxdir_local_to_local } + }; + + return package - base_package; +} + +/** + * ps2fb_cb_copyarea - copy console buffer area + * @area: area to copy + * @info: frame buffer info object + */ +void ps2fb_cb_copyarea(const struct fb_copyarea *area, struct fb_info *info) +{ + const enum gs_psm psm = var_to_psm(&info->var, info); + struct ps2fb_par *par = info->par; + unsigned long flags; + + if (info->state != FBINFO_STATE_RUNNING) + return; + if (area->width < 1 || area->height < 1) + return; + if (!valid_bitbltbuf_width(area->width, psm)) { + /* + * Some widths are not entirely supported with BITBLTBUF, + * but there will be more graphical glitches by refusing + * to proceed. Besides, info->pixmap.blit_x says that + * they are unsupported so unless someone wants to have + * odd fonts we will not end up here anyway. Warn once + * here for the protocol. + */ + fb_warn_once(info, "%s: " + "Unsupported width %u for pixel storage format %u\n", + __func__, area->width, psm); + } + + spin_lock_irqsave(&par->lock, flags); + + if (gif_wait()) { + union package * const base_package = par->package.buffer; + union package *package = base_package; + + package += package_copyarea(package, area, info); + + gif_write(&base_package->gif, package - base_package); + } + + spin_unlock_irqrestore(&par->lock, flags); +} + /** * pixel - background or foreground pixel palette index for given coordinates * @image: image to sample pixel from @@ -844,6 +968,28 @@ static void ps2fb_cb_settile(struct fb_info *info, struct fb_tilemap *map) ps2fb_cb_texflush(info); } +/** + * ps2fb_cb_tilecopy - copy console buffer tiles + * @info: frame buffer info object + * @area: tile area to copy + */ +static void ps2fb_cb_tilecopy(struct fb_info *info, struct fb_tilearea *area) +{ + const struct ps2fb_par *par = info->par; + const u32 tw = par->cb.tile.width; + const u32 th = par->cb.tile.height; + const struct fb_copyarea a = { + .dx = tw * area->dx, + .dy = th * area->dy, + .width = tw * area->width, + .height = th * area->height, + .sx = tw * area->sx, + .sy = th * area->sy + }; + + ps2fb_cb_copyarea(&a, info); +} + /** * ps2fb_cb_get_tilemax - maximum number of tiles * @info: frame buffer info object @@ -1507,6 +1653,7 @@ static int init_console_buffer(struct platform_device *pdev, static struct fb_tile_ops tileops = { .fb_settile = ps2fb_cb_settile, + .fb_tilecopy = ps2fb_cb_tilecopy, .fb_get_tilemax = ps2fb_cb_get_tilemax }; @@ -1522,6 +1669,7 @@ static int init_console_buffer(struct platform_device *pdev, info->fbops = &fbops; info->flags = FBINFO_DEFAULT | + FBINFO_HWACCEL_COPYAREA | FBINFO_READS_FAST; info->flags |= FBINFO_MISC_TILEBLITTING; From patchwork Sun Sep 1 16:33:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125545 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5ECEC112C for ; Sun, 1 Sep 2019 16:33:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3C9CD233A2 for ; Sun, 1 Sep 2019 16:33:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728952AbfIAQdL (ORCPT ); Sun, 1 Sep 2019 12:33:11 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60574 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAQdK (ORCPT ); Sun, 1 Sep 2019 12:33:10 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 7A4543F752 for ; Sun, 1 Sep 2019 18:33:07 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gQtH_eozbrRP for ; Sun, 1 Sep 2019 18:33:06 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 94EF33F393 for ; Sun, 1 Sep 2019 18:33:06 +0200 (CEST) Date: Sun, 1 Sep 2019 18:33:06 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 104/120] MIPS: PS2: FB: Hardware accelerated fb_tilefill() support Message-ID: <0b481fd149279130e4fa0cfbed92f74c66cd5489.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The local Graphics Synthesizer palette is updated if either the background or the foreground colour index have changed. A single BITBLTBUF operation performs the tile fill. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 233 ++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 2123686af013..c00c0f6a4a49 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -252,6 +252,23 @@ static const struct fb_videomode standard_modes[] = { FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA } }; +/** + * console_pseudo_palette - Graphics Synthesizer RGBA for a palette index + * @regno: pseudo palette index number + * @par: driver specific object + * + * Return: RGBA colour object for the Graphics Synthesizer + */ +static struct gs_rgbaq console_pseudo_palette(const u32 regno, + const struct ps2fb_par *par) +{ + const struct gs_rgba32 c = regno < PALETTE_SIZE ? + par->pseudo_palette[regno] : (struct gs_rgba32) { }; + const u32 a = (c.a + 1) / 2; /* 0x80 = GS_ALPHA_ONE = 1.0 */ + + return (struct gs_rgbaq) { .r = c.r, .g = c.g, .b = c.b, .a = a }; +} + /** * var_to_fbw - frame buffer width for a given virtual x resolution * @var: screen info object to compute FBW for @@ -344,6 +361,19 @@ static u32 block_address_for_index(const u32 block_index, return 0; } +/** + * color_base_pointer - colour base pointer + * @info: frame buffer info object + * + * Return: block index of the colour palette, that follows the display buffer + */ +static u32 color_base_pointer(const struct fb_info *info) +{ + const struct ps2fb_par *par = info->par; + + return par->cb.block_count; +} + /** * texture_address_for_index - frame buffer texture address for given index * @block_index: index of block to compute the address of @@ -968,6 +998,187 @@ static void ps2fb_cb_settile(struct fb_info *info, struct fb_tilemap *map) ps2fb_cb_texflush(info); } +/** + * package_palette - package palette tags and data for the GIF + * @package: DMA buffer to put packages in + * @bg: background colour palette index + * @fg: foreground colour palette index + * @info: frame buffer info object + * + * Return: number of generated GIF packages in 16-byte unit + */ +static size_t package_palette(union package *package, + const int bg, const int fg, struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + union package * const base_package = par->package.buffer; + const struct gs_rgbaq bg_rgbaq = console_pseudo_palette(bg, par); + const struct gs_rgbaq fg_rgbaq = console_pseudo_palette(fg, par); + + GIF_PACKAGE_TAG(package) { + .flg = gif_packed_mode, + .reg0 = gif_reg_ad, + .nreg = 1, + .nloop = 4 + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_bitbltbuf, + .data.bitbltbuf = { + .dpsm = gs_psm_ct32, + .dbw = 1, /* Palette is one block wide */ + .dbp = color_base_pointer(info) + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxpos, + .data.trxpos = { + .dsax = 0, + .dsay = 0 + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxreg, + .data.trxreg = { + .rrw = 2, /* Background and foreground color */ + .rrh = 1 + } + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_trxdir, + .data.trxdir = { .xdir = gs_trxdir_host_to_local } + }; + + GIF_PACKAGE_TAG(package) { + .flg = gif_image_mode, + .nloop = 1, + .eop = 1 + }; + package->gif.rgba32[0] = (struct gs_rgba32) { + .r = bg_rgbaq.r, + .g = bg_rgbaq.g, + .b = bg_rgbaq.b, + .a = bg_rgbaq.a + }; + package->gif.rgba32[1] = (struct gs_rgba32) { + .r = fg_rgbaq.r, + .g = fg_rgbaq.g, + .b = fg_rgbaq.b, + .a = fg_rgbaq.a + }; + package++; + + GIF_PACKAGE_TAG(package) { + .flg = gif_packed_mode, + .reg0 = gif_reg_ad, + .nreg = 1, + .nloop = 1 + }; + GIF_PACKAGE_AD(package) { + .addr = gs_addr_texflush + }; + + return package - base_package; +} + +/** + * write_tilefill - write console buffer tile fill operation to the GIF + * @info: frame buffer info object + * @rect: rectangle to fill with tiles + */ +static void write_tilefill(struct fb_info *info, const struct fb_tilerect rect) +{ + const struct tile_texture tt = texture_for_tile(rect.index, info); + struct ps2fb_par *par = info->par; + union package * const base_package = par->package.buffer; + union package *package = base_package; + const u32 cbp = color_base_pointer(info); + const u32 dsax = par->cb.tile.width * rect.sx; + const u32 dsay = par->cb.tile.height * rect.sy; + const u32 rrw = par->cb.tile.width * rect.width; + const u32 rrh = par->cb.tile.height * rect.height; + const u32 tw2 = par->cb.tile.width2; + const u32 th2 = par->cb.tile.height2; + + /* Determine whether background or foreground color needs update. */ + const bool cld = (par->cb.bg != rect.bg || par->cb.fg != rect.fg); + + if (!gif_wait()) + return; + + if (cld) { + package += package_palette(package, rect.bg, rect.fg, info); + par->cb.bg = rect.bg; + par->cb.fg = rect.fg; + } + + GIF_PACKAGE_TAG(package) { + .flg = gif_reglist_mode, + .reg0 = gif_reg_prim, + .reg1 = gif_reg_nop, + .reg2 = gif_reg_tex0_1, + .reg3 = gif_reg_clamp_1, + .reg4 = gif_reg_uv, + .reg5 = gif_reg_xyz2, + .reg6 = gif_reg_uv, + .reg7 = gif_reg_xyz2, + .nreg = 8, + .nloop = 1, + .eop = 1 + }; + GIF_PACKAGE_REG(package) { + .lo.prim = { + .prim = gs_sprite, + .tme = gs_texturing_on, + .fst = gs_texturing_uv + } + }; + GIF_PACKAGE_REG(package) { + .lo.tex0 = { + .tbp0 = tt.tbp, + .tbw = GS_PSMT4_BLOCK_WIDTH / 64, + .psm = gs_psm_t4, + .tw = 5, /* 2^5 = 32 texels wide PSMT4 block */ + .th = 4, /* 2^4 = 16 texels high PSMT4 block */ + .tcc = gs_tcc_rgba, + .tfx = gs_tfx_decal, + .cbp = cbp, + .cpsm = gs_psm_ct32, + .csm = gs_csm1, + .cld = cld ? 1 : 0 + }, + .hi.clamp_1 = { + .wms = gs_clamp_region_repeat, + .wmt = gs_clamp_region_repeat, + .minu = tw2 - 1, /* Mask, tw is always a power of 2 */ + .maxu = tt.u, + .minv = th2 - 1, /* Mask, th is always a power of 2 */ + .maxv = tt.v + } + }; + GIF_PACKAGE_REG(package) { + .lo.uv = { + .u = gs_pxcs_to_tcs(tt.u), + .v = gs_pxcs_to_tcs(tt.v) + }, + .hi.xyz2 = { + .x = gs_fbcs_to_pcs(dsax), + .y = gs_fbcs_to_pcs(dsay) + } + }; + GIF_PACKAGE_REG(package) { + .lo.uv = { + .u = gs_pxcs_to_tcs(tt.u + rrw), + .v = gs_pxcs_to_tcs(tt.v + rrh) + }, + .hi.xyz2 = { + .x = gs_fbcs_to_pcs(dsax + rrw), + .y = gs_fbcs_to_pcs(dsay + rrh) + } + }; + + gif_write(&base_package->gif, package - base_package); +} + /** * ps2fb_cb_tilecopy - copy console buffer tiles * @info: frame buffer info object @@ -990,6 +1201,26 @@ static void ps2fb_cb_tilecopy(struct fb_info *info, struct fb_tilearea *area) ps2fb_cb_copyarea(&a, info); } +/** + * ps2fb_cb_tilefill - tile fill operation + * @info: frame buffer info object + * @rect: rectangle to fill with tiles + */ +static void ps2fb_cb_tilefill(struct fb_info *info, struct fb_tilerect *rect) +{ + struct ps2fb_par *par = info->par; + unsigned long flags; + + if (info->state != FBINFO_STATE_RUNNING) + return; + + spin_lock_irqsave(&par->lock, flags); + + write_tilefill(info, *rect); + + spin_unlock_irqrestore(&par->lock, flags); +} + /** * ps2fb_cb_get_tilemax - maximum number of tiles * @info: frame buffer info object @@ -1654,6 +1885,7 @@ static int init_console_buffer(struct platform_device *pdev, static struct fb_tile_ops tileops = { .fb_settile = ps2fb_cb_settile, .fb_tilecopy = ps2fb_cb_tilecopy, + .fb_tilefill = ps2fb_cb_tilefill, .fb_get_tilemax = ps2fb_cb_get_tilemax }; @@ -1670,6 +1902,7 @@ static int init_console_buffer(struct platform_device *pdev, info->fbops = &fbops; info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT | FBINFO_READS_FAST; info->flags |= FBINFO_MISC_TILEBLITTING; From patchwork Sun Sep 1 16:33:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125547 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9073F112C for ; Sun, 1 Sep 2019 16:33:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 776C821874 for ; Sun, 1 Sep 2019 16:33:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728955AbfIAQdV (ORCPT ); Sun, 1 Sep 2019 12:33:21 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60586 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAQdV (ORCPT ); Sun, 1 Sep 2019 12:33:21 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 686243F752 for ; Sun, 1 Sep 2019 18:33:19 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RaQV-ZdkojwV for ; Sun, 1 Sep 2019 18:33:18 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id BAABE3F393 for ; Sun, 1 Sep 2019 18:33:18 +0200 (CEST) Date: Sun, 1 Sep 2019 18:33:18 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 105/120] MIPS: PS2: FB: Simplified fb_tileblit() support Message-ID: <7963a4604eb75027d7a628a34b6c963c500fb9d7.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The tile blit operation is implemented as a series of tile fill operations. This is very simple but not particularly efficient. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index c00c0f6a4a49..c63215efd07d 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -1221,6 +1221,43 @@ static void ps2fb_cb_tilefill(struct fb_info *info, struct fb_tilerect *rect) spin_unlock_irqrestore(&par->lock, flags); } +/** + * ps2fb_cb_tileblit - tile bit block transfer operation + * @info: frame buffer info object + * @blit: tile bit block to transfer + */ +static void ps2fb_cb_tileblit(struct fb_info *info, struct fb_tileblit *blit) +{ + struct ps2fb_par *par = info->par; + int i = 0, dx, dy; + + if (info->state != FBINFO_STATE_RUNNING) + return; + + /* + * Note: This could be done faster, possibly often as a single + * set of GIF packages. + */ + for (dy = 0; i < blit->length && dy < blit->height; dy++) + for (dx = 0; i < blit->length && dx < blit->width; dx++, i++) { + unsigned long flags; + + spin_lock_irqsave(&par->lock, flags); + + write_tilefill(info, (struct fb_tilerect) { + .sx = blit->sx + dx, + .sy = blit->sy + dy, + .width = 1, + .height = 1, + .index = blit->indices[i], + .fg = blit->fg, + .bg = blit->bg + }); + + spin_unlock_irqrestore(&par->lock, flags); + } +} + /** * ps2fb_cb_get_tilemax - maximum number of tiles * @info: frame buffer info object @@ -1886,6 +1923,7 @@ static int init_console_buffer(struct platform_device *pdev, .fb_settile = ps2fb_cb_settile, .fb_tilecopy = ps2fb_cb_tilecopy, .fb_tilefill = ps2fb_cb_tilefill, + .fb_tileblit = ps2fb_cb_tileblit, .fb_get_tilemax = ps2fb_cb_get_tilemax }; @@ -1903,6 +1941,7 @@ static int init_console_buffer(struct platform_device *pdev, info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | + FBINFO_HWACCEL_IMAGEBLIT | FBINFO_READS_FAST; info->flags |= FBINFO_MISC_TILEBLITTING; From patchwork Sun Sep 1 16:33:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125549 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 01E8214E5 for ; Sun, 1 Sep 2019 16:33:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DF023233A2 for ; Sun, 1 Sep 2019 16:33:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728961AbfIAQdj (ORCPT ); Sun, 1 Sep 2019 12:33:39 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60602 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAQdj (ORCPT ); Sun, 1 Sep 2019 12:33:39 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id CDFF93F752 for ; Sun, 1 Sep 2019 18:33:37 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ShLec1K07khl for ; Sun, 1 Sep 2019 18:33:37 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 29A223F393 for ; Sun, 1 Sep 2019 18:33:37 +0200 (CEST) Date: Sun, 1 Sep 2019 18:33:36 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 106/120] MIPS: PS2: FB: fb_tilecursor() placeholder Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Drawing the cursor seems to require composition such as xor, which is not possible here. If the character under the cursor was known, a simple change of foreground and background colours could be implemented to achieve the same effect. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index c63215efd07d..bbf9e1d9e3c1 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -1258,6 +1258,17 @@ static void ps2fb_cb_tileblit(struct fb_info *info, struct fb_tileblit *blit) } } +static void ps2fb_cb_tilecursor(struct fb_info *info, + struct fb_tilecursor *cursor) +{ + /* + * FIXME: Drawing the cursor seems to require composition such as + * xor, which is not possible here. If the character under the + * cursor was known, a simple change of foreground and background + * colors could be implemented to achieve the same effect. + */ +} + /** * ps2fb_cb_get_tilemax - maximum number of tiles * @info: frame buffer info object @@ -1924,6 +1935,7 @@ static int init_console_buffer(struct platform_device *pdev, .fb_tilecopy = ps2fb_cb_tilecopy, .fb_tilefill = ps2fb_cb_tilefill, .fb_tileblit = ps2fb_cb_tileblit, + .fb_tilecursor = ps2fb_cb_tilecursor, .fb_get_tilemax = ps2fb_cb_get_tilemax }; From patchwork Sun Sep 1 16:33:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125551 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8613414E5 for ; Sun, 1 Sep 2019 16:33:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6C411233A2 for ; Sun, 1 Sep 2019 16:33:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728929AbfIAQd6 (ORCPT ); Sun, 1 Sep 2019 12:33:58 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60620 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725954AbfIAQd6 (ORCPT ); Sun, 1 Sep 2019 12:33:58 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 7F0273F752 for ; Sun, 1 Sep 2019 18:33:55 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EZYa50pzo7sJ for ; Sun, 1 Sep 2019 18:33:54 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id B17CB3F393 for ; Sun, 1 Sep 2019 18:33:54 +0200 (CEST) Date: Sun, 1 Sep 2019 18:33:54 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 107/120] MIPS: PS2: FB: Hardware accelerated fb_pan_display() support Message-ID: <51eeb04f97611833d2be487dae2da2a040d4aa13.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org XPAN, YPAN and YWRAP are hardware accelerated. YWRAP is implemented using the two independent rectangular area read output circuits of the Graphics Synthesizer[1]. The DISPLAY1 register outputs the upper part and the DISPLAY2 register outputs the lower part. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 82. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 120 ++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index bbf9e1d9e3c1..73fc1fd3f4eb 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -1368,6 +1368,109 @@ static void clear_screen(struct fb_info *info) gif_write(&base_package->gif, package - base_package); } +/** + * write_cb_pan_display - write console buffer pan operation to the GIF + * @var: screen info object + * @info: frame buffer info object + * + * XPAN, YPAN and YWRAP are hardware accelerated. YWRAP is implemented using + * the two independent rectangular area read output circuits of the Graphics + * Synthesizer. The DISPLAY1 register outputs the upper part and the DISPLAY2 + * register outputs the lower part. + */ +static void write_cb_pan_display(const struct fb_var_screeninfo *var, + const struct fb_info *info) +{ + const struct gs_display display = gs_read_display1(); + const int psm = var_to_psm(var, info); + const int fbw = var_to_fbw(var); + const int yo = var->yoffset % var->yres_virtual; + const int dh1 = min_t(int, var->yres_virtual - yo, var->yres); + const int dh2 = var->yres - dh1; + + GS_WRITE_DISPLAY1( + .dh = dh1 - 1, + .dw = display.dw, + .magv = display.magv, + .magh = display.magh, + .dy = display.dy, + .dx = display.dx, + ); + + GS_WRITE_DISPLAY2( + .dh = dh2 - 1, + .dw = display.dw, + .magv = display.magv, + .magh = display.magh, + .dy = display.dy + dh1, + .dx = display.dx, + ); + + GS_WRITE_DISPFB1( + .fbw = fbw, + .psm = psm, + .dbx = var->xoffset, + .dby = yo + ); + + GS_WRITE_DISPFB2( + .fbw = fbw, + .psm = psm, + .dbx = var->xoffset, + .dby = 0, + ); + + GS_WRITE_PMODE( + .en1 = 1, + .en2 = dh2 ? 1 : 0, + .crtmd = 1 + ); +} + +/** + * changed_cb_pan_display - is display panning needed? + * @var: screen info object + * + * Panning is undefined until the DISPFB1 register has been set. + * + * Return: %true if the horizontal or vertical panning is needed, otherwise + * %false + */ +static bool changed_cb_pan_display(const struct fb_var_screeninfo *var) +{ + if (gs_valid_dispfb1()) { + const struct gs_dispfb dspfb12 = gs_read_dispfb1(); + const int yo = var->yoffset % var->yres_virtual; + + return dspfb12.dbx != var->xoffset || dspfb12.dby != yo; + } + + return false; /* DISPFB1 is incomparable before video mode is set. */ +} + +/** + * ps2fb_cb_pan_display - pan the display + * @var: screen info object + * @info: frame buffer info object + * + * Return: 0 on success, otherwise a negative error number + */ +static int ps2fb_cb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + unsigned long flags; + + spin_lock_irqsave(&par->lock, flags); + + if (changed_cb_pan_display(var)) + write_cb_pan_display(var, info); + + spin_unlock_irqrestore(&par->lock, flags); + + return 0; +} + /** * bits_per_pixel_fits - does the given resolution fit the given buffer size? * @xres_virtual: virtual x resolution in pixels @@ -1438,8 +1541,11 @@ static int ps2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->yres < 1 || 2048 < var->yres) return -EINVAL; - var->xres_virtual = var->xres; - var->yres_virtual = var->yres; + /* Check virtual resolution. */ + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; var->xoffset = 0; var->yoffset = 0; @@ -1833,8 +1939,8 @@ static int ps2fb_set_par(struct fb_info *info) info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.xpanstep = 0; - info->fix.ypanstep = 0; + info->fix.xpanstep = var->xres_virtual > var->xres ? 1 : 0; + info->fix.ypanstep = var->yres_virtual > var->yres ? 1 : 0; info->fix.ywrapstep = 1; info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; @@ -1883,6 +1989,7 @@ static int ps2fb_cb_set_par(struct fb_info *info) par->cb.block_count = var_to_block_count(info); write_cb_environment(info); + write_cb_pan_display(&info->var, info); clear_screen(info); } @@ -1928,6 +2035,7 @@ static int init_console_buffer(struct platform_device *pdev, .fb_setcolreg = ps2fb_setcolreg, .fb_set_par = ps2fb_cb_set_par, .fb_check_var = ps2fb_cb_check_var, + .fb_pan_display = ps2fb_cb_pan_display, }; static struct fb_tile_ops tileops = { @@ -1954,6 +2062,10 @@ static int init_console_buffer(struct platform_device *pdev, FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_XPAN | + FBINFO_HWACCEL_YPAN | + FBINFO_HWACCEL_YWRAP | + FBINFO_PARTIAL_PAN_OK | FBINFO_READS_FAST; info->flags |= FBINFO_MISC_TILEBLITTING; From patchwork Sun Sep 1 16:34:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125553 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 494E4112C for ; Sun, 1 Sep 2019 16:34:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 31663233A2 for ; Sun, 1 Sep 2019 16:34:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728967AbfIAQeK (ORCPT ); Sun, 1 Sep 2019 12:34:10 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33348 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728966AbfIAQeJ (ORCPT ); Sun, 1 Sep 2019 12:34:09 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 065F03FC34 for ; Sun, 1 Sep 2019 18:34:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JI6C7rzUa2rr for ; Sun, 1 Sep 2019 18:34:07 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 58BF83FBF6 for ; Sun, 1 Sep 2019 18:34:07 +0200 (CEST) Date: Sun, 1 Sep 2019 18:34:07 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 108/120] MIPS: PS2: FB: fb_blank() display power management signaling (DPMS) Message-ID: <2ac54422f1a639be35b049f1608e0f5f7d3e19dd.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The Graphics Synthesizer implements four DPMS levels: on, standby, suspend and off. The level is set with the SMODE2 register DPMS field[1]. References: [1] "GS User's Manual", version 6.0, Sony Computer Entertainment Inc., p. 157. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 73fc1fd3f4eb..92957797045f 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -2004,6 +2004,38 @@ static int ps2fb_cb_set_par(struct fb_info *info) return err; } +/** + * ps2fb_blank - VESA display power management signaling (DPMS) + * @blank: frame buffer blanking level + * @info: frame buffer info object + * + * Return: 0 on success, otherwise a negative error number + */ +static int ps2fb_blank(int blank, struct fb_info *info) +{ + struct ps2fb_par *par = info->par; + struct gs_smode2 smode2; + unsigned long flags; + + if (!gs_valid_smode2()) + return -EIO; /* Blanking before video mode is set. */ + + spin_lock_irqsave(&par->lock, flags); + + smode2 = gs_read_smode2(); + + smode2.dpms = blank == FB_BLANK_POWERDOWN ? gs_dpms_off : + blank == FB_BLANK_NORMAL ? gs_dpms_standby : + blank == FB_BLANK_VSYNC_SUSPEND ? gs_dpms_suspend : + blank == FB_BLANK_HSYNC_SUSPEND ? gs_dpms_suspend : + gs_dpms_on; + gs_write_smode2(smode2); + + spin_unlock_irqrestore(&par->lock, flags); + + return 0; +} + static u32 block_dimensions(u32 dim, u32 alignment) { u32 mask = 0; @@ -2032,6 +2064,7 @@ static int init_console_buffer(struct platform_device *pdev, { static struct fb_ops fbops = { .owner = THIS_MODULE, + .fb_blank = ps2fb_blank, .fb_setcolreg = ps2fb_setcolreg, .fb_set_par = ps2fb_cb_set_par, .fb_check_var = ps2fb_cb_check_var, From patchwork Sun Sep 1 16:34:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125555 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3B714112C for ; Sun, 1 Sep 2019 16:34:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 23F8B233A2 for ; Sun, 1 Sep 2019 16:34:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728496AbfIAQeU (ORCPT ); Sun, 1 Sep 2019 12:34:20 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:45524 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQeT (ORCPT ); Sun, 1 Sep 2019 12:34:19 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 257473F63C for ; Sun, 1 Sep 2019 18:34:18 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fT08sWrPsi-E for ; Sun, 1 Sep 2019 18:34:17 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 9C4403F58C for ; Sun, 1 Sep 2019 18:34:17 +0200 (CEST) Date: Sun, 1 Sep 2019 18:34:17 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 109/120] MIPS: PS2: FB: Disable GIF DMA completion interrupts Message-ID: <7c32a4bbe85b15f94958070991dc9a6ad77d4e1c.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The GIF asserts DMA completion interrupts that are uninteresting because DMA operations are fast enough to busy-wait for. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 92957797045f..d7a54108f37e 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -2173,6 +2173,12 @@ static int ps2fb_probe(struct platform_device *pdev) } fb_set_cmap(&info->cmap, info); + /* + * The GIF asserts DMA completion interrupts that are uninteresting + * because DMA operations are fast enough to busy-wait for. + */ + disable_irq(IRQ_DMAC_GIF); + if (register_framebuffer(info) < 0) { fb_err(info, "register_framebuffer failed\n"); err = -EINVAL; @@ -2184,6 +2190,7 @@ static int ps2fb_probe(struct platform_device *pdev) return 0; err_register_framebuffer: + enable_irq(IRQ_DMAC_GIF); fb_dealloc_cmap(&info->cmap); err_alloc_cmap: err_find_mode: @@ -2212,6 +2219,7 @@ static int ps2fb_remove(struct platform_device *pdev) fb_err(info, "Failed to complete GIF DMA transfer\n"); err = -EBUSY; } + enable_irq(IRQ_DMAC_GIF); free_page((unsigned long)par->package.buffer); return err; From patchwork Sun Sep 1 16:34:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125557 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 028DF14E5 for ; Sun, 1 Sep 2019 16:34:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DE141233A2 for ; Sun, 1 Sep 2019 16:34:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728753AbfIAQeg (ORCPT ); Sun, 1 Sep 2019 12:34:36 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33412 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQeg (ORCPT ); Sun, 1 Sep 2019 12:34:36 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 796033FC34 for ; Sun, 1 Sep 2019 18:34:35 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1PvGBYYg-fTG for ; Sun, 1 Sep 2019 18:34:34 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id D5C793FBF6 for ; Sun, 1 Sep 2019 18:34:34 +0200 (CEST) Date: Sun, 1 Sep 2019 18:34:34 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 110/120] MIPS: PS2: FB: PAL and NTSC grayscale support Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Construct luminance[1] Y' = 0.299R' + 0.587G' + 0.114B' with fixed-point integer arithmetic, where 77 + 150 + 29 = 256. References: [1] "Studio encoding parameters of digital television for standard 4:3 and wide-screen 16:9 aspect ratios", recommendation ITU-R BT.601-7, International Telecommunication Union - Radiocommunication sector, p. 2. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index d7a54108f37e..4975f9adb5d0 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -125,6 +125,7 @@ struct console_buffer { * @lock: spin lock to be taken for all structure operations * @mode: frame buffer video mode * @pseudo_palette: pseudo palette, used for texture colouring + * @grayscale: perform grayscale colour conversion if %true * @cb: console buffer definition * @package: tags and datafor the GIF * @package.capacity: maximum number of GIF packages in 16-byte unit @@ -135,6 +136,7 @@ struct ps2fb_par { struct fb_videomode mode; struct gs_rgba32 pseudo_palette[PALETTE_SIZE]; + bool grayscale; struct console_buffer cb; @@ -266,6 +268,16 @@ static struct gs_rgbaq console_pseudo_palette(const u32 regno, par->pseudo_palette[regno] : (struct gs_rgba32) { }; const u32 a = (c.a + 1) / 2; /* 0x80 = GS_ALPHA_ONE = 1.0 */ + if (par->grayscale) { + /* + * Construct luminance Y' = 0.299R' + 0.587G' + 0.114B' with + * fixed-point integer arithmetic, where 77 + 150 + 29 = 256. + */ + const u32 y = (c.r*77 + c.g*150 + c.b*29) >> 8; + + return (struct gs_rgbaq) { .r = y, .g = y, .b = y, .a = a }; + } + return (struct gs_rgbaq) { .r = c.r, .g = c.g, .b = c.b, .a = a }; } @@ -1935,6 +1947,7 @@ static int ps2fb_set_par(struct fb_info *info) struct gs_smode1 smode1 = sp.smode1; par->mode = vm; + par->grayscale = (var->grayscale == 1); invalidate_palette(par); info->fix.type = FB_TYPE_PACKED_PIXELS; From patchwork Sun Sep 1 16:34:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125559 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 92B3D14E5 for ; Sun, 1 Sep 2019 16:34:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7B91D233A2 for ; Sun, 1 Sep 2019 16:34:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728616AbfIAQev (ORCPT ); Sun, 1 Sep 2019 12:34:51 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:45570 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbfIAQev (ORCPT ); Sun, 1 Sep 2019 12:34:51 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id D7DD93F63C for ; Sun, 1 Sep 2019 18:34:48 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Xm8D0X-kbY-w for ; Sun, 1 Sep 2019 18:34:48 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 237AC3F58C for ; Sun, 1 Sep 2019 18:34:48 +0200 (CEST) Date: Sun, 1 Sep 2019 18:34:47 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 111/120] MIPS: PS2: FB: Analogue display mode adjustment module parameter Message-ID: <1dec8a1cc49058ccc7d2973f6eeee0888012fc2a.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Analogue devices are frequently a few pixels off. Use this mode_margin option to make necessary device dependent adjustments to the built-in modes. Signed-off-by: Fredrik Noring --- drivers/video/fbdev/ps2fb.c | 58 ++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/ps2fb.c b/drivers/video/fbdev/ps2fb.c index 4975f9adb5d0..121c271aa826 100644 --- a/drivers/video/fbdev/ps2fb.c +++ b/drivers/video/fbdev/ps2fb.c @@ -67,6 +67,7 @@ /* Module parameters */ static char *mode_option; +static char *mode_margin = ""; union package { union gif_data gif; @@ -1923,9 +1924,45 @@ static struct gs_sync_param vm_to_sp(const struct fb_videomode *vm) return vm_to_sp_for_synch_gen(vm, gs_synch_gen_for_vck(vm->pixclock)); } +/** + * struct margin_adjustment - move display screen relative given display mode + * @dx: positive, negative or zero horizontal x adjustment in pixels + * @dy: positive, negative or zero vertical y adjustment in pixels + */ +struct margin_adjustment { + int dx; + int dy; +}; + +static struct margin_adjustment margin_adjustment(struct fb_info *info) +{ + char sx = '+', sy = '+'; + int dx = 0, dy = 0; + + bool valid = + sscanf(mode_margin, "%c%d%c%d", &sx, &dx, &sy, &dy) == 4 && + (sx == '-' || sx == '+') && + (sy == '-' || sy == '+'); + + if (sx == '-') + dx = -dx; + if (sy == '-') + dy = -dy; + + if (mode_margin[0] != '\0') + fb_info(info, "Mode margin \"%s\" with %d dx %d dy is %s\n", + mode_margin, dx, dy, valid ? "valid" : "invalid"); + + if (!valid) + return (struct margin_adjustment) { }; + + return (struct margin_adjustment) { .dx = dx, .dy = dy }; +} + static int ps2fb_set_par(struct fb_info *info) { struct ps2fb_par *par = info->par; + const struct margin_adjustment margin_adjust = margin_adjustment(info); const struct fb_var_screeninfo *var = &info->var; const struct fb_videomode *mm = fb_match_mode(var, &info->modelist); const struct fb_videomode vm = (struct fb_videomode) { @@ -1933,10 +1970,10 @@ static int ps2fb_set_par(struct fb_info *info) .xres = var->xres, .yres = var->yres, .pixclock = var->pixclock, - .left_margin = var->left_margin, - .right_margin = var->right_margin, - .upper_margin = var->upper_margin, - .lower_margin = var->lower_margin, + .left_margin = var->left_margin + margin_adjust.dx, + .right_margin = var->right_margin - margin_adjust.dx, + .upper_margin = var->upper_margin + margin_adjust.dy, + .lower_margin = var->lower_margin - margin_adjust.dy, .hsync_len = var->hsync_len, .vsync_len = var->vsync_len, .sync = var->sync, @@ -2198,6 +2235,9 @@ static int ps2fb_probe(struct platform_device *pdev) goto err_register_framebuffer; } + /* Clear the mode adjustment after setting the initial mode. */ + mode_margin = ""; + platform_set_drvdata(pdev, info); return 0; @@ -2269,6 +2309,8 @@ static int __init ps2fb_init(void) mode_option = &this_opt[12]; else if ('0' <= this_opt[0] && this_opt[0] <= '9') mode_option = this_opt; + else if (!strncmp(this_opt, "mode_margin:", 12)) + mode_margin = &this_opt[12]; else pr_warn(DEVICE_NAME ": Unrecognized option \"%s\"\n", this_opt); @@ -2307,6 +2349,14 @@ module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Specify initial video mode as \"x[-][@]\""); +/* + * Analogue devices are frequently a few pixels off. Use this mode_margin + * option to make necessary device dependent adjustments to the built-in modes. + */ +module_param(mode_margin, charp, 0); +MODULE_PARM_DESC(mode_margin, + "Adjust initial video mode margin as \"<-|+><-|+>\""); + MODULE_DESCRIPTION("PlayStation 2 frame buffer driver"); MODULE_AUTHOR("Fredrik Noring"); MODULE_LICENSE("GPL"); From patchwork Sun Sep 1 16:35:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125561 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 21AE1112C for ; Sun, 1 Sep 2019 16:35:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F39F9233A2 for ; Sun, 1 Sep 2019 16:35:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728570AbfIAQfM (ORCPT ); Sun, 1 Sep 2019 12:35:12 -0400 Received: from pio-pvt-msa3.bahnhof.se ([79.136.2.42]:45588 "EHLO pio-pvt-msa3.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQfM (ORCPT ); Sun, 1 Sep 2019 12:35:12 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id 56DBF3F63C for ; Sun, 1 Sep 2019 18:35:10 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J-TUNSvu7yIo for ; Sun, 1 Sep 2019 18:35:09 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id 84DF83F58C for ; Sun, 1 Sep 2019 18:35:09 +0200 (CEST) Date: Sun, 1 Sep 2019 18:35:09 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 112/120] USB: OHCI: Support for the PlayStation 2 Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Support the USB 1.1 OHCI for the PlayStation 2. The controller is connected to the input/output processor (IOP) which is separate from the main (R5900) processor that runs the kernel. IOP DMA memory and OHCI registers are mapped into kernel address space. OHCI interrupts are asserted on the IOP and forwarded to the kernel by an IOP IRQ relay module. Signed-off-by: Fredrik Noring --- drivers/usb/host/Kconfig | 8 ++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-ps2.c | 245 ++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+) create mode 100644 drivers/usb/host/ohci-ps2.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 40b5de597112..5b3b138006cd 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -552,6 +552,14 @@ config USB_OHCI_EXYNOS help Enable support for the Samsung Exynos SOC's on-chip OHCI controller. +config USB_OHCI_HCD_PS2 + tristate "OHCI support for the Sony PlayStation 2" + depends on SONY_PS2 + select GENERIC_ALLOCATOR + default y + help + Enable support for the Sony PlayStation 2 OHCI controller. + config USB_CNS3XXX_OHCI bool "Cavium CNS3XXX OHCI Module (DEPRECATED)" depends on ARCH_CNS3XXX diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 84514f71ae44..9ed4e0fa6657 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_USB_OHCI_HCD_S3C2410) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_PXA27X) += ohci-pxa27x.o obj-$(CONFIG_USB_OHCI_HCD_DAVINCI) += ohci-da8xx.o +obj-$(CONFIG_USB_OHCI_HCD_PS2) += ohci-ps2.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o diff --git a/drivers/usb/host/ohci-ps2.c b/drivers/usb/host/ohci-ps2.c new file mode 100644 index 000000000000..a1d446313c13 --- /dev/null +++ b/drivers/usb/host/ohci-ps2.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 USB 1.1 OHCI host controller (HCD) + * + * Copyright (C) 2017 Jürgen Urban + * Copyright (C) 2018 Fredrik Noring + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ohci.h" + +#define DRIVER_DESC "PlayStation 2 USB OHCI host controller" +#define DRV_NAME "ohci-ps2" + +/* Size allocated from IOP heap (maximum size of DMA memory). */ +#define DMA_BUFFER_SIZE (256 * 1024) + +#define hcd_to_priv(hcd) ((struct ps2_hcd *)(hcd_to_ohci(hcd)->priv)) + +/** + * struct ps2_hcd - private device driver structure + * @iop_dma_addr: input/output processor (IOP) DMA buffer address + */ +struct ps2_hcd { + dma_addr_t iop_dma_addr; +}; + +static struct hc_driver __read_mostly ohci_ps2_hc_driver; + +static void ohci_ps2_enable(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + + ohci_writel(ohci, 1, &ohci->regs->roothub.portstatus[11]); +} + +static void ohci_ps2_disable(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + + ohci_writel(ohci, 0, &ohci->regs->roothub.portstatus[11]); +} + +static void ohci_ps2_start_hc(struct usb_hcd *hcd) +{ + iop_set_dma_dpcr2(IOP_DMA_DPCR2_OHCI); + + outw(1, IOP_OHCI_BASE + 0x80); +} + +static void ohci_ps2_stop_hc(struct usb_hcd *hcd) +{ + iop_clr_dma_dpcr2(IOP_DMA_DPCR2_OHCI); +} + +static int ohci_ps2_reset(struct usb_hcd *hcd) +{ + int err; + + ohci_ps2_start_hc(hcd); + + err = ohci_setup(hcd); + if (err) { + ohci_ps2_stop_hc(hcd); + return err; + } + + ohci_ps2_enable(hcd); + + return 0; +} + +static int iopheap_alloc_dma_buffer(struct platform_device *pdev, size_t size) +{ + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct ps2_hcd *ps2priv = hcd_to_priv(hcd); + int err; + + ps2priv->iop_dma_addr = iop_alloc(size); + if (!ps2priv->iop_dma_addr) { + dev_err(dev, "iop_alloc failed\n"); + return -ENOMEM; + } + + err = usb_hcd_setup_local_mem(hcd, + iop_bus_to_phys(ps2priv->iop_dma_addr), + ps2priv->iop_dma_addr, size); + if (err) { + dev_err(dev, "usb_hcd_setup_local_mem failed with %d\n", err); + iop_free(ps2priv->iop_dma_addr); + ps2priv->iop_dma_addr = 0; + return err; + } + + return 0; +} + +static void iopheap_free_dma_buffer(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct ps2_hcd *ps2priv = hcd_to_priv(hcd); + + if (!ps2priv->iop_dma_addr) + return; + + iop_free(ps2priv->iop_dma_addr); + ps2priv->iop_dma_addr = 0; +} + +static int ohci_hcd_ps2_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *regs; + struct usb_hcd *hcd; + struct ps2_hcd *ps2priv; + int irq; + int err; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "platform_get_irq failed\n"); + return irq; + } + + hcd = usb_create_hcd(&ohci_ps2_hc_driver, dev, dev_name(dev)); + if (!hcd) { + dev_err(dev, "usb_create_hcd failed\n"); + return -ENOMEM; + } + + ps2priv = hcd_to_priv(hcd); + memset(ps2priv, 0, sizeof(*ps2priv)); + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(dev, "platform_get_resource 0 failed\n"); + err = -ENOENT; + goto err_platform; + } + + hcd->rsrc_start = regs->start; + hcd->rsrc_len = resource_size(regs); + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (IS_ERR(hcd->regs)) { + err = PTR_ERR(hcd->regs); + dev_err(dev, "ioremap failed with %d\n", err); + goto err_ioremap; + } + + err = iopheap_alloc_dma_buffer(pdev, DMA_BUFFER_SIZE); + if (err) + goto err_alloc_dma_buffer; + + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) { + dev_err(dev, "usb_add_hcd failed with %d\n", err); + goto err_add_hcd; + } + + err = device_wakeup_enable(hcd->self.controller); + if (err) { + dev_err(dev, "device_wakeup_enable failed with %d\n", err); + goto err_wakeup; + } + + return 0; + +err_wakeup: + usb_remove_hcd(hcd); +err_add_hcd: + iopheap_free_dma_buffer(pdev); +err_alloc_dma_buffer: + iounmap(hcd->regs); +err_ioremap: +err_platform: + usb_put_hcd(hcd); + return err; +} + +static int ohci_hcd_ps2_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + usb_remove_hcd(hcd); + + ohci_ps2_disable(hcd); + ohci_ps2_stop_hc(hcd); + + iopheap_free_dma_buffer(pdev); + iounmap(hcd->regs); + + usb_put_hcd(hcd); + + return 0; +} + +static struct platform_driver ohci_hcd_ps2_driver = { + .probe = ohci_hcd_ps2_probe, + .remove = ohci_hcd_ps2_remove, + .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = DRV_NAME, + }, +}; + +static const struct ohci_driver_overrides ps2_overrides __initconst = { + .reset = ohci_ps2_reset, + .product_desc = DRIVER_DESC, + .extra_priv_size = sizeof(struct ps2_hcd), +}; + +static int __init ohci_ps2_init(void) +{ + if (usb_disabled()) { + pr_err(DRV_NAME ": Initialization failed: USB is disabled\n"); + return -ENODEV; + } + + ohci_init_driver(&ohci_ps2_hc_driver, &ps2_overrides); + + return platform_driver_register(&ohci_hcd_ps2_driver); +} +module_init(ohci_ps2_init); + +static void __exit ohci_ps2_exit(void) +{ + platform_driver_unregister(&ohci_hcd_ps2_driver); +} +module_exit(ohci_ps2_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Fredrik Noring"); +MODULE_AUTHOR("Jürgen Urban"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); From patchwork Sun Sep 1 16:35:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125563 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 55D93112C for ; Sun, 1 Sep 2019 16:35:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3DC9321874 for ; Sun, 1 Sep 2019 16:35:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728496AbfIAQfV (ORCPT ); Sun, 1 Sep 2019 12:35:21 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60740 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQfU (ORCPT ); Sun, 1 Sep 2019 12:35:20 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 3A9533F752 for ; Sun, 1 Sep 2019 18:35:19 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fkrI8xPP0jOh for ; Sun, 1 Sep 2019 18:35:18 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 9BFB53F393 for ; Sun, 1 Sep 2019 18:35:18 +0200 (CEST) Date: Sun, 1 Sep 2019 18:35:18 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 113/120] USB: OHCI: OHCI_INTR_MIE workaround for freeze on the PlayStation 2 Message-ID: <786e161e0e7f52ca14e635e3f1225e76b5f7833b.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org OHCI_INTR_MIE needs to be disabled, most likely due to a hardware bug. Without it, reading a large amount of data (> 1 GB) from a mass storage device results in a freeze. Signed-off-by: Fredrik Noring --- drivers/usb/host/ohci-ps2.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/usb/host/ohci-ps2.c b/drivers/usb/host/ohci-ps2.c index a1d446313c13..cdbcbe5ff34e 100644 --- a/drivers/usb/host/ohci-ps2.c +++ b/drivers/usb/host/ohci-ps2.c @@ -35,6 +35,7 @@ struct ps2_hcd { }; static struct hc_driver __read_mostly ohci_ps2_hc_driver; +static irqreturn_t (*ohci_irq)(struct usb_hcd *hcd); static void ohci_ps2_enable(struct usb_hcd *hcd) { @@ -79,6 +80,21 @@ static int ohci_ps2_reset(struct usb_hcd *hcd) return 0; } +static irqreturn_t ohci_ps2_irq(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + struct ohci_regs __iomem *regs = ohci->regs; + + /* + * OHCI_INTR_MIE needs to be disabled, most likely due to a + * hardware bug. Without it, reading a large amount of data + * (> 1 GB) from a mass storage device results in a freeze. + */ + ohci_writel(ohci, OHCI_INTR_MIE, ®s->intrdisable); + + return ohci_irq(hcd); /* Call normal IRQ handler. */ +} + static int iopheap_alloc_dma_buffer(struct platform_device *pdev, size_t size) { struct device *dev = &pdev->dev; @@ -228,6 +244,9 @@ static int __init ohci_ps2_init(void) ohci_init_driver(&ohci_ps2_hc_driver, &ps2_overrides); + ohci_irq = ohci_ps2_hc_driver.irq; /* Save normal IRQ handler. */ + ohci_ps2_hc_driver.irq = ohci_ps2_irq; /* Install IRQ workaround. */ + return platform_driver_register(&ohci_hcd_ps2_driver); } module_init(ohci_ps2_init); From patchwork Sun Sep 1 16:35:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125565 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8913C17E0 for ; Sun, 1 Sep 2019 16:35:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7320E233A2 for ; Sun, 1 Sep 2019 16:35:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728616AbfIAQfd (ORCPT ); Sun, 1 Sep 2019 12:35:33 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60758 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQfd (ORCPT ); Sun, 1 Sep 2019 12:35:33 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 962F23F752 for ; Sun, 1 Sep 2019 18:35:31 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qzbCWvMS0Tdg for ; Sun, 1 Sep 2019 18:35:30 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id E67533F393 for ; Sun, 1 Sep 2019 18:35:30 +0200 (CEST) Date: Sun, 1 Sep 2019 18:35:30 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 114/120] MIPS: PS2: Workaround for unexpected uLaunchELF CP0 Status user mode Message-ID: <05de0a34e2f6e28a611838c615c562bb12e3f680.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org The PlayStation 2 uLaunchELF program, used as a kernel boot loader, starts in user mode with CP0 access enabled (CP0 Status 0x70030c11). This is unexpected and causes a boot freeze. Signed-off-by: Fredrik Noring --- arch/mips/boot/compressed/head.S | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/mips/boot/compressed/head.S b/arch/mips/boot/compressed/head.S index e3dc831e2616..6dc728d6ebea 100644 --- a/arch/mips/boot/compressed/head.S +++ b/arch/mips/boot/compressed/head.S @@ -24,6 +24,15 @@ start: move s2, a2 move s3, a3 +#ifdef CONFIG_CPU_R5900 + # The PlayStation 2 uLaunchELF starts in user mode with + # CP0 access enabled (CP0 Status 0x70030c11), which is + # unexpected. This is corrected here: + li k0, 0x30010000 + mtc0 k0, $12 + sync.p +#endif /* CONFIG_CPU_R5900 */ + /* Clear BSS */ PTR_LA a0, _edata - 4 PTR_LA a2, _end From patchwork Sun Sep 1 16:35:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125567 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C71AE14E5 for ; Sun, 1 Sep 2019 16:35:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AFBCA233A2 for ; Sun, 1 Sep 2019 16:35:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728570AbfIAQfs (ORCPT ); Sun, 1 Sep 2019 12:35:48 -0400 Received: from pio-pvt-msa1.bahnhof.se ([79.136.2.40]:60782 "EHLO pio-pvt-msa1.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQfs (ORCPT ); Sun, 1 Sep 2019 12:35:48 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTP id 17EC13F752 for ; Sun, 1 Sep 2019 18:35:46 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa1.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa1.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pR8RBlBRDiXy for ; Sun, 1 Sep 2019 18:35:45 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa1.bahnhof.se (Postfix) with ESMTPA id 6225D3F393 for ; Sun, 1 Sep 2019 18:35:45 +0200 (CEST) Date: Sun, 1 Sep 2019 18:35:45 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 115/120] MIPS: PS2: Define initial PlayStation 2 devices Message-ID: <42b5ac5dc3f4ea9f5ac57f4abc142bdd52a3d494.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Only the real-time clock (RTC), the input/output processor (IOP), USB OHCI and the Graphics Synthesizer are supported at the moment. Signed-off-by: Fredrik Noring --- arch/mips/ps2/Makefile | 1 + arch/mips/ps2/devices.c | 98 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 arch/mips/ps2/devices.c diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index 6f671112fbcb..925952a83625 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -1,3 +1,4 @@ +obj-y += devices.o obj-y += dmac-irq.o obj-y += identify.o obj-y += intc-irq.o diff --git a/arch/mips/ps2/devices.c b/arch/mips/ps2/devices.c new file mode 100644 index 000000000000..67aa1b158e29 --- /dev/null +++ b/arch/mips/ps2/devices.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 devices + * + * Copyright (C) 2019 Fredrik Noring + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct resource iop_resources[] = { + [0] = { + .name = "IOP RAM", + .start = IOP_RAM_BASE, + .end = IOP_RAM_BASE + IOP_RAM_SIZE - 1, + .flags = IORESOURCE_MEM, /* 2 MiB IOP RAM */ + }, +}; + +static struct platform_device iop_device = { + .name = "iop", + .id = -1, + .num_resources = ARRAY_SIZE(iop_resources), + .resource = iop_resources, +}; + +static struct resource ohci_resources[] = { /* FIXME: Subresource to IOP */ + [0] = { + .name = "USB OHCI", + .start = IOP_OHCI_BASE, + .end = IOP_OHCI_BASE + 0xff, + .flags = IORESOURCE_MEM, /* 256 byte HCCA. */ + }, + [1] = { + .start = IRQ_IOP_USB, + .end = IRQ_IOP_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ohci_device = { + .name = "ohci-ps2", + .id = -1, + .num_resources = ARRAY_SIZE(ohci_resources), + .resource = ohci_resources, +}; + +static struct resource gs_resources[] = { + [0] = { + .name = "Graphics Synthesizer", + .start = GS_REG_BASE, + .end = GS_REG_BASE + 0x1ffffff, + .flags = IORESOURCE_MEM, /* FIXME: IORESOURCE_REG? */ + }, + [1] = { + .start = IRQ_DMAC_GIF, + .end = IRQ_DMAC_GIF, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_GS_SIGNAL, + .end = IRQ_GS_EXVSYNC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device gs_device = { + .name = "gs", + .id = -1, + .num_resources = ARRAY_SIZE(gs_resources), + .resource = gs_resources, +}; + +static struct platform_device rtc_device = { + .name = "rtc-ps2", + .id = -1, +}; + +static struct platform_device *ps2_platform_devices[] __initdata = { + &iop_device, + &ohci_device, + &gs_device, + &rtc_device, +}; + +static int __init ps2_device_setup(void) +{ + return platform_add_devices(ps2_platform_devices, + ARRAY_SIZE(ps2_platform_devices)); +} +device_initcall(ps2_device_setup); From patchwork Sun Sep 1 16:35:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125569 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8D9A8112C for ; Sun, 1 Sep 2019 16:35:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7608E233A2 for ; Sun, 1 Sep 2019 16:35:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728621AbfIAQf7 (ORCPT ); Sun, 1 Sep 2019 12:35:59 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33524 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQf7 (ORCPT ); Sun, 1 Sep 2019 12:35:59 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 20FC83FC34 for ; Sun, 1 Sep 2019 18:35:58 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id U4-H2k3DEMNQ for ; Sun, 1 Sep 2019 18:35:57 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 69FD73FBF6 for ; Sun, 1 Sep 2019 18:35:57 +0200 (CEST) Date: Sun, 1 Sep 2019 18:35:57 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 116/120] MIPS: PS2: Define workarounds related to the PlayStation 2 Message-ID: <5b2bda95c84d149338fcf3d6d583063f33f173fc.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/include/asm/mach-ps2/war.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/war.h diff --git a/arch/mips/include/asm/mach-ps2/war.h b/arch/mips/include/asm/mach-ps2/war.h new file mode 100644 index 000000000000..f2ebbd31e9ee --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/war.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 workarounds + * + * Copyright (C) 2010-2013 Jürgen Urban + */ + +#ifndef __ASM_MIPS_MACH_PS2_WAR_H +#define __ASM_MIPS_MACH_PS2_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_PS2_WAR_H */ From patchwork Sun Sep 1 16:36:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125571 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 284DA14E5 for ; Sun, 1 Sep 2019 16:36:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1075B233A2 for ; Sun, 1 Sep 2019 16:36:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728654AbfIAQgJ (ORCPT ); Sun, 1 Sep 2019 12:36:09 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33538 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQgJ (ORCPT ); Sun, 1 Sep 2019 12:36:09 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 0DCF33FC34 for ; Sun, 1 Sep 2019 18:36:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Rc02y_NILEGS for ; Sun, 1 Sep 2019 18:36:07 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 72DB73FBF6 for ; Sun, 1 Sep 2019 18:36:07 +0200 (CEST) Date: Sun, 1 Sep 2019 18:36:07 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 117/120] MIPS: PS2: Define R5900 feature overrides Message-ID: <656c226804a2a6a93c4da13b8a95da2c60e905d7.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- .../asm/mach-ps2/cpu-feature-overrides.h | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 arch/mips/include/asm/mach-ps2/cpu-feature-overrides.h diff --git a/arch/mips/include/asm/mach-ps2/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ps2/cpu-feature-overrides.h new file mode 100644 index 000000000000..e9b218e657f7 --- /dev/null +++ b/arch/mips/include/asm/mach-ps2/cpu-feature-overrides.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 CPU features + * + * Copyright (C) 2010-2013 Jürgen Urban + */ + +#ifndef __ASM_MACH_PS2_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_PS2_CPU_FEATURE_OVERRIDES_H + +#define cpu_has_llsc 0 +#define cpu_has_4k_cache 1 +#define cpu_has_divec 1 +#define cpu_has_4kex 1 +#define cpu_has_counter 1 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_mcheck 0 +#define cpu_has_nofpuex 1 +#define cpu_has_mipsmt 0 +#define cpu_has_vce 0 +#define cpu_has_dsp 0 +#define cpu_has_userlocal 0 +#define cpu_has_64bit_addresses 0 +#define cpu_has_64bit 1 /* FIXME */ +#define cpu_has_64bit_gp_regs 0 /* FIXME */ +#define cpu_has_64bit_zero_reg 0 /* FIXME */ +#define cpu_vmbits 31 +#define cpu_has_clo_clz 0 +#define cpu_has_ejtag 0 +#define cpu_has_ic_fills_f_dc 0 +#define cpu_has_inclusive_pcaches 0 +#define cpu_has_fpu 0 /* FIXME */ + +#endif /* __ASM_MACH_PS2_CPU_FEATURE_OVERRIDES_H */ From patchwork Sun Sep 1 16:36:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125573 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9354C14E5 for ; Sun, 1 Sep 2019 16:36:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7C388233A2 for ; Sun, 1 Sep 2019 16:36:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728672AbfIAQgW (ORCPT ); Sun, 1 Sep 2019 12:36:22 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33552 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726727AbfIAQgW (ORCPT ); Sun, 1 Sep 2019 12:36:22 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 3BDA33FBF6 for ; Sun, 1 Sep 2019 18:36:20 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Pa0a8E4AXjw2 for ; Sun, 1 Sep 2019 18:36:19 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 9B3583F52B for ; Sun, 1 Sep 2019 18:36:19 +0200 (CEST) Date: Sun, 1 Sep 2019 18:36:19 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 118/120] MIPS: PS2: Define the PlayStation 2 platform Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/Kbuild.platforms | 1 + arch/mips/ps2/Makefile | 1 + arch/mips/ps2/Platform | 7 +++++++ arch/mips/ps2/prom.c | 18 ++++++++++++++++++ 4 files changed, 27 insertions(+) create mode 100644 arch/mips/ps2/Platform create mode 100644 arch/mips/ps2/prom.c diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 0de839882106..84be263f44d2 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -24,6 +24,7 @@ platforms += netlogic platforms += paravirt platforms += pic32 platforms += pistachio +platforms += ps2 platforms += pmcs-msp71xx platforms += pnx833x platforms += ralink diff --git a/arch/mips/ps2/Makefile b/arch/mips/ps2/Makefile index 925952a83625..dbc1bdbac2a8 100644 --- a/arch/mips/ps2/Makefile +++ b/arch/mips/ps2/Makefile @@ -4,6 +4,7 @@ obj-y += identify.o obj-y += intc-irq.o obj-y += irq.o obj-y += memory.o +obj-y += prom.o obj-y += reboot.o obj-y += rom.o obj-m += rom-sysfs.o diff --git a/arch/mips/ps2/Platform b/arch/mips/ps2/Platform new file mode 100644 index 000000000000..5e9695f86b99 --- /dev/null +++ b/arch/mips/ps2/Platform @@ -0,0 +1,7 @@ +# +# PlayStation 2 +# +platform-$(CONFIG_SONY_PS2) += ps2/ +cflags-$(CONFIG_SONY_PS2) += -I$(srctree)/arch/mips/include/asm/mach-ps2 +load-$(CONFIG_SONY_PS2) += 0x80010000 +zload-$(CONFIG_SONY_PS2) += 0x00800000 diff --git a/arch/mips/ps2/prom.c b/arch/mips/ps2/prom.c new file mode 100644 index 000000000000..f4d594c4457e --- /dev/null +++ b/arch/mips/ps2/prom.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PlayStation 2 PROM handling + */ + +#include + +void prom_putchar(char c) +{ +} + +void __init prom_init(void) +{ +} + +void __init prom_free_prom_memory(void) +{ +} From patchwork Sun Sep 1 16:36:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125575 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E917112C for ; Sun, 1 Sep 2019 16:36:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 12AC721874 for ; Sun, 1 Sep 2019 16:36:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726727AbfIAQgh (ORCPT ); Sun, 1 Sep 2019 12:36:37 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33614 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728764AbfIAQgh (ORCPT ); Sun, 1 Sep 2019 12:36:37 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 3A1BC3FBF6 for ; Sun, 1 Sep 2019 18:36:36 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8EQrpcWt9muu for ; Sun, 1 Sep 2019 18:36:35 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id 8BA313F52B for ; Sun, 1 Sep 2019 18:36:35 +0200 (CEST) Date: Sun, 1 Sep 2019 18:36:35 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 119/120] MIPS: PS2: Initial support for the Sony PlayStation 2 Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring --- arch/mips/Kconfig | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 88d6c13260e1..f90af3fd31d3 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1011,6 +1011,27 @@ config MIPS_PARAVIRT help This option supports guest running under ???? +config SONY_PS2 + bool "Sony PlayStation 2" + select BOOT_ELF32 + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT + select HARDIRQS_SW_RESEND + select HAVE_PATA_PLATFORM + select IRQ_MIPS_CPU + select MIPS_L1_CACHE_SHIFT_6 + select NO_IOPORT + select SYS_HAS_CPU_R5900 + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_ZBOOT + select USB_ARCH_HAS_OHCI + select USB_OHCI_LITTLE_ENDIAN + help + This enables support for the Sony PlayStation 2. + endchoice source "arch/mips/alchemy/Kconfig" @@ -1037,6 +1058,7 @@ source "arch/mips/loongson32/Kconfig" source "arch/mips/loongson64/Kconfig" source "arch/mips/netlogic/Kconfig" source "arch/mips/paravirt/Kconfig" +source "arch/mips/ps2/Kconfig" endmenu From patchwork Sun Sep 1 16:37:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fredrik Noring X-Patchwork-Id: 11125577 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6AE2414E5 for ; Sun, 1 Sep 2019 16:37:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 52A3A233A2 for ; Sun, 1 Sep 2019 16:37:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728764AbfIAQhG (ORCPT ); Sun, 1 Sep 2019 12:37:06 -0400 Received: from pio-pvt-msa2.bahnhof.se ([79.136.2.41]:33644 "EHLO pio-pvt-msa2.bahnhof.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728763AbfIAQhG (ORCPT ); Sun, 1 Sep 2019 12:37:06 -0400 Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTP id 7E7D83FBF6 for ; Sun, 1 Sep 2019 18:37:04 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Flag: NO X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-1.899 tagged_above=-999 required=6.31 tests=[BAYES_00=-1.9, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no Received: from pio-pvt-msa2.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa2.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id MUIoWlveRTL9 for ; Sun, 1 Sep 2019 18:37:03 +0200 (CEST) Received: from localhost (h-41-252.A163.priv.bahnhof.se [46.59.41.252]) (Authenticated sender: mb547485) by pio-pvt-msa2.bahnhof.se (Postfix) with ESMTPA id DDA2B3F52B for ; Sun, 1 Sep 2019 18:37:03 +0200 (CEST) Date: Sun, 1 Sep 2019 18:37:03 +0200 From: Fredrik Noring To: linux-mips@vger.kernel.org Subject: [PATCH 120/120] MIPS: Fix name of BOOT_MEM_ROM_DATA Message-ID: <54a08fcb41b12e715529148a6bc11bcb3e2adb4d.1567326213.git.noring@nocrew.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- arch/mips/kernel/setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index ab349d2381c3..7d5bf8cb513b 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -870,14 +870,16 @@ static void __init resource_init(void) switch (boot_mem_map.map[i].type) { case BOOT_MEM_RAM: case BOOT_MEM_INIT_RAM: - case BOOT_MEM_ROM_DATA: res->name = "System RAM"; res->flags |= IORESOURCE_SYSRAM; break; + case BOOT_MEM_ROM_DATA: + res->name = "System ROM"; + break; case BOOT_MEM_RESERVED: case BOOT_MEM_NOMAP: default: - res->name = "reserved"; + res->name = "Reserved"; } request_resource(&iomem_resource, res);