linux icon indicating copy to clipboard operation
linux copied to clipboard

The Graphics Synthesizer (GS) drivers

Open frno7 opened this issue 6 years ago • 64 comments

The Graphics Synthesizer (GS) frame buffer device driver drivers/video/fbdev/ps2fb.c currently operates in

  1. 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_ops such as fb_tileblit, fb_fillrect and fb_copyarea are 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 accelerate YWRAP in 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 printk during booting.

It’s possible to implement a

  1. 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,

  1. 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?

frno7 avatar Mar 17 '19 07:03 frno7

@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? */
};

frno7 avatar May 03 '19 08:05 frno7

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.

sp193 avatar May 03 '19 13:05 sp193

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.

frno7 avatar May 04 '19 06:05 frno7

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.

sp193 avatar May 04 '19 18:05 sp193

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!

rickgaiser avatar May 06 '19 08:05 rickgaiser

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.

frno7 avatar May 06 '19 16:05 frno7

@rickgaiser, DRM/KMS is now required to proceed with #1, so I have registered #30 for it.

frno7 avatar Sep 07 '19 09:09 frno7

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.

Ravenslofty avatar Sep 14 '19 14:09 Ravenslofty

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

frno7 avatar Sep 15 '19 07:09 frno7

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.

Ravenslofty avatar Sep 15 '19 09:09 Ravenslofty

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

frno7 avatar Sep 15 '19 12:09 frno7

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.

Ravenslofty avatar Sep 15 '19 12:09 Ravenslofty

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.

frno7 avatar Sep 15 '19 12:09 frno7

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.

Ravenslofty avatar Sep 15 '19 12:09 Ravenslofty

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.

Ravenslofty avatar Sep 15 '19 12:09 Ravenslofty

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.

Ravenslofty avatar Sep 15 '19 12:09 Ravenslofty

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.

frno7 avatar Sep 15 '19 13:09 frno7

Sadly I'm very much lacking an oscilloscope, so pure speculation is all I can do at present.

Ravenslofty avatar Sep 15 '19 13:09 Ravenslofty

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.

Ravenslofty avatar Sep 16 '19 11:09 Ravenslofty

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.

rickgaiser avatar Sep 16 '19 13:09 rickgaiser

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.

Ravenslofty avatar Sep 17 '19 08:09 Ravenslofty

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.

Ravenslofty avatar Sep 19 '19 09:09 Ravenslofty

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

frno7 avatar Sep 21 '19 06:09 frno7

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.

sp193 avatar Sep 21 '19 10:09 sp193

@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.

frno7 avatar Dec 05 '19 17:12 frno7

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:

  1. 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.

  2. 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.

kernle32dll avatar Dec 05 '19 22:12 kernle32dll

@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

rickgaiser avatar Dec 06 '19 07:12 rickgaiser

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!

frno7 avatar Dec 06 '19 13:12 frno7

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)

frno7 avatar Jan 27 '20 17:01 frno7

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.

frno7 avatar Feb 15 '20 08:02 frno7