shithub: riscv

Download patch

ref: ea2a5a33ca880e4f5e3950350bf4dbb4187f51b8
parent: 834f6703498f95ca6534463db6ecb32acb5487fa
author: cinap_lenrek <[email protected]>
date: Sat Jul 27 13:59:25 EDT 2019

bcm64: fix wrong prescaler for generic timer on rpi4

the raspberry pi 4 uses 54 instead of 19.2 MHz crystal.
detect which frequency is used by reading OTP bootmode
register:

https://www.raspberrypi.org/documentation/hardware/raspberrypi/otpbits.md

Bit 1: sets the oscillator frequency to 19.2MHz

--- a/sys/src/9/bcm64/clock.c
+++ b/sys/src/9/bcm64/clock.c
@@ -121,14 +121,23 @@
 
 	syswr(CNTP_TVAL_EL0, ~0UL);
 	if(m->machno == 0){
+		int oscfreq;
+
 		syswr(CNTP_CTL_EL0, Imask);
 
 		*(u32int*)(ARMLOCAL + GPUirqroute) = 0;
 
-		/* input clock is 19.2Mhz crystal */
+		/* bit 1 from OTP bootmode register determines OSC frequency */
+		if(*((u32int*)(VIRTIO+0x20f000)) & (1<<1))
+			oscfreq = 19200000;
+		else
+			oscfreq = 54000000;
+
+		/* input clock to OSC */
 		*(u32int*)(ARMLOCAL + Localctl) = 0;
+
 		/* divide by (2^31/Prescaler) */
-		*(u32int*)(ARMLOCAL + Prescaler) = (((uvlong)SystimerFreq<<31)/19200000)&~1UL;
+		*(u32int*)(ARMLOCAL + Prescaler) = (((uvlong)SystimerFreq<<31)/oscfreq)&~1UL;
 	} else {
 		syswr(CNTP_CTL_EL0, Enable);
 		intrenable(IRQcntpns, localclockintr, nil, BUSUNKNOWN, "clock");
--- a/sys/src/9/bcm64/sysreg.h
+++ b/sys/src/9/bcm64/sysreg.h
@@ -31,6 +31,7 @@
 #define PMCCNTR_EL0			SYSREG(3,3,9,13,0)
 #define PMUSERENR_EL0			SYSREG(3,3,9,14,0)
 
+#define CNTPCT_EL0			SYSREG(3,3,14,0,1)
 #define CNTP_TVAL_EL0			SYSREG(3,3,14,2,0)
 #define CNTP_CTL_EL0			SYSREG(3,3,14,2,1)
 #define CNTP_CVAL_EL0			SYSREG(3,3,14,2,2)