gl: clear w, h on reinit
[libpicofe.git] / gp2x / soc_pollux.c
index e59a561..7e86092 100644 (file)
 
 #include "soc.h"
 #include "plat_gp2x.h"
+#include "pollux_set.h"
 #include "../plat.h"
 
 static int battdev = -1, mixerdev = -1;
 static int cpu_clock_allowed;
+static unsigned short saved_memtimex[2];
 static unsigned int saved_video_regs[2][6];
 static unsigned int timer_drift; // count per real second
 
@@ -59,12 +61,33 @@ static int decode_pll(unsigned int reg)
        return v;
 }
 
+/* RAM timings */
+static void set_ram_timings(void)
+{
+       pollux_set_fromenv(memregs, "POLLUX_RAM_TIMINGS");
+}
+
+static void unset_ram_timings(void)
+{
+       int i;
+
+       memregs[0x14802>>1] = saved_memtimex[0];
+       memregs[0x14804>>1] = saved_memtimex[1] | 0x8000;
+
+       for (i = 0; i < 0x100000; i++)
+               if (!(memregs[0x14804>>1] & 0x8000))
+                       break;
+
+       printf("RAM timings reset to startup values.\n");
+}
+
 #define TIMER_BASE3 0x1980
 #define TIMER_REG(x) memregl[(TIMER_BASE3 + x) >> 2]
 
 static unsigned int gp2x_get_ticks_us_(void)
 {
-       TIMER_REG(0x08) = 0x4b;  /* run timer, latch value */
+       unsigned int div = TIMER_REG(0x08) & 3;
+       TIMER_REG(0x08) = 0x48 | div;  /* run timer, latch value */
        return TIMER_REG(0);
 }
 
@@ -117,9 +140,9 @@ int pollux_get_real_snd_rate(int req_rate)
        rate = decode_pll(clk0_src ? memregl[0xf008>>2] : memregl[0xf004>>2]);
 
        // apply divisors
-       div = ((memregl[0xdbc4>>2] >> 4) & 0x1f) + 1;
+       div = ((memregl[0xdbc4>>2] >> 4) & 0x3f) + 1;
        rate /= div;
-       div = ((memregl[0xdbc8>>2] >> 4) & 0x1f) + 1;
+       div = ((memregl[0xdbc8>>2] >> 4) & 0x3f) + 1;
        rate /= div;
        rate /= 64;
 
@@ -235,6 +258,11 @@ void pollux_init(void)
        }
        memregl = (volatile void *)memregs;
 
+       saved_memtimex[0] = memregs[0x14802>>1];
+       saved_memtimex[1] = memregs[0x14804>>1];
+
+       set_ram_timings();
+
        // save video regs of both MLCs
        save_multiple_regs(saved_video_regs[0], 0x4058, ARRAY_SIZE(saved_video_regs[0]));
        save_multiple_regs(saved_video_regs[1], 0x4458, ARRAY_SIZE(saved_video_regs[1]));
@@ -275,6 +303,9 @@ void pollux_init(void)
                TIMER_REG(0x44) = ((timer_div - 1) << 4) | 2;   /* using PLL1 */
                TIMER_REG(0x40) = 0x0c;                         /* clocks on */
                TIMER_REG(0x08) = 0x68 | timer_div2;            /* run timer, clear irq, latch value */
+
+               gp2x_get_ticks_ms = gp2x_get_ticks_ms_;
+               gp2x_get_ticks_us = gp2x_get_ticks_us_;
        }
        else {
                fprintf(stderr, "warning: could not make use of timer\n");
@@ -296,15 +327,14 @@ void pollux_init(void)
        plat_target.cpu_clock_set = pollux_cpu_clock_set;
        plat_target.bat_capacity_get = pollux_bat_capacity_get;
        plat_target.step_volume = step_volume;
-
-       gp2x_get_ticks_ms = gp2x_get_ticks_ms_;
-       gp2x_get_ticks_us = gp2x_get_ticks_us_;
 }
 
 void pollux_finish(void)
 {
        timer_cleanup();
 
+       unset_ram_timings();
+
        restore_multiple_regs(0x4058, saved_video_regs[0],
                ARRAY_SIZE(saved_video_regs[0]));
        restore_multiple_regs(0x4458, saved_video_regs[1],