new file mode 100644
@@ -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 <asm/types.h>
+
+#include <uapi/asm/gif.h>
+
+#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 */
@@ -1,3 +1,4 @@
+obj-$(CONFIG_PS2_GS) += gif.o
obj-$(CONFIG_PS2_GS) += gs-irq.o
obj-$(CONFIG_PS2_GS) += gs-registers.o
new file mode 100644
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PlayStation 2 Graphics Synthesizer interface (GIF)
+ *
+ * Copyright (C) 2019 Fredrik Noring
+ */
+
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+
+#include <asm/mach-ps2/dmac.h>
+#include <asm/mach-ps2/gif.h>
+#include <asm/mach-ps2/gs.h>
+
+#include <uapi/asm/gif.h>
+#include <uapi/asm/gs.h>
+
+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");
Signed-off-by: Fredrik Noring <noring@nocrew.org> --- 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