ref: 01e6f4d436fa3c03eb768268b4d90cfbd2af71ad
parent: db27bd5be753519505973cc0226e3a49ef5aa23e
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Aug 9 16:01:17 EDT 2022
aux/imx8pm: add core/gpu/vpu temp read support (kernel counterpart is TBD)
--- a/sys/src/cmd/aux/imx8pm.c
+++ b/sys/src/cmd/aux/imx8pm.c
@@ -8,25 +8,53 @@
{
Mhz = 1000*1000,
Pwmsrcclk = 25*Mhz,
+
Ctl = 1,
+ Temp,
- PWMSAR = 0x0C/4,
+ PWMSAR = 0x0c/4,
PWMPR = 0x10/4,
+
+ TMUTMR = 0x00/4,
+ TMR_ME = 1<<31,
+ TMR_ALPF_SHIFT = 26,
+ TMR_MSITE_SHIFT = 13,
+ TMUTSR = 0x04/4,
+ TSR_MIE = 1<<30,
+ TSR_ORL = 1<<29,
+ TSR_ORH = 1<<28,
+ TMUTMTMIR = 0x08/4,
+ TMUTIER = 0x20/4,
+ TMUTIDR = 0x24/4,
+ TIDR_MASK = 0xe0000000,
+ TMUTISCR = 0x28/4,
+ TMUTICSCR = 0x2c/4,
+ TMUTRITSR0 = 0x100/4,
+ TMUTRITSR1 = 0x110/4,
+ TMUTRITSR2 = 0x120/4,
+ TMUTTR0CR = 0xf10/4,
+ TMUTTR1CR = 0xf14/4,
+ TMUTTR2CR = 0xf18/4,
+ TMUTTR3CR = 0xf1c/4,
+ CR_CAL_PTR_SHIFT = 16,
+
};
-static u32int *pwm2;
+static u32int *pwm2, *tmu;
static char *uid = "mntpm";
static void
wr(u32int *base, int reg, u32int v)
{
- base[reg] = v;
+ //fprint(2, "[0%x] ← 0x%ux\n", reg, v);
+ if(base != nil)
+ base[reg] = v;
}
static u32int
rd(u32int *base, int reg)
{
- return base[reg];
+ return base != nil ? base[reg] : -1;
}
static void
@@ -43,18 +71,87 @@
wr(pwm2, PWMPR, (Pwmsrcclk/(v*p/100))-2);
}
+static int
+getbrightness(void)
+{
+ u32int m, v;
+
+ m = Pwmsrcclk / rd(pwm2, PWMSAR);
+ v = Pwmsrcclk / (rd(pwm2, PWMPR)+2);
+ return v*100/m;
+}
+
+static int
+getcputemp(int c[3])
+{
+ int i, r[] = {TMUTRITSR0, TMUTRITSR1, TMUTRITSR2};
+ u32int s;
+
+ s = rd(tmu, TMUTSR);
+ if(s & TSR_MIE){
+ werrstr("monitoring interval exceeded");
+ return -1;
+ }
+ if(s & (TSR_ORL|TSR_ORH)){
+ werrstr("out of range");
+ return -1;
+ }
+
+ c[0] = c[1] = c[2] = 0;
+ for(;;){
+ for(i = 0; i < 3; i++)
+ if(c[i] >= 0)
+ c[i] = rd(tmu, r[i]);
+ if(c[0] < 0 && c[1] < 0 && c[2] < 0)
+ break;
+ sleep(10);
+ }
+ c[0] &= 0xff;
+ c[1] &= 0xff;
+ c[2] &= 0xff;
+ return 0;
+}
+
static void
+tmuinit(void)
+{
+ wr(tmu, TMUTMR, 0); /* disable */
+
+ wr(tmu, TMUTIDR, TIDR_MASK); /* W1Clear interrupt detect */
+ wr(tmu, TMUTISCR, 0); /* clear interrupt site */
+ wr(tmu, TMUTICSCR, 0); /* clear interrupt critical site */
+ wr(tmu, TMUTIER, 0); /* disable all interrupts */
+ wr(tmu, TMUTMTMIR, 7); /* interval 800MHz=1.34s */
+
+ /* configure default ranges */
+ wr(tmu, TMUTTR0CR, 11<<CR_CAL_PTR_SHIFT | 0);
+ wr(tmu, TMUTTR1CR, 10<<CR_CAL_PTR_SHIFT | 38);
+ wr(tmu, TMUTTR2CR, 8<<CR_CAL_PTR_SHIFT | 72);
+ wr(tmu, TMUTTR3CR, 7<<CR_CAL_PTR_SHIFT | 97);
+
+ /* enable: all sites, ALPF 00=1.0 */
+ wr(tmu, TMUTMR, TMR_ME | 0<<TMR_ALPF_SHIFT | 7<<TMR_MSITE_SHIFT);
+}
+
+static void
fsread(Req *r)
{
- u32int m, v;
char msg[256];
+ int c[3];
- if(r->fid->file->aux == (void*)Ctl){
- m = Pwmsrcclk / rd(pwm2, PWMSAR);
- v = Pwmsrcclk / (rd(pwm2, PWMPR)+2);
- snprint(msg, sizeof(msg), "brightness %d\n", v*100/m);
- readstr(r, msg);
+ msg[0] = 0;
+ if(r->ifcall.offset == 0){
+ if(r->fid->file->aux == (void*)Ctl)
+ snprint(msg, sizeof(msg), "brightness %d\n", getbrightness());
+ else if(r->fid->file->aux == (void*)Temp){
+ if(getcputemp(c) == 0)
+ snprint(msg, sizeof(msg), "%d\n%d\n%d\n", c[0], c[1], c[2]);
+ else
+ snprint(msg, sizeof(msg), "%r\n");
+ }
}
+
+ readstr(r, msg);
respond(r, nil);
}
@@ -113,11 +210,18 @@
usage();
}ARGEND
- if((pwm2 = segattach(0, "pwm2", 0, 0x18)) == (void*)-1)
- sysfatal("pwm2");
-
fs.tree = alloctree(uid, uid, DMDIR|0555, nil);
createfile(fs.tree->root, "ctl", uid, 0666, (void*)Ctl);
+
+ if((tmu = segattach(0, "tmu", 0, 0xf20)) == (void*)-1)
+ tmu = nil;
+ else{
+ createfile(fs.tree->root, "cputemp", uid, 0444, (void*)Temp);
+ tmuinit();
+ }
+ if((pwm2 = segattach(0, "pwm2", 0, 0x18)) == (void*)-1)
+ pwm2 = nil;
+
postmountsrv(&fs, srv, mtpt, MREPL);
exits(nil);