1 # --- T2-COPYRIGHT-NOTE-BEGIN ---
2 # This copyright note is auto-generated by scripts/Create-CopyPatch.
4 # T2 SDE: architecture/powerpc64/package/.../0600-ps3fb-ioctls.patch
5 # Copyright (C) 2020 The T2 SDE Project
7 # More information can be found in the files COPYING and README.
9 # This patch file is dual-licensed. It is available under the license the
10 # patched project is licensed under, as long as it is an OpenSource license
11 # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
12 # of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
15 # --- T2-COPYRIGHT-NOTE-END ---
17 --- ./arch/powerpc/include/uapi/asm/ps3fb.h 2012-07-21 22:58:29.000000000 +0200
18 +++ ./arch/powerpc/include/uapi/asm/ps3fb.h 2018-01-27 14:10:55.546169979 +0100
20 #define PS3FB_IOCTL_ON _IO('r', 4) /* use IOCTL_FSEL */
21 #define PS3FB_IOCTL_OFF _IO('r', 5) /* return to normal-flip */
22 #define PS3FB_IOCTL_FSEL _IOW('r', 6, int) /* blit and flip request */
23 +#define PS3FB_IOCTL_GPU_SETUP _IO('r', 7) /* enable FIFO access */
24 +#define PS3FB_IOCTL_GPU_INFO _IOR('r', 8, int) /* get GPU info */
25 +#define PS3FB_IOCTL_GPU_ATTR _IOW('r', 9, int) /* set attribute */
27 #ifndef FBIO_WAITFORVSYNC
28 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) /* wait for vsync */
30 __u32 num_frames; /* num of frame buffers */
33 +struct ps3fb_ioctl_gpu_info {
34 + __u32 vram_size; /* size of available video memory */
35 + __u32 fifo_size; /* size of command buffer */
36 + __u32 ctrl_size; /* size of dma control registers */
37 + __u32 dinfo_size; /* size of driver info */
38 + __u32 reports_size; /* size of reports */
39 + __u32 device_size[8]; /* size of gpu devices */
42 +struct ps3fb_ioctl_gpu_attr {
43 + __u64 attr; /* attribute */
44 + __u64 p0; /* 1st parameter */
45 + __u64 p1; /* 2nd parameter */
46 + __u64 p2; /* 3rd parameter */
47 + __u64 p3; /* 4th parameter */
51 #endif /* _ASM_POWERPC_PS3FB_H_ */
53 --- linux-4.19/drivers/video/fbdev/ps3fb.c.vanilla 2019-01-20 16:56:42.125880993 +0000
54 +++ linux-4.19/drivers/video/fbdev/ps3fb.c 2019-01-20 17:28:08.129859492 +0000
57 * Copyright (C) 2006 Sony Computer Entertainment Inc.
58 * Copyright 2006, 2007 Sony Corporation
59 + * Copyright 2018-2020 René Rebe
61 * This file is based on :
68 + * Based on NV47 (Nvidia GeForce 7800 architecture)
69 + * 256 MB GDDR3 RAM at 650 MHz
70 + * 256 MB XDR DRAM is system memory!
71 + * we have 3 memory ranges
74 + * 3: fifo cmd ring buffer
75 + * DMA object handles: 0xfeed0000 RSX DDR, 0xfeed0001 targets system XDR memory
78 #include <linux/module.h>
79 #include <linux/kernel.h>
80 #include <linux/errno.h>
83 #define DEVICE_NAME "ps3fb"
85 +#define DDR_SIZE (0x0fc00000UL)
86 #define GPU_CMD_BUF_SIZE (2 * 1024 * 1024)
87 #define GPU_FB_START (64 * 1024)
88 #define GPU_IOIF (0x0d000000UL)
89 +#define GPU_CTRL_SIZE (4096)
90 #define GPU_ALIGN_UP(x) ALIGN((x), 64)
91 #define GPU_MAX_LINE_LENGTH (65536 - 64)
94 struct gpu_driver_info *dinfo;
104 u64 vblank_count; /* frame count */
105 wait_queue_head_t wait_vsync;
108 atomic_t ext_flip; /* on/off flip with vsync */
109 atomic_t f_count; /* fb_open count */
112 struct task_struct *task;
114 static struct ps3fb_priv ps3fb;
115 +static int ps3fb_gpu_major;
118 u32 pseudo_palette[16];
120 pr_debug("%s: enter\n", __func__);
122 /* copy setup program to FIFO */
124 + pr_debug("fifo start: %p len: %x curr: %p\n", fifo->start, fifo->len, fifo->curr);
125 memcpy(fifo->curr, fifo_setup_program, sizeof(fifo_setup_program));
126 fifo->curr += sizeof(fifo_setup_program) / sizeof(u32);
132 - pr_debug("%s: leave (%d)\n", __func__, retval);
133 + //pr_debug("%s: leave (%d)\n", __func__, retval);
137 @@ -1143,15 +1168,24 @@
141 - dev_dbg(info->device, "PS3FB_IOCTL_ON:\n");
143 + volatile struct gpu_fifo_ctrl *fifo_ctrl = ps3fb.fifo.ctrl;
144 + dev_dbg(info->device, "PS3FB_IOCTL_ON: %x %x\n", fifo_ctrl->put, fifo_ctrl->get);
145 atomic_inc(&ps3fb.ext_flip);
150 case PS3FB_IOCTL_OFF:
151 - dev_dbg(info->device, "PS3FB_IOCTL_OFF:\n");
153 + volatile struct gpu_fifo_ctrl *fifo_ctrl = ps3fb.fifo.ctrl;
154 + dev_dbg(info->device, "PS3FB_IOCTL_OFF: %x %x\n", fifo_ctrl->put, fifo_ctrl->get);
155 atomic_dec_if_positive(&ps3fb.ext_flip);
156 + // ReneR: re-read & sync FIFO PUT/GET here? we coudl also memset all ot NOPs?
157 + ps3fb.fifo.curr = ps3fb.fifo.start + (fifo_ctrl->put - ps3fb.fifo.ioif) / 4;
158 + dev_dbg(info->device, "PS3FB_IOCTL_OFF: synced to %x\n", ps3fb.fifo.curr);
163 case PS3FB_IOCTL_FSEL:
164 @@ -1164,6 +1198,58 @@
168 + case PS3FB_IOCTL_GPU_SETUP:
169 + dev_dbg(info->device, " PS3FB_IOCTL_GPU_SETUP\n");
170 + //ReneR: I hope we do not need this anymore?
171 + //retval = ps3fb_fifo_setup(info->device);
175 + case PS3FB_IOCTL_GPU_INFO:
178 + struct ps3fb_ioctl_gpu_info res;
180 + dev_dbg(info->device, " PS3FB_IOCTL_GPU_INFO\n");
182 + res.vram_size = ps3fb.vram_size;
183 + res.fifo_size = ps3fb.fifo.len;
184 + res.ctrl_size = ps3fb.ctrl_size;
185 + res.dinfo_size = 0; //ps3fb.dinfo_size;
187 + // this looks unused
188 + res.reports_size = 0; //ps3fb.reports_size;
189 + for (i = 0; i < 8; i++)
190 + res.device_size[i] = 0; //ps3fb.device_size[i];
192 + if (!copy_to_user(argp, &res, sizeof(res)))
197 + case PS3FB_IOCTL_GPU_ATTR:
199 + struct ps3fb_ioctl_gpu_attr arg;
201 + if (copy_from_user(&arg, argp, sizeof(arg)))
204 + dev_dbg(info->device,
205 + " PS3FB_IOCTL_GPU_ATTR(0x%lx,0x%lx,0x%lx,0x%lx,0x%lx)\n",
206 + arg.attr, arg.p0, arg.p1, arg.p2, arg.p3);
208 + retval = lv1_gpu_context_attribute(
209 + ps3fb.context_handle,
210 + arg.attr, arg.p0, arg.p1, arg.p2, arg.p3);
212 + dev_err(info->device,
213 + "lv1_gpu_context_attribute failed (%d)\n",
221 retval = -ENOIOCTLCMD;
223 @@ -1276,14 +1363,89 @@
224 .visual = FB_VISUAL_TRUECOLOR,
225 .accel = FB_ACCEL_NONE,
228 +static int ps3fb_gpu_open(struct inode *inode, struct file *filp)
233 +static int ps3fb_gpu_release(struct inode *inode, struct file *filp)
238 +static int ps3fb_gpu_mmap(struct file *filp, struct vm_area_struct *vma)
240 + unsigned int minor = iminor(filp->f_path.dentry->d_inode);
241 + unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
242 + unsigned long vsize = vma->vm_end - vma->vm_start;
243 + unsigned long physical;
244 + unsigned long psize;
246 + printk("ps3fb_mmap: %llx %p %llx\n", ps3fb.vram_lpar, ps3fb.fifo.start, ps3fb.ctrl_lpar);
250 + physical = ps3fb.vram_lpar + off;
251 + psize = ps3fb.vram_size - off;
254 + physical = ps3fb.fifo.start + off;
255 + psize = ps3fb.fifo.len - off;
257 + case 2: /* FIFO registers */
258 + physical = ps3fb.ctrl_lpar + off;
259 + psize = ps3fb.ctrl_size - off;
262 + case 3: /* driver info */
263 + physical = ps3fb.dinfo_lpar + off;
264 + psize = ps3fb.dinfo_size - off;
266 + case 4: /* reports */
267 + physical = ps3fb.reports_lpar + off;
268 + psize = ps3fb.reports_size - off;
272 + if (ps3fb.device_lpar[minor - 8]) {
273 + physical = ps3fb.device_lpar[minor - 8] + off;
274 + psize = ps3fb.device_size[minor - 8] - off;
284 + printk("ps3fb_mmap: %d %lx %lx\n", minor, physical, psize);
287 + return -EINVAL; /* spans too high */
289 + if (remap_pfn_range(vma, vma->vm_start,
290 + physical >> PAGE_SHIFT,
291 + vsize, vma->vm_page_prot))
297 +struct file_operations ps3fb_gpu_fops = {
298 + .mmap = ps3fb_gpu_mmap,
299 + .open = ps3fb_gpu_open,
300 + .release = ps3fb_gpu_release,
303 static int ps3fb_probe(struct ps3_system_bus_device *dev)
305 struct fb_info *info;
306 struct ps3fb_par *par;
309 - u64 lpar_dma_control = 0;
310 + //u64 ddr_lpar = 0;
311 + //u64 lpar_dma_control = 0;
312 u64 lpar_driver_info = 0;
313 u64 lpar_reports = 0;
314 u64 lpar_reports_size = 0;
315 @@ -1340,21 +1502,31 @@
316 ps3fb_videomemory.size = max_ps3fb_size;
319 - /* get gpu context handle */
320 - status = lv1_gpu_memory_allocate(ps3fb_videomemory.size, ps3fb_gpu_mem_size[0],
321 - ps3fb_gpu_mem_size[1], ps3fb_gpu_mem_size[2], ps3fb_gpu_mem_size[3],
322 - &ps3fb.memory_handle, &ddr_lpar);
324 - dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
327 - goto err_close_device;
328 + /* get gpu context handle */
329 + ps3fb.vram_size = DDR_SIZE; // ps3fb_videomemory.size;
330 + status = lv1_gpu_memory_allocate(ps3fb.vram_size, ps3fb_gpu_mem_size[0],
331 + ps3fb_gpu_mem_size[1], ps3fb_gpu_mem_size[2], ps3fb_gpu_mem_size[3],
332 + &ps3fb.memory_handle, &ps3fb.vram_lpar);
334 + dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
336 + goto err_close_device;
338 + dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ps3fb.vram_lpar);
340 + if (request_mem_region(ps3fb.vram_lpar, ps3fb.vram_size,
341 + "GPU DDR memory") == NULL) {
342 + dev_err(&dev->core,
343 + "%s: failed to reserve DDR video memory region: %d\n",
345 + goto err_gpu_memory_free;
347 - dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar);
349 - status = lv1_gpu_context_allocate(ps3fb.memory_handle, ps3fb_gpu_ctx_flags,
350 - &ps3fb.context_handle,
351 - &lpar_dma_control, &lpar_driver_info,
352 + ps3fb.ctrl_size = GPU_CTRL_SIZE;
354 + status = lv1_gpu_context_allocate(ps3fb.memory_handle, ps3fb_gpu_ctx_flags,
355 + &ps3fb.context_handle,
356 + &ps3fb.ctrl_lpar, &lpar_driver_info,
357 &lpar_reports, &lpar_reports_size);
360 @@ -1424,19 +1596,21 @@
364 + //ps3fb.fifo_lpar = xdr_lpar + ps3fb_videomemory.size;
365 + //ps3fb.fifo_size = GPU_CMD_BUF_SIZE;
367 dev_dbg(&dev->core, "video:%p ioif:%lx lpar:%llx size:%lx\n",
368 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
369 ps3fb_videomemory.size);
372 - ps3fb.fifo.ctrl = (void __force *)ioremap(lpar_dma_control, PAGE_SIZE);
373 + ps3fb.fifo.ctrl = (void __force *)ioremap(ps3fb.ctrl_lpar, ps3fb.ctrl_size);
374 if (!ps3fb.fifo.ctrl) {
375 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
376 goto err_context_unmap;
379 - ps3fb.fifo.start = ps3fb_videomemory.address;
380 - ps3fb.fifo.curr = ps3fb.fifo.start;
381 + ps3fb.fifo.start = ps3fb.fifo.curr = ps3fb_videomemory.address;
382 ps3fb.fifo.len = GPU_FB_START;
383 ps3fb.fifo.ioif = GPU_IOIF;
385 @@ -1509,6 +1683,21 @@
390 + status = register_chrdev(ps3fb_gpu_major, DEVICE_NAME, &ps3fb_gpu_fops);
392 + dev_err(&dev->core,
393 + "%s: failed to register GPU device with major %d (%d)\n",
394 + __func__, ps3fb_gpu_major, status);
395 + /* ReneR: if this fails continue anway, ...
396 + goto err_unregister_framebuffer; */
398 + if (ps3fb_gpu_major == 0)
399 + ps3fb_gpu_major = status;
401 + dev_info(&dev->core, "%s: using major %d for direct GPU access\n",
402 + __func__, ps3fb_gpu_major);
406 err_unregister_framebuffer:
407 @@ -1545,6 +1734,8 @@
409 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
411 + unregister_chrdev(ps3fb_gpu_major, DEVICE_NAME);
413 atomic_inc(&ps3fb.ext_flip); /* flip off */
414 ps3fb.dinfo->irq.mask = 0;