diff --git a/plat/rpi/build.mk b/plat/rpi/build.mk index 4db4a4849..c89847607 100644 --- a/plat/rpi/build.mk +++ b/plat/rpi/build.mk @@ -23,6 +23,7 @@ platform-libsys := \ pi_phys_to_user.s \ pi_user_to_phys.s \ pi_uart.s \ + pi_fast_mode.s \ creat.c \ close.c \ open.c \ diff --git a/plat/rpi/include/pi.h b/plat/rpi/include/pi.h index 656543bde..24e89a9a1 100644 --- a/plat/rpi/include/pi.h +++ b/plat/rpi/include/pi.h @@ -32,5 +32,17 @@ extern void* pi_phys_to_user(void* ptr); /* Converts a pointer from a user address to a physical address. */ extern void* pi_user_to_phys(void* ptr); +/* Change the clock speed from 19.2MHz to 250MHz. Must be called *before* + * pi_init_uart(). */ +extern void pi_fast_mode(void); + +/* Initialise the RAM. */ +extern void pi_init_ram(void); + +/* The current clock speed (used by pi_init_uart to calculate the correct + * UART settings). */ + +extern int pi_clock_speed; + #endif diff --git a/plat/rpi/libsys/pi_fast_mode.s b/plat/rpi/libsys/pi_fast_mode.s new file mode 100644 index 000000000..8b50990f0 --- /dev/null +++ b/plat/rpi/libsys/pi_fast_mode.s @@ -0,0 +1,70 @@ +# +/* + * Raspberry Pi support library for the ACK + * © 2013 David Given + * This file is redistributable under the terms of the 3-clause BSD license. + * See the file 'Copying' in the root of the distribution for the full text. + */ + +#include "libsysasm.h" + +.sect .text + +#define PASSWD 0x5a000000 +#define PLLC 5 +#define OSC 1 + +#define A2W 0x7e102000 +#define A2W_PLLC_MULT 0x7e102020 +#define A2W_PLLC_MULT2 0x7e102120 +#define A2W_PLLC_MULT_FRACT 0x7e102220 +#define A2W_PLLx_DIV 0x7e102620 + +#define CM 0x7e101000 +#define CM_VPU_CTL 0x7e101008 +#define CM_VPU_DIV 0x7e10100c +#define CM_TIME_DIV 0x7e1010ec +#define CM_TIME_CTL 0x7e1010e8 + +#define hash # +#define copy(A) A +#define poke(A, V) \ + mov r0, copy(hash) V; mov r1, copy(hash) A; st r0, (r1) + +! Changes the clock speed to 250MHz. + +.define _pi_fast_mode +_pi_fast_mode: + poke(A2W + 0x190, 0x5a000001) + poke(A2W_PLLC_MULT_FRACT, PASSWD | 87380) + poke(A2W_PLLC_MULT2, PASSWD | 52 | 0x1000) + poke(A2W + 0x3c, 0x5a000100) + poke(A2W + 0x38, 0x5a000000) + poke(A2W + 0x34, 0x5a144000) + poke(A2W + 0x30, 0x5a000000) + poke(CM + 0x108, 0x5a000200) + poke(CM + 0x108, 0x5a0002aa) + poke(A2W + 0x2c, 0x5a000000) + poke(A2W + 0x28, 0x5a400000) + poke(A2W + 0x24, 0x5a000005) + poke(A2W_PLLC_MULT, PASSWD | 52 | 0x555000) + poke(A2W_PLLC_MULT2, PASSWD | 52 | 0x21000) + poke(A2W + 0x2c, 0x5a000042) + poke(A2W + 0x28, 0x5a500401) + poke(A2W + 0x24, 0x5a004005) + poke(A2W_PLLC_MULT, PASSWD | 52 | 0x555000) + poke(A2W_PLLx_DIV, PASSWD | 2) + poke(CM + 0x108, 0x5a0002ab) + poke(CM + 0x108, 0x5a0002aa) + poke(CM + 0x108, 0x5a0002a8) + poke(CM_VPU_CTL, PASSWD | 0x200 | OSC | 0x40) + poke(CM_VPU_DIV, PASSWD | [4 << 12]) + poke(CM_VPU_CTL, PASSWD | PLLC | 0x40) + poke(CM_VPU_CTL, PASSWD | PLLC | 0x50) + poke(CM_TIME_DIV, PASSWD | [19 << 12] | 819) + poke(CM_TIME_CTL, PASSWD | OSC | 0x10) + + mov r0, #250000000 + st r0, _pi_clock_speed + b lr + diff --git a/plat/rpi/libsys/pi_uart.s b/plat/rpi/libsys/pi_uart.s index d52069d71..b7ce9898e 100644 --- a/plat/rpi/libsys/pi_uart.s +++ b/plat/rpi/libsys/pi_uart.s @@ -14,9 +14,6 @@ ! So be careful with your serial/terminal, some adjustment may be necessary. TARGET_BAUD_RATE = 115200 -! System clock is running directly off the 19.2MHz crystal at initial reset -SYSTEM_CLOCK = 19200000 - GPFSEL1 = 0x7e200004 GPSET0 = 0x7e20001C GPCLR0 = 0x7e200028 @@ -102,7 +99,10 @@ delay2: st r0, (r1) mov r1, #AUX_MU_BAUD_REG - mov r0, #[[SYSTEM_CLOCK/[TARGET_BAUD_RATE*8]]-1] + ld r0, _pi_clock_speed + mov r2, #TARGET_BAUD_RATE*8 + divu r0, r0, r2 + sub r0, #1 st r0, (r1) mov r1, #AUX_MU_LCR_REG @@ -176,3 +176,10 @@ recvwait: b lr .comm __uart_status, 1 + +.sect .data +.define _pi_clock_speed + +! System clock is running directly off the 19.2MHz crystal at initial reset +_pi_clock_speed: + .data4 19200000