plan9fox/sys/src/9/imx8/clock.c
cinap_lenrek fff070f2cb imx8: add work in progress i.MX8MQ kernel for the mntreform2 laptop
This is a work in progress port to the mntreform2 laptop.

Working so far:

- mmu (same as raspberry pi 3b+)
- arm generic timer
- gicv3
- uart1
- enet

With access to the uart, one can netboot this kernel in u-boot
using the following commands:

> dhcp
> bootm
2022-05-08 16:50:29 +00:00

115 lines
1.4 KiB
C

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
#include "sysreg.h"
static uvlong freq;
enum {
Enable = 1<<0,
Imask = 1<<1,
Istatus = 1<<2,
};
void
clockshutdown(void)
{
}
static void
localclockintr(Ureg *ureg, void *)
{
timerintr(ureg, 0);
}
void
clockinit(void)
{
syswr(PMCR_EL0, 1<<6 | 7);
syswr(PMCNTENSET, 1<<31);
syswr(PMUSERENR_EL0, 1<<2);
syswr(CNTKCTL_EL1, 1<<1);
syswr(CNTP_TVAL_EL0, ~0UL);
syswr(CNTP_CTL_EL0, Enable);
if(m->machno == 0){
freq = sysrd(CNTFRQ_EL0);
print("timer frequency %lld Hz\n", freq);
}
intrenable(IRQcntpns, localclockintr, nil, BUSUNKNOWN, "clock");
}
void
timerset(uvlong next)
{
uvlong now;
long period;
now = fastticks(nil);
period = next - now;
syswr(CNTP_TVAL_EL0, period);
}
uvlong
fastticks(uvlong *hz)
{
if(hz)
*hz = freq;
return sysrd(CNTPCT_EL0);
}
ulong
perfticks(void)
{
return fastticks(nil);
}
ulong
µs(void)
{
uvlong hz;
uvlong t = fastticks(&hz);
return (t * 1000000ULL) / hz;
}
void
microdelay(int n)
{
ulong now;
now = µs();
while(µs() - now < n);
}
void
delay(int n)
{
while(--n >= 0)
microdelay(1000);
}
void
synccycles(void)
{
static Ref r1, r2;
int s;
s = splhi();
r2.ref = 0;
incref(&r1);
while(r1.ref != conf.nmach)
;
// syswr(PMCR_EL0, 1<<6 | 7);
incref(&r2);
while(r2.ref != conf.nmach)
;
r1.ref = 0;
splx(s);
}