GP2X Ram-hack (tweak) Topic


Q

quasist

Guest
Since me is lacking the system programming skills I copy-paste some code from very popular tweaking untility.
Here is final version of code that is easy to add to program.
As far it works nicely.
But It will be good if some pro-gp2x-linux-coder would look through for some bug... and saving the innocent users

CODE

#ifdef GP2X
#include "sys/mman.h"
#include "fcntl.h"

volatile unsigned short *MEM_REG;
unsigned long gp2x_dev=0;

void RamHack(void)//I't me! RamHack!
{
gp2x_dev = open("/dev/mem", O_RDWR);

MEM_REG=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev, 0xc0000000);
unsigned short v,timing;

//tRC
timing=5;
v = (unsigned short)(MEM_REG[0x3804>>1] & (~(0xF << 8)));
MEM_REG[0x3804>>1] = ((timing & 0xF) << 8) | v;

//tRAS
timing=3;
v = (unsigned short)(MEM_REG[0x3804>>1] & (~(0xF << 4)));
MEM_REG[0x3804>>1] = ((timing & 0xF) << 4) | v;

//tWR
timing=0;
v = (unsigned short)(MEM_REG[0x3804>>1] & (~(0xF)));
MEM_REG[0x3804>>1] = (timing & 0xF) | v;

//tMRD
timing=0;

v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF << 12)));
MEM_REG[0x3802>>1] = ((timing & 0xF) << 12) | v;

//tRFC
timing=0;

v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF << 8)));
MEM_REG[0x3802>>1] = ((timing & 0xF) << 8) | v;

//tRP
timing=1;

v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF << 4)));
MEM_REG[0x3802>>1] = ((timing & 0xF) << 4) | v;
//tRCD
timing=1;

v = (unsigned short)(MEM_REG[0x3802>>1] & (~(0xF)));
MEM_REG[0x3802>>1] = (timing & 0xF) | v;

close(gp2x_dev);
}

#endif
 

Daid

Member
Joined
Jun 13, 2006
Messages
267
Location
Netherlands
Website
Visit site
This is for the RAM timings? Does not make me that happy then, as my GP2x unit can be overclocked stable up to 270Mhz, but crashes when I fiddle with the RAMtimings. Thus I always leave the RAM timings for what they are. If people start to include this as 'always on' in there programs, then some consoles will crash.
 

JyCet

Member
Joined
Feb 23, 2004
Messages
469
Age
116
Location
France
Website
Visit site
Daid said:
This is for the RAM timings? Does not make me that happy then, as my GP2x unit can be overclocked stable up to 270Mhz, but crashes when I fiddle with the RAMtimings. Thus I always leave the RAM timings for what they are. If people start to include this as 'always on' in there programs, then some consoles will crash.
for very low underclock, I've never seen (yet) a gp2x which crash with aggresive ram tweak
and you win a lot of fps :)
but i always add ram tweak like an option for if one day one unlucky gp2x exist :)
 
Last edited by a moderator:

Guyfawkes

Certified Idiot :)
Joined
Jan 11, 2004
Messages
795
Age
46
Location
London, UK
Website
www.emuholic.com
Just tried it on my game and got a very noticeable increase in speed, at least 10 FPS which I quickly timed (certain point in the music). combined with the mmuhack there's loads of extra FPS out there now :)
 

Dr_Ian

Still Fresh
Joined
Sep 18, 2006
Messages
91
I've don't really an idea what this is doing, but I have tried to simplify it :(
CODE

#ifdef GP2X
#include "sys/mman.h"
#include "fcntl.h"

volatile unsigned short *MEM_REG;
unsigned long gp2x_dev=0;

void RamHack(void)
{
gp2x_dev = open("/dev/mem", O_RDWR);

MEM_REG=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev, 0xc0000000);
MEM_REG[0x3804>>1] = 0x0530 | (MEM_REG[0x3804>>1] & 0xF000);
MEM_REG[0x3802>>1] = 0x0011;

close(gp2x_dev);
}

#endif
 

rokdcasbah

got me a date with botticelli's niece
Joined
Jan 5, 2006
Messages
1,516
Location
up on cripple creek
i find that in a few cases if i use gmenu's ram tweak option, i get corrupt sound output. maybe this is because of something else though, i dunno. also, with gpsp it took me a while to find good ram timings that weren't actually causing a net speed loss, and that didn't cause a crash.

so my advice would be to always leave the option of turning it on or off. also if you don't change those registers at all then the user can still script the cpu/lcd/ram tweaker, or use the similar functionality that's built into gmenu2x.
 

Puck2099

Certified Guru
Joined
Oct 22, 2004
Messages
422
Location
Madrid, Spain
Website
www.gp32wip.com
Hi,

That RAM tweak increases a lot performance, but it doesn't dissapear when you exit that program...

Does anyone know what are the default values for that registers or how to revert to "normal" timmings?

Thanks :)

EDIT: I'm quite tired or stupid, forget what I've asked, it's too simple to ask that :D
 

Trenki

Member
Joined
Jun 15, 2006
Messages
114
Age
39
Location
South Tyrol, Italy
Website
www.trenki.net
Ok, I still have to test this code with my software renderer to see if it makes things noticeably faster. But for now I created a very cleaned up version of the code (warning: not tested yet).

CODE
#define MEMTIMEX0 0x3802
#define MEMTIMEX1 0x3804

union memtimex0_t {
struct {
unsigned int tRCD : 4; // default = 2
unsigned int tRP : 4; // default = 15
unsigned int tRFC : 4; // default = 4
unsigned int tMRD : 4; // default = 4
} s;
unsigned short i;
};

union memtimex1_t {
struct {
unsigned int tWR : 4; // default = 2
unsigned int tRAS : 4; // default = 7
unsigned int tRC : 4; // default = 10
unsigned int LAT : 1; // default = 1; apparently readonly
unsigned int reserved : 2; // readonly

// Write: Set 1 to set new SDRAM mode parameter;
// Read: 0 = complete, 1 = busy
unsigned int ModeStatusSet : 1;
} s;
unsigned short i;
};

void RamHack()
{
memtimex0_t t0;
t0.i = memreg16(MEMTIMEX0);
t0.s.tRCD = 1;
t0.s.tRP = 1;
t0.s.tRFC = 0;
t0.s.tMRD = 0;
memreg16(MEMTIMEX0) = t0.i;

memtimex1_t t1;
t1.i = memreg16(MEMTIMEX1);
t1.s.tWR = 0;
t1.s.tRAS = 3;
t1.s.tRC = 5;

// The docs say to write 1 to set new mode
// parameter but seems to work without?
t1.s.ModeStatusSet = 1;
memreg16(MEMTIMEX1) = t1.i;

// Wait until mode is set. May not be necessary?
do {
t1.i = memreg16(MEMTIMEX1);
} while (t1.s.ModeStatusSet);
}

The default values were taken from the MMSP2 Data Book. Some values seem to be read only. There is a ModeSet/ModeStatus bit in the MEMTIMEX1 register. The docs says to write 1 to set new SDRAM parameters, so I do this in the above code and also wait for this bit to be cleared as this should indicate completion. I don't realy know if this is actually necessary as it seems to work without it.

I don't really know what the individual values mean. I assume it is: cylcles = value + 1. If this is true we really lower the numer of cycles by a lot!

I think it would be quite useful to create a wiki page for this and put some explanations on it and post appropriate timing data which would make it as fast as possible while also keeping it stable even when the CPU is overclocked to say 266MHz.

EDIT: I tested it now. The first time it crashed my GP2X! But it worked on the second try. With this hack my demo runs ~11% faster on average. Actually the scene where I least expected it runs fastest.
 
Q

quasist

Guest
I got nearly same speed increase (10-20%), when was added ramhack it to my FleshChasmer. I'm not sure, but h/w accelerated SDL blitting could be more benefit from ramhack than software 3d.

2Puck2099
Just launch the cpu&lcd tweak untility with no ramhack aplied. There should be displayed current ram-timings settings.
 

Yod4z

Member
Joined
Feb 16, 2006
Messages
916
Age
43
Location
France
earx said:
is this the same thing as squidge's mmu hack? if not, i should really give it a try :)
no, not the same has Squidge mmu hack. Here we just change the ram timings of the gp2x to have faster acces to the ram
 
Last edited by a moderator:

rlyeh

Certified Guru
Joined
Mar 25, 2003
Messages
277
Age
44
Location
49°9' East latitude, 126°43' South longitude: in y
Website
www.retrodev.info
these values have been discused a few times in this board afaik
if i'm right, emu&co discovered the magic values, then craigix modified them a little and posted them at boards

this is the implementation from minimal library which also sets the cpu clock:

CODE


/* Function: gp2x_dualcore_clock
This function sets the clock at ARM 920T coprocessor and RAM tweaks.

Note:
- Call this function only from your 920T program.

Parameters:
s (50,75,100,125,150,175,200,225,250) - Speed value in MHz. Default is 200.

Credits:
RobBrown, sasq and whizzbang (original clock setting code)

god_at_hell (original RAM tweaking code)

craigix, Emu&Co (tweaked RAM timing values) */

void gp2x_dualcore_clock(int s)
{
unsigned long interrupt_flags = gp2x_memregl[0x808>>2],
//tRC=7-1 if mhz > 266
//CAS=0,tRC=6-1,tRAS=3-1,tWR=1-1,tMRD=1-1,tRFC=1-1,tRP=1-1,tRCD=2-1; //emu&co's timings
CAS=0,tRC=6-1,tRAS=4-1,tWR=1-1,tMRD=1-1,tRFC=1-1,tRP=2-1,tRCD=2-1; //craigix's timings

//hardcoded values:
s=(s>=250?0x5D04:s>=225?0x5304:s>=200?0x4904:s>=175?0x3F04:s>=125?0x3c01:s>=100?0x6502:s>=75?0x4902:s>=50?0x6503:0);

if(s)
{
gp2x_memregl[0x0808>>2] = 0xFF8FFFE7; // Mask interrupts

gp2x_memregs[0x0910>>1] = s; // Set clock and wait

while(gp2x_memregs[0x0902>>1] & 1);

gp2x_memregs[0x3802>>1] = ((tMRD<<12)|(tRFC<<8)|(tRP<<4)|(tRCD)); //set RAM tweaks
gp2x_memregs[0x3804>>1] = ((CAS<<12)|(tRC<<8)|(tRAS<<4)|(tWR));

gp2x_memregs[0x0924>>1] = 0x8900 + ((1)<<8); // Set upll timing prescaler to 1 (0x5A00 for fw 1.0.x)

gp2x_memregl[0x0808>>2] = interrupt_flags; // Turn on interrupts
}
}




hope this helps someone
 
Top