The Graphics Synthesizer (GS) drivers
The Graphics Synthesizer (GS) frame buffer device driver drivers/video/fbdev/ps2fb.c currently operates in
-
text console mode, via the fbcon driver and its tiled API. It turned out to be a rather good fit. The GS has 4 MiB of local frame buffer video memory that is not directly accessible by the kernel due to its hardware design. No main memory is allocated for the frame buffer, which is a significant saving given that the PlayStation 2 is limited to 32 MiB of total main memory, and mmap is disabled.
The maximum practical resolution 1920×1080p at 16 bits per pixel is 4147200 bytes, which leaves 47104 bytes for a tiled font, which at 8×8 pixels and at a minimum of a 4 bits indexed texture palette is at most 1464 characters. The indexed palette makes it easy to switch colors.
struct fb_tile_opssuch asfb_tileblit,fb_fillrectandfb_copyareaare accelerated by GS hardware that is very fast for the kernel via simple DMA (GIF) GS commands. The GS has two CRT merge circuits made for picture-in-picture that are used to accelerateYWRAPin hardware, which is particularly effective for console text scrolling.Console text operations are synchronous and therefore work properly in interrupt contexts, with kernel panics, etc. This is essential for debuggability (see also #27). Various optimisation techniques, such as buffering, can possibly be even faster, but one might want to implement that as a user space console driver via some kind of /dev/gs interface (as explained below) that can do zero-copying of GS commands, etc.
See also #9 for early
printkduring booting.
It’s possible to implement a
- virtual frame buffer mode, similar to the PlayStation 3 in that the whole visible main memory frame buffer is regularly copied to the GS via DMA at vertical blank intervals. This enables mmap, which is required for frame buffer compatibility, but it is otherwise very inefficient and slow. A complete copy of the whole frame buffer is allocated in main memory and GS hardware acceleration is turned off.
An interesting variant,
- a specific Graphics Synthesizer device driver, is not yet implemented. The GS hardware is essentially a serial device that accepts a series of commands via DMA. A /dev/gs device driver could provide direct access to the GS hardware, which would be very efficient and enable most of the GS features to applications. The main drawback is that this kind of device driver is specific to the GS.
Support the Direct Rendering Manager subsystem?
@sp193, I'm attempting to document the privileged Graphics Synthesizer (GS) registers, and a few bit fields remain unclear. Would you be able to fill in some details?
Specifically, the SMODE1 register has many unknown fields marked with FIXME below. Its CMOD field has some kind of standard (VESA/HDTV) mode apart from PAL and NTSC. Is there a better name than gs_cmod_standard?
The field sizes for SRFSH RFSH and SYNCH1 HS are unknown. The HSEQ and HSVS fields of SYNCH1 are unknown too.
Are more fields symbolical (to be represented with enums) rather than numerical? This is somewhat important because symbols are used whenever appropriate to read/write registers with sysfs. For example, inspecting the PMODE register shows symbols for its fields MMOD, AMOD and SLBG, which is much more helpful than their numerical representations:
# cat /sys/devices/platform/gs/registers/pmode
en1 1
en2 0
crtmd 1
mmod circuit1
amod circuit1
slbg circuit2
alp 0
One or several bit fields can be written simultaneously, so even simple shell scripts can set any conceivable video mode configuration. For example, the SLBG field can be changed with:
# echo "slbg bgcolor" >/sys/devices/platform/gs/registers/pmode
These privileged GS registers and bit fields are at the moment partly unclear:
enum gs_smode1_cmod {
gs_cmod_standard, /* FIXME: Better name than standard? */
/* Reserved */
gs_cmod_ntsc = 2, /* NTSC broadcast */
gs_cmod_pal /* PAL broadcast */
};
enum gs_smode1_gcont {
gs_gcont_rgbyc,
gs_gcont_ycrcb
};
struct gs_smode1 {
u64 rc : 3; /* PLL reference divider */
u64 lc : 7; /* PLL loop divider */
u64 t1248 : 2; /* PLL output divider */
u64 slck : 1; /* FIXME */
u64 cmod : 2; /* Display mode (PAL, NTSC, VESA, etc.) */
u64 ex : 1; /* FIXME */
u64 prst : 1; /* PLL reset */
u64 sint : 1; /* PLL (phase-locked loop) */
u64 xpck : 1; /* FIXME */
u64 pck2 : 2; /* FIXME */
u64 spml : 4; /* FIXME */
u64 gcont : 1; /* Select RGBYC or YCrCb */
u64 phs : 1; /* HSync output */
u64 pvs : 1; /* VSync output */
u64 pehs : 1; /* FIXME */
u64 pevs : 1; /* FIXME */
u64 clksel : 2; /* FIXME */
u64 nvck : 1; /* FIXME */
u64 slck2 : 1; /* FIXME */
u64 vcksel : 2; /* FIXME */
u64 vhp : 1; /* FIXME */
u64 : 27;
};
struct gs_srfsh {
u64 rfsh : 4; /* DRAM refresh FIXME: Number of bits? */
u64 : 60;
};
struct gs_synch1 {
u64 hfp : 11; /* Horizontal front porch */
u64 hbp : 11; /* Horizontal back porch */
u64 hseq : 10; /* FIXME */
u64 hsvs : 11; /* FIXME */
u64 hs : 21; /* FIXME: Number of bits? */
};
You should refer to the Sony documentation for the meanings behind the documented registers like PMODE.
Those undocumented registers like SMODE1 were just undocumented. The most official information you can find, is from the official PS2Linux. But they only mentioned the field names. Everything else you might find on the Internet, were likely derived through experimentation. Other than PS2Linux, everything else went through the EE kernel to get video modes set up.
If you worked with analog video signals, some things like HBP might make sense - it requires domain knowledge that I do not have.
On a side note, setting up a video mode for PS2s requires the DVE to be configured. This device was totally replaced with the SCPH-75000 and later, and was always different on the T10000. On the PC CARD consoles, the access to the DVE required slightly different initialization. In all cases, the register interfaces are undocumented. You may find some code from dve_reg.S of OPL, as I updated the original version from Kernelloader to support models up to the SCPH-70000.
Thanks! Yes, PMODE is covered by the documentation; it only served as an example in using symbolic text fields with sysfs. I'm happy about how that turned out, since it's so easy and flexible to inspect and configure whatever video mode one may wish for, including all specifics (such as overlays and picture-in-picture) that the Graphics Synthesizer can do, without any ioctls. I think it will be great for applications.
I have gathered as much as I can about SMODE1, SRFSH and SYNCH1. I have also implemented conversion functions from the standard kernel video mode timings notation. For example, the standard Linux frame buffer mode for 1920×1080 at 50 Hz progressive moved 13 px to the right to is
mode "1920x1080-50"
# D: 148.500 MHz, H: 56.250 kHz, V: 50.000 Hz
geometry 1920 1080 1920 1080 16
timings 6734 148 484 36 4 88 5
bcast true
rgba 5/0,5/5,5/10,1/15
endmode
One can adjust these standard Linux frame buffer notation timings quite freely to adjust screen margins, refresh rates, etc. and the GS registers are recomputed accordingly.
You may find some code from dve_reg.S of OPL, as I updated the original version from Kernelloader to support models up to the SCPH-70000.
Thanks! What does the abbreviation DVE stand for? Are the DVE registers in dve_reg.S needed if the GS is reset? The Linux GS driver does not yet reset the GS, as it currently relies on the GS already being setup at boot. The GIF is reset, though.
It's the Digital Video Encoder. Originally a COTS device, it was eventually replaced with a Sony part. Only Sony will know what will happen if you don't do things in the right order, unfortunately. But I can tell you that it is required for proper video output. It's a reason why the "old" 576P code in GSM did not seem to work properly on some PS2 models (e.g. G/H/I/J-chassis), as GSM used to only just write to the GS priviledged registers for the 576P mode.
The configuration also involves the selection of the PLL clock input (53.9MHz for PAL, 54.0MHz for NTSC), on the F-chassis and later. They did replace the hardware differences between PAL/NTSC regions with a software switch and the DVE configuration code got longer at some point, along with the introduction of messages about a 53.9MHz/54.0MHz selection in TESTMODE. From the service manual for the GH-015 (F-chassis), the DVE gained the 54CLK_SEL input from the SSBUS Interface controller.
I've attempted a DRM/KMS driver for the ps2 a long time ago. Perhaps the info helps.
This basic DMA driver is fully functional, but breaks some legacy (ps2 specific) interfaces: https://github.com/rickgaiser/linux/commits/ps2-v3.8-dma
On top of that I tried a DRM/KMS driver, but it's in a terrible state (you'll risk damaging your ps2 if you try this branch, the crtc output is wrong): https://github.com/rickgaiser/linux/commits/ps2-v3.8-dma-drm
One can adjust these standard Linux frame buffer notation timings quite freely to adjust screen margins, refresh rates, etc. and the GS registers are recomputed accordingly.
Does this mean you can now get a proper 1080p50 output? And possible other resolutions and refresh rates? Having these GS register values would be great for other software as well.
PS: Nice to see you're working on this!
Does this mean you can now get a proper 1080p50 output?
Yes, all modes you could reasonably expect, including both 1080p50 and 1080p60. I have also made them compatible with a popular PS2 HDMI adapter.
And possible other resolutions and refresh rates?
Yes, there are currently 34 video modes (shown below) provided for convenience. All of them are calculated from first principles so one can adjust margins, clock speeds, etc. or even invent new modes.
# cat /sys/class/graphics/fb0/modes | column
V:1280x1024p-75 V:640x480p-60 S:1920x1080i-60 U:1688x964p-50 S:1280x720p-50
V:1280x1024p-60 U:1688x964p-60 S:1280x720p-60 U:1688x964i-50 S:720x576p-50
V:1024x768p-75 U:1688x964i-60 S:720x480p-60 U:1124x644p-50 S:720x576i-50
V:1024x768p-60 U:1124x644p-60 S:720x480i-60 U:576x460p-50 S:640x512i-50
V:800x600p-75 U:576x384p-60 S:640x448i-60 U:576x460i-50 S:720x288p-50
V:800x600p-60 U:576x384i-60 S:720x240p-60 S:1920x1080p-50 S:640x256p-50
V:640x480p-75 S:1920x1080p-60 S:640x224p-60 S:1920x1080i-50
Having these GS register values would be great for other software as well.
Yes, with direct GS register access only the hardware sets the video mode configuration limits.
A quick note, since I can't think of anywhere better to put this: in your GS privileged register documentation, SMODE1.SPML stands for "sub-pixel magnification level".
EDIT: And SMODE1.VHP controls progressive/interlaced.
EDIT 2: Also, you have self-referential comments for SYNCV.VBP and SYNCV.VBPE. Your comments state that VBP happens after VBPE, but also that VBPE happens after VBP.
A quick note, since I can't think of anywhere better to put this: in your GS privileged register documentation, SMODE1.SPML stands for "sub-pixel magnification level".
Thanks, @ZirconiumX! Fixed here:
https://github.com/frno7/linux/blob/e795c4827f4582bafe21b371047690a8f813d25e/arch/mips/include/asm/mach-ps2/gs.h#L22
https://github.com/frno7/linux/blob/274d9da7cf6006d9c458818764346703364750ad/arch/mips/include/asm/mach-ps2/gs-registers.h#L133
EDIT: And SMODE1.VHP controls progressive/interlaced.
Fixed here:
https://github.com/frno7/linux/blob/274d9da7cf6006d9c458818764346703364750ad/arch/mips/include/asm/mach-ps2/gs-registers.h#L143
EDIT 2: Also, you have self-referential comments for SYNCV.VBP and SYNCV.VBPE. Your comments state that VBP happens after VBPE, but also that VBPE happens after VBP.
Heh, right, that must be VBPE after VS, as fixed here:
https://github.com/frno7/linux/blob/274d9da7cf6006d9c458818764346703364750ad/arch/mips/include/asm/mach-ps2/gs-registers.h#L266
Another one: if SYNCV.VS is number of VSYNC lines, then SYNCH1.HS must surely be number of HSYNC clocks.
EDIT: Actually, your documentation states that SYNCV.V[BF]P[E] talks about colorburst, but this is wrong because colorburst happens every horizontal sync in analogue TV, not every vertical sync.
EDIT 2: The above leads me to believe that SYNCH1.{HSEQ,HSVS} must have something to do with colorburst, but I do not have an oscilloscope to test.
Another one: if SYNCV.VS is number of VSYNC lines, then SYNCH1.HS must surely be number of HSYNC clocks.
Indeed, there is a certain correspondence, modulated with SPML. The HDTV modes (720×576p, 1920×1080p, etc.) computed in the vm_to_sp_hdtv function show some register relationships, how they sum, and so on (the functions vm_to_sp_sdtv for SDTV and vm_to_sp_vesa for VESA are similar):
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L1771-L1827
EDIT: Actually, your documentation states that SYNCV.V[BF]P[E] talks about colorburst, but this is wrong because colorburst happens every horizontal sync in analogue TV, not every vertical sync.
Well, it is to say that there is no colour burst for the entirety of the horizontal line.
EDIT 2: The above leads me to believe that SYNCH1.{HSEQ,HSVS} must have something to do with colorburst, but I do not have an oscilloscope to test.
HSEQ and HSVS are computed like so, for SDTV:
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L1722-L1723
and HDTV and VESA:
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L1800-L1802
Well, it is to say that there is no colour burst for the entirety of the horizontal line.
I'm sorry, I don't quite understand what you mean here. While there is no colorburst for VESA or digital TV modes, both PAL and NTSC require a colourburst in the horizontal back porch.
I'm sorry, I don't quite understand what you mean here. While there is no colorburst for VESA or digital TV modes, both PAL and NTSC require a colourburst in the horizontal back porch.
Perhaps a more accurate term than colour burst could be used? In any case, no pixels from the frame buffer are displayed for the given line, as I recall.
So, here's something which I think should be tested.
From http://martin.hinner.info/vga/pal.html
You can stop the display being interlaced if you want - the solution appears to be to just use the same sync pulse train each field, ie: the 6-5-5 one from 'field one' (which lasts 8 whole lines). I've seen it done like this in chip data sheets and tested it with my Z80 project (also confirmed with a oscilloscope connected to a Playstation2 running a non-interlaced game).
I wonder if what SMODE1.VHP actually controls is the sync pulse pattern.
Perhaps a more accurate term than colour burst could be used? In any case, no pixels from the frame buffer are displayed for the given line, as I recall.
Colorburst is the accurate term here; it's the clock burst in the horizontal back porch that is used to synchronise the chroma carrier clocks between the PS2 and TV. Without the colorburst, there is no colour.
VESA gets around this by having colour clocks synchronised out of band in a VGA connector, but in PAL and NTSC they are synchronised in-band due to being broadcast standards.
Oh, I know what you're talking about now. You're talking about the "vertical blanking interval" (AKA VBLANK) in which nothing is drawn, which is an entirely different thing to "colourburst", where the chroma carriers are synchronised.
Since all Graphics Synthesizer registers are available symbolically via sysfs in this Linux kernel, it’s very easy to examine and try out new field value combinations, especially if one has access to an oscilloscope. To view SMODE1 and SMODE2 for example, simply use the cat command:
# cat /sys/devices/platform/gs/registers/smode1
rc 1
lc 22
t1248 1
slck 0
cmod vesa
ex 0
prst 0
sint 0
xpck 0
pck2 0
spml 1
gcont ycrcb
phs 0
pvs 0
pehs 0
pevs 0
clksel 1
nvck 1
slck2 1
vcksel 0
vhp 1
# cat /sys/devices/platform/gs/registers/smode2
intm progressive
ffmd field
dpms on
To update a register, just use the echo command with the wanted field values, like so:
# echo "dpms standby" >/sys/devices/platform/gs/registers/smode2
The updated SMODE2 register can be viewed with cat again:
# cat /sys/devices/platform/gs/registers/smode2
intm progressive
ffmd field
dpms standby
It’s probably best to fiddle with the video registers via a remote login shell, such as ssh.
Sadly I'm very much lacking an oscilloscope, so pure speculation is all I can do at present.
I've been trying to work out what units HFP, HS and HBP are in, but I'm having no luck.
Take the PAL timings, as that's what my country uses.
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L1706-L1713
Given this is accurate:
https://github.com/frno7/linux/blob/274d9da7cf6006d9c458818764346703364750ad/arch/mips/include/asm/mach-ps2/gs-registers.h#L145
Then the SDTV parameters calculates a 13.5MHz clock by multiplying a 13.5MHz by 32, and then dividing it by 32 again, which strikes me as odd because you could get the same clock rate by setting SMODE1.LC = 1, SMODE1.T1248 = 0, SMODE1.SPML = 1, SMODE1.RC = 1. This feels like it has some side effects beyond just VCK.
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L1720-L1726
These are the timings I don't understand.
Quoting http://martin.hinner.info/vga/pal.html :
General timing
Line period 64 us (Micro-seconds)
Line blanking 12.05 +- 0.25 us
Line sync 4.7 +- 0.1 us
Front porch: 1.65 +- 0.1 us
Burst start 5.6 +- 0.1 us after sync start.
Burst 10 +- 1 cycles
12.05 (HBLANK) - 1.65 (Front Porch) - 4.7 (HSYNC) = 5.7 (Back Porch).
However, assuming VCK = 13.5MHz:
VCK tick = 1 / 13.5MHz = 0.074 microseconds
48 (SMODE1.HFP) * 0.074 = 3.552 microseconds (way too high)
48 * (0.074 / 2) = 1.776 microseconds (still too high, but almost in spec)
48 * (0.074 / 4) = 0.888 microseconds (too low)
254 (SMODE1.HS) * 0.074 = 18.74 microseconds (too high)
254 * (0.074 / 2) = 9.398 microseconds (also too high)
254 * (0.074 / 4) = 4.699 microseconds (OK)
262 (SMODE1.HBP) * 0.074 = 19.388 microseconds (too high)
262 * (0.074 / 2) = 9.694 microseconds (also too high)
262 * (0.074 / 4) = 4.847 microseconds (too low)
Based on these I'm wondering if VCK is actually 13.5MHz * 4 = 54MHz, which is given strength by the schematics of the SCPH-39000 I have, where the GS receives a 54MHz input, and the comments by @sp193 who mentions the PLL init.
I think T1248 is interpreted wrong, but I'm not sure: https://github.com/frno7/linux/blob/274d9da7cf6006d9c458818764346703364750ad/arch/mips/include/asm/mach-ps2/gs-registers.h#L145
I think it should be:
The video clock VCK = ((13500000 * @lc) / (@spml * @rc)) >> @t1248
Where T1248 is used to right-shift, resulting in a devide of 1, 2, 4 or 8, hence the name T1248. Again I'm not sure, and since I've only seen T1248 to be 0 or 1, both calculations will give the same outcome.
When working with clock signals, right-shifting is not a well-defined operation. So you're probably right in terms of functionality, but I'd wager it's switching between a /1, /2, /4 and /8 PLL internally.
Here's another possibility. SMODE1.CMOD has three known states: PAL, NTSC and VESA. What if the fourth option is SÉCAM as used in Russia and France?
Even if the guess is wrong, my reading of the sysfs code for CMOD is that it doesn't expose the fourth option. It'd be nice if you did.
I've been trying to work out what units HFP, HS and HBP are in, but I'm having no luck.
HFP, HS and HBP are related to the pixel clock, and SPML in particular. I think you are right that some register details are not yet fully understood. HSVS and HSEQ, mentioned previously, remain unknown as well, although one can guess and attempt to interpolate their values based on known video mode resolutions.
Then the SDTV parameters calculates a 13.5MHz clock by multiplying a 13.5MHz by 32, and then dividing it by 32 again, which strikes me as odd because you could get the same clock rate by setting SMODE1.LC = 1, SMODE1.T1248 = 0, SMODE1.SPML = 1, SMODE1.RC = 1. This feels like it has some side effects beyond just VCK.
Indeed, I also observed that some combinations appear to be equivalent. To resolve this, I tabulated the known frequencies as preferred ones, and the rest are searched for exhaustively, hoping for the best, as shown here:
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/ps2/gs.c#L201-L274
As @rickgaiser noted, T1248 may have a greater range than indicated in that piece of code.
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L1720-L1726 These are the timings I don't understand.
The fixed values come from official SDTV modes. It would be better to compute them, though. Some relations can be gathered from how the sums work out, for example:
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L1702-L1703
Based on these I'm wondering if VCK is actually 13.5MHz * 4 = 54MHz, which is given strength by the schematics of the SCPH-39000 I have, where the GS receives a 54MHz input, and the comments by @sp193 who mentions the PLL init.
It seems you are referring to this mode?
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/ps2/gs.c#L217
It computes to (13500000 * 32) / ((1 + 1) * 4) / 4 = 13.5 MHz = 74074 ps. The video mode computations are based on
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/Documentation/fb/framebuffer.txt#L217-L253
where pixclock is defined in ps (picoseconds). For SDTV pixclock is 74074 ps for both PAL and NTSC, as for example shown here:
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/video/fbdev/ps2fb.c#L181-L182
Here's another possibility. SMODE1.CMOD has three known states: PAL, NTSC and VESA. What if the fourth option is SÉCAM as used in Russia and France?
Can this be confirmed in some reasonable way? GS User’s Manual, version 6.0, by Sony Computer Entertainment Inc. does not mention SÉCAM as a possibility, as far as I can see.
Even if the guess is wrong, my reading of the sysfs code for CMOD is that it doesn't expose the fourth option. It'd be nice if you did.
The sysfs field is defined in
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/drivers/ps2/gs-sysfs.c#L391
based on the enum in
https://github.com/frno7/linux/blob/c94ed72e624d28f05c2f1f034917fa432d259bc2/arch/mips/include/asm/mach-ps2/gs-registers.h#L98-L109
Older console models had either a 54.0MHz or 53.9MHz PLL input (as indicated in service manuals), while newer consoles can be configured in software for either operation (via the I2C interface of DEV9). This means that F-chassis (GH-015) and earlier can only output proper video signals in the regions that they were meant for, although the difference is very subtle.
@rickgaiser and @kernle32dll, I’m moving the GS discussion from #33 to this topic.
@rickgaiser, I imagine that a /dev/gs device would be a character device for HWREG1, that is the GS data port for transmission between buffers, via scatter-gather DMA. The device would handle details such noncontinuous physical memory, virtual memory, paging and misalignment. Writing nonaligned data would incur a performance penalty, of course, because the kernel would have realign the data automatically, but it would otherwise work transparently.
One can then simply do cat animation.gs >/dev/gs to draw just about anything on the screen, from a file animation.gs containing GS primitives. In principle, I imagine one could do things such as cat /dev/iop >/dev/gs to have the IOP draw on the screen efficiently and entirely with DMA. With devices for VU1, IPU, etc. that line of thought could be interesting, I think.
1 GS User's Manual, version 6.0, Sony Computer Entertainment Inc., p. 111.
Seems I need to get my hands on the GS manual ;-) (I have my sources, but it will take a while)
All I can weigh in for the moment are two thoughts:
-
It would be interesting, how this all fares against how the official PS2 Linux handles things. I am yet to get it running (did not invest much time), but from what I could gather it sports an hardware accelerated desktop environment of kind. While we are far away from that, it would be interesting to find out if and how programs (e.g. firefox) had to be adjusted, to work in this environment.
-
This circles back to gsKit, as I mentioned in #33 . In terms of graphical output, is it worthwhile to adjust existing applications to run with gs acceleration, or should the graphical capabilities be provided much more low level, e.g. via DRM, and for that matter e.g. an X server?
In regards to 2 - it is probably interesting to support both. E.g. have some generic underlying rendering "thingy", that allows to run existing applications on top of it easily. But it would also be cool to provide headers and/or libraries, to access the GS in own code of sorts.
@rickgaiser, I imagine that a /dev/gs device would be a character device for HWREG1, that is the GS data port for transmission between buffers, via scatter-gather DMA. The device would handle details such noncontinuous physical memory, virtual memory, paging and misalignment. Writing nonaligned data would incur a performance penalty, of course, because the kernel would have realign the data automatically, but it would otherwise work transparently.
HWREG1 would not be written to directly, but by using EE-DMA channel 2 (called PATH3 by sony).
In principle, I imagine one could do things such as cat /dev/iop >/dev/gs to have the IOP draw on the screen efficiently and entirely with DMA.
Possible, but not efficient. There's no direct DMA path from IOP to GS, and the IOP is very slow. But I get the point, having a character devices for the GS would give lots of possibilities.
Seems I need to get my hands on the GS manual ;-) (I have my sources, but it will take a while)
I hope you found what you where looking for.
This circles back to gsKit, as I mentioned in #33 . In terms of graphical output, is it worthwhile to adjust existing applications to run with gs acceleration, or should the graphical capabilities be provided much more low level, e.g. via DRM, and for that matter e.g. an X server?
I think the graphical capabilities should be provided by standard API's. So porting of applications is more easy, or not needed at all. For instance Quake1&2 should run perfectly using OpenGL 1.2. So having an OpenGL 1.2 library (ps2gl for instance) would make this game possible without porting. These high performace libraries need to use VU0 and VU1... so having only a /dev/gs interface would not be enough. A DRM driver would have to provide access to the VU's as well. Since gsKit does not use the VU's, it would be possible to port gsKit. But I think it's only usefull for small demo apps. Quake1 for instance would require a lot of work to port, and the end result would be slow.
edit: link removed
HWREG1 would not be written to directly, but by using EE-DMA channel 2 (called PATH3 by sony).
Of course. The idea, more precisely, is to turn gif_write into a fully functioning character device /dev/gs. The most useful privileged GS registers are already exposed via the gs-sysfs driver.
Possible, but not efficient. There's no direct DMA path from IOP to GS, and the IOP is very slow.
I have the impression that DMA channels can be chained to transfer data between multiple devices, including the IOP and the GS. That is efficient in the sense that the R5900 does not need to move any data.
But I get the point, having a character devices for the GS would give lots of possibilities.
Yes!
I have now obtained an almost fully working Direct Rendering Manager (DRM) variant of the frame buffer console for the PlayStation 2 Graphics Synthesizer. When completed, the deprecated drivers/video/fbdev/ps2fb.c will be retired and removed. Kernel configurations and init scripts must be updated to use the DRM driver instead, as this is a precondition for #1.
The remaining glitch is related to the DRM plane-crtc-connector-framebuffer pipe, which isn’t quite working yet, as shown here:
# cat /sys/kernel/debug/dri/0/state
plane[32]: plane-0
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
crtc[33]: crtc-0
enable=0
active=0
self_refresh_active=0
planes_changed=0
mode_changed=0
active_changed=0
connectors_changed=0
color_mgmt_changed=0
plane_mask=0
connector_mask=0
encoder_mask=0
mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
connector[31]: TV-1
crtc=(null)
self_refresh_aware=0
# cat /sys/kernel/debug/dri/0/framebuffer
framebuffer[35]:
allocated by = [fbcon]
refcount=1
format=XR24 little-endian (0x34325258)
modifier=0x0
size=1920x1080
layers:
size[0]=1920x1080
pitch[0]=7680
offset[0]=0
obj[0]:(null)
There is apparently significant user space breakage with the generic DRM frame buffer subsystem. As an example, consider the DRM driver for the AMD Radeon RX 550 (or a DRM driver for any other graphics hardware, as I understand the situation). Many relevant video modes are missing in the modes file (in fact, only one is shown), the vertical refresh value is wrong (0 instead of 60), and the mode type (U instead of S) is wrong too:
# cat /sys/class/graphics/fb0/modes
U:1920x1200p-0
The fbset tool no longer works properly, as the timing values are all zero:
# fbset
mode "1920x1200"
geometry 1920 1200 1920 4800 32
timings 0 0 0 0 0 0 0
accel true
rgba 8/16,8/8,8/0,0/0
endmode
Furthermore, fbset timing mode settings are ignored by the DRM subsystem, and so is attempts to set modes with /sys/class/graphics/fb0/mode. [ I also have the impression that the standard DRM video modes have mixed up the sync and front porch timings in struct drm_display_mode but this remains to be confirmed. ]
Some problems are due to breakage in drivers/gpu/drm/drm_fb_helper.c and others are due to DRM design choices, such as the abstraction of connectors, CRTs, planes and framebuffers. The DRM subsystem relies heavily on EDID to automatically choose an appropriate video resolution, which would explain why compatibility is lost and other mode setting methods are ignored.
I’m not aware of any EDID capabilities for the PlayStation 2, and so it seems important to retain compatibility with sysfs and fbset. This means reimplementing some generic parts of drivers/gpu/drm/drm_fb_helper.c in the specific DRM driver for the Graphics Synthesizer, to obtain all proper modes and timings:
# column </sys/class/graphics/fb0/modes
V:1280x1024p-75 V:640x480p-60 S:1920x1080i-60 U:1688x964p-50 S:1280x720p-50
V:1280x1024p-60 U:1688x964p-60 S:1280x720p-60 U:1688x964i-50 S:720x576p-50
V:1024x768p-75 U:1688x964i-60 S:720x480p-60 U:1124x644p-50 S:720x576i-50
V:1024x768p-60 U:1124x644p-60 S:720x480i-60 U:576x460p-50 S:640x512i-50
V:800x600p-75 U:576x384p-60 S:640x448i-60 U:576x460i-50 S:720x288p-50
V:800x600p-60 U:576x384i-60 S:720x240p-60 S:1920x1080p-50 S:640x256p-50
V:640x480p-75 S:1920x1080p-60 S:640x224p-60 S:1920x1080i-50
# fbset
mode "1920x1080-50"
# D: 148.500 MHz, H: 56.250 kHz, V: 50.000 Hz
geometry 1920 1080 1920 1080 16
timings 6734 148 484 36 4 88 5
accel false
rgba 5/0,5/5,5/10,1/15
endmode
The PlayStation 2 video connector is called AV-MULTI-OUT by the DRM driver. It remains to be decided whether the DRM concept of subconnectors ought to be applied, as in DRM_MODE_SUBCONNECTOR_Composite, DRM_MODE_SUBCONNECTOR_SVIDEO, DRM_MODE_SUBCONNECTOR_SCART, DRM_MODE_SUBCONNECTOR_VGA, DRM_MODE_SUBCONNECTOR_Component and possibly a new variant DRM_MODE_SUBCONNECTOR_DTerminal for D-Terminal that is popular in Japan.