* updated maddy (0.7.1 -> 0.8.1), untested
[t2sde.git] / package / kernel / linux / 0666-ps3fb-vram.patch
blobe97d6635469285363b6919b2a7e2f563780343a5
1 # --- T2-COPYRIGHT-NOTE-BEGIN ---
2 # T2 SDE: package/*/linux/0666-ps3fb-vram.patch
3 # Copyright (C) 2021 - 2024 The T2 SDE Project
4 #
5 # This Copyright note is generated by scripts/Create-CopyPatch,
6 # more information can be found in the files COPYING and README.
7 #
8 # This patch file is dual-licensed. It is available under the license the
9 # patched project is licensed under, as long as it is an OpenSource license
10 # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
11 # of the GNU General Public License version 2 as used by the T2 SDE.
12 # --- T2-COPYRIGHT-NOTE-END ---
14 Free system memory, bandwidth and simply the code by drawing into the
15 RSX DDR frame-buffer directly. Read-back is very slow, so just don't
16 do that, and use RSX accelerated X anyway ;-)
18 Signed-off-by: Ren<C3><A9> Rebe <rene@exactcode.de>
20 --- linux-6.7/drivers/video/fbdev/Kconfig.vanilla 2024-01-21 20:44:48.495877650 +0100
21 +++ linux-6.7/drivers/video/fbdev/Kconfig 2024-01-21 21:02:49.276834557 +0100
22 @@ -1742,7 +1742,7 @@
23 config FB_PS3_DEFAULT_SIZE_M
24 int "PS3 default frame buffer size (in MiB)"
25 depends on FB_PS3
26 - default 9
27 + default 2
28 help
29 This is the default size (in MiB) of the virtual frame buffer in
30 the PS3.
31 --- linux-6.7/drivers/video/fbdev/ps3fb.c.vanilla 2024-01-07 21:18:38.000000000 +0100
32 +++ linux-6.7/drivers/video/fbdev/ps3fb.c 2024-01-21 21:21:59.889788678 +0100
33 @@ -1,6 +1,7 @@
35 * linux/drivers/video/ps3fb.c -- PS3 GPU frame buffer device
37 + * Copyright (C) 2021-2024 René Rebe <rene@exactcode.de>
38 * Copyright (C) 2006 Sony Computer Entertainment Inc.
39 * Copyright 2006, 2007 Sony Corporation
41 @@ -25,7 +26,6 @@
42 #include <linux/interrupt.h>
43 #include <linux/console.h>
44 #include <linux/ioctl.h>
45 -#include <linux/kthread.h>
46 #include <linux/freezer.h>
47 #include <linux/uaccess.h>
48 #include <linux/fb.h>
49 @@ -115,8 +115,6 @@
50 atomic_t ext_flip; /* on/off flip with vsync */
51 atomic_t f_count; /* fb_open count */
52 int is_blanked;
53 - int is_kicked;
54 - struct task_struct *task;
56 static struct ps3fb_priv ps3fb;
58 @@ -128,7 +126,6 @@
59 unsigned int height;
60 unsigned int ddr_line_length;
61 unsigned int ddr_frame_size;
62 - unsigned int xdr_frame_size;
63 unsigned int full_offset; /* start of fullscreen DDR fb */
64 unsigned int fb_offset; /* start of actual DDR fb */
65 unsigned int pan_offset;
66 @@ -438,31 +435,10 @@
67 return id;
70 -static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
71 - u64 dst_offset, u64 src_offset, u32 width,
72 - u32 height, u32 dst_line_length,
73 - u32 src_line_length)
74 +static void ps3fb_sync_image(struct device *dev, u64 frame_offset)
76 int status;
77 - u64 line_length;
79 - line_length = dst_line_length;
80 - if (src_line_length != dst_line_length)
81 - line_length |= (u64)src_line_length << 32;
83 - src_offset += GPU_FB_START;
85 - mutex_lock(&ps3_gpu_mutex);
86 - status = lv1_gpu_fb_blit(ps3fb.context_handle, dst_offset,
87 - GPU_IOIF + src_offset,
88 - L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
89 - (width << 16) | height,
90 - line_length);
91 - mutex_unlock(&ps3_gpu_mutex);
93 - if (status)
94 - dev_err(dev, "%s: lv1_gpu_fb_blit failed: %d\n", __func__,
95 - status);
96 #ifdef HEAD_A
97 status = lv1_gpu_display_flip(ps3fb.context_handle, 0, frame_offset);
98 if (status)
99 @@ -481,7 +457,7 @@
101 struct ps3fb_par *par = info->par;
102 int error = 0;
103 - u64 ddr_base, xdr_base;
104 + u64 ddr_base;
106 if (frame > par->num_frames - 1) {
107 dev_dbg(info->device, "%s: invalid frame number (%u)\n",
108 @@ -490,13 +468,9 @@
109 goto out;
112 - xdr_base = frame * par->xdr_frame_size;
113 ddr_base = frame * par->ddr_frame_size;
115 - ps3fb_sync_image(info->device, ddr_base + par->full_offset,
116 - ddr_base + par->fb_offset, xdr_base + par->pan_offset,
117 - par->width, par->height, par->ddr_line_length,
118 - info->fix.line_length);
119 + ps3fb_sync_image(info->device, ddr_base + par->full_offset);
121 out:
122 return error;
123 @@ -603,10 +577,9 @@
124 static int ps3fb_set_par(struct fb_info *info)
126 struct ps3fb_par *par = info->par;
127 - unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
128 + unsigned int mode, ddr_line_length, xdr_line_length;
129 unsigned int ddr_xoff, ddr_yoff, offset;
130 const struct fb_videomode *vmode;
131 - u64 dst;
133 mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
134 if (!mode)
135 @@ -620,10 +593,8 @@
137 par->ddr_line_length = ddr_line_length;
138 par->ddr_frame_size = vmode->yres * ddr_line_length;
139 - par->xdr_frame_size = info->var.yres_virtual * xdr_line_length;
141 - par->num_frames = info->fix.smem_len /
142 - max(par->ddr_frame_size, par->xdr_frame_size);
143 + par->num_frames = info->fix.smem_len / par->ddr_frame_size;
145 /* Keep the special bits we cannot set using fb_var_screeninfo */
146 par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
147 @@ -649,20 +620,10 @@
148 par->mode_id = par->new_mode_id;
151 - /* Clear XDR frame buffer memory */
152 + /* Clear frame buffer memory */
153 memset(info->screen_buffer, 0, info->fix.smem_len);
155 - /* Clear DDR frame buffer memory */
156 - lines = vmode->yres * par->num_frames;
157 - if (par->full_offset)
158 - lines++;
159 - maxlines = info->fix.smem_len / ddr_line_length;
160 - for (dst = 0; lines; dst += maxlines * ddr_line_length) {
161 - unsigned int l = min(lines, maxlines);
162 - ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l,
163 - ddr_line_length, ddr_line_length);
164 - lines -= l;
166 + ps3fb_sync(info, 0);
168 return 0;
170 @@ -887,25 +848,6 @@
171 return retval;
174 -static int ps3fbd(void *arg)
176 - struct fb_info *info = arg;
178 - set_freezable();
179 - while (!kthread_should_stop()) {
180 - try_to_freeze();
181 - set_current_state(TASK_INTERRUPTIBLE);
182 - if (ps3fb.is_kicked) {
183 - ps3fb.is_kicked = 0;
184 - console_lock();
185 - ps3fb_sync(info, 0); /* single buffer */
186 - console_unlock();
188 - schedule();
190 - return 0;
193 static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
195 struct device *dev = ptr;
196 @@ -923,11 +865,6 @@
197 if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) {
198 /* VSYNC */
199 ps3fb.vblank_count = head->vblank_count;
200 - if (ps3fb.task && !ps3fb.is_blanked &&
201 - !atomic_read(&ps3fb.ext_flip)) {
202 - ps3fb.is_kicked = 1;
203 - wake_up_process(ps3fb.task);
205 wake_up_interruptible(&ps3fb.wait_vsync);
208 @@ -973,9 +910,7 @@
209 u64 lpar_reports_size = 0;
210 u64 xdr_lpar;
211 struct gpu_driver_info *dinfo;
212 - void *fb_start;
213 int status;
214 - struct task_struct *task;
215 unsigned long max_ps3fb_size;
217 if (ps3fb_videomemory.size < GPU_CMD_BUF_SIZE) {
218 @@ -1025,7 +960,7 @@
221 /* get gpu context handle */
222 - status = lv1_gpu_memory_allocate(ps3fb_videomemory.size, 0, 0, 0, 0,
223 + status = lv1_gpu_memory_allocate(32*1024*1024, 0, 0, 0, 0,
224 &ps3fb.memory_handle, &ddr_lpar);
225 if (status) {
226 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
227 @@ -1133,22 +1068,14 @@
228 info->fbops = &ps3fb_ops;
229 info->fix = ps3fb_fix;
231 - /*
232 - * The GPU command buffer is at the start of video memory
233 - * As we don't use the full command buffer, we can put the actual
234 - * frame buffer at offset GPU_FB_START and save some precious XDR
235 - * memory
236 - */
237 - fb_start = ps3fb_videomemory.address + GPU_FB_START;
238 - info->screen_buffer = fb_start;
239 - info->fix.smem_start = __pa(fb_start);
240 - info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
242 - info->pseudo_palette = par->pseudo_palette;
243 - info->flags = FBINFO_VIRTFB | FBINFO_READS_FAST |
244 - FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
246 - retval = fb_alloc_cmap(&info->cmap, 256, 0);
247 + info->fix.smem_start = ddr_lpar;
248 + info->fix.smem_len = 32*1024*1024;
249 + info->screen_buffer = (char __force __iomem *)ioremap_wc(ddr_lpar, info->fix.smem_len);
251 + info->pseudo_palette = par->pseudo_palette;
252 + info->flags = FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
254 + retval = fb_alloc_cmap(&info->cmap, 256, 0);
255 if (retval < 0)
256 goto err_framebuffer_release;
258 @@ -1170,18 +1097,8 @@
260 fb_info(info, "using %u KiB of video memory\n", info->fix.smem_len >> 10);
262 - task = kthread_run(ps3fbd, info, DEVICE_NAME);
263 - if (IS_ERR(task)) {
264 - retval = PTR_ERR(task);
265 - goto err_unregister_framebuffer;
268 - ps3fb.task = task;
270 return 0;
272 -err_unregister_framebuffer:
273 - unregister_framebuffer(info);
274 err_fb_dealloc:
275 fb_dealloc_cmap(&info->cmap);
276 err_framebuffer_release:
277 @@ -1217,11 +1134,6 @@
278 atomic_inc(&ps3fb.ext_flip); /* flip off */
279 ps3fb.dinfo->irq.mask = 0;
281 - if (ps3fb.task) {
282 - struct task_struct *task = ps3fb.task;
283 - ps3fb.task = NULL;
284 - kthread_stop(task);
286 if (ps3fb.irq_no) {
287 free_irq(ps3fb.irq_no, &dev->core);
288 ps3_irq_plug_destroy(ps3fb.irq_no);
289 --- linux-6.7/drivers/video/fbdev/ps3fb.c.vanilla 2024-01-22 12:37:26.289907882 +0100
290 +++ linux-6.7/drivers/video/fbdev/ps3fb.c 2024-01-22 12:46:42.827885691 +0100
291 @@ -328,7 +328,7 @@
294 static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var,
295 - u32 *ddr_line_length, u32 *xdr_line_length)
296 + u32 *ddr_line_length)
298 unsigned int id, best_id;
299 int diff, best_diff;
300 @@ -418,13 +418,6 @@
301 var->vsync_len = vmode->vsync_len;
302 var->sync = vmode->sync;
304 - if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
305 - *xdr_line_length = GPU_ALIGN_UP(var->xres_virtual * BPP);
306 - if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
307 - *xdr_line_length = GPU_MAX_LINE_LENGTH;
308 - } else
309 - *xdr_line_length = *ddr_line_length;
311 if (vmode->sync & FB_SYNC_BROADCAST) {
312 /* Full broadcast modes have the full mode bit set */
313 if (vmode->xres == var->xres && vmode->yres == var->yres)
314 @@ -504,15 +497,15 @@
316 static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
318 - u32 xdr_line_length, ddr_line_length;
319 + u32 ddr_line_length;
320 int mode;
322 - mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
323 + mode = ps3fb_find_mode(var, &ddr_line_length);
324 if (!mode)
325 return -EINVAL;
327 /* Virtual screen */
328 - if (var->xres_virtual > xdr_line_length / BPP) {
329 + if (var->xres_virtual > ddr_line_length / BPP) {
330 dev_dbg(info->device,
331 "Horizontal virtual screen size too large\n");
332 return -EINVAL;
333 @@ -557,7 +550,7 @@
336 /* Memory limit */
337 - if (var->yres_virtual * xdr_line_length > info->fix.smem_len) {
338 + if (var->yres_virtual * ddr_line_length > info->fix.smem_len) {
339 dev_dbg(info->device, "Not enough memory\n");
340 return -ENOMEM;
342 @@ -575,11 +568,11 @@
343 static int ps3fb_set_par(struct fb_info *info)
345 struct ps3fb_par *par = info->par;
346 - unsigned int mode, ddr_line_length, xdr_line_length;
347 + unsigned int mode, ddr_line_length;
348 unsigned int ddr_xoff, ddr_yoff, offset;
349 const struct fb_videomode *vmode;
351 - mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
352 + mode = ps3fb_find_mode(&info->var, &ddr_line_length);
353 if (!mode)
354 return -EINVAL;
356 @@ -587,7 +580,7 @@
358 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
359 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
360 - info->fix.line_length = xdr_line_length;
361 + info->fix.line_length = ddr_line_length;
363 par->ddr_line_length = ddr_line_length;
364 par->ddr_frame_size = vmode->yres * ddr_line_length;
365 @@ -607,7 +600,7 @@
367 par->fb_offset = GPU_ALIGN_UP(offset);
368 par->full_offset = par->fb_offset - offset;
369 - par->pan_offset = info->var.yoffset * xdr_line_length +
370 + par->pan_offset = info->var.yoffset * ddr_line_length +
371 info->var.xoffset * BPP;
373 if (par->new_mode_id != par->mode_id) {
374 @@ -901,12 +894,11 @@
375 struct fb_info *info;
376 struct ps3fb_par *par;
377 int retval;
378 - u64 ddr_lpar = 0;
379 + u64 ddr_lpar = 0, xdr_lpar;
380 u64 lpar_dma_control = 0;
381 u64 lpar_driver_info = 0;
382 u64 lpar_reports = 0;
383 u64 lpar_reports_size = 0;
384 - u64 xdr_lpar;
385 struct gpu_driver_info *dinfo;
386 int status;
387 unsigned long max_ps3fb_size;